Initial commit.
commit
f4f043e4d6
|
@ -0,0 +1,60 @@
|
|||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.4.32"
|
||||
id("com.github.johnrengelman.shadow") version "5.2.0"
|
||||
}
|
||||
|
||||
group = "nl.kallestruik"
|
||||
version = "1.0"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://repo.aikar.co/content/groups/aikar/")
|
||||
maven("https://repo.dmulloy2.net/repository/public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("co.aikar:acf-paper:0.5.0-SNAPSHOT")
|
||||
compileOnly("com.destroystokyo.paper:paper:1.16.5-R0.1-SNAPSHOT")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.6.0")
|
||||
compileOnly(kotlin("stdlib-jdk8"))
|
||||
|
||||
compileOnly("nl.kallestruik:DLib:1.0")
|
||||
|
||||
testImplementation(kotlin("test-junit5"))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
|
||||
}
|
||||
|
||||
tasks.compileJava {
|
||||
options.compilerArgs.add("-parameters")
|
||||
}
|
||||
|
||||
tasks.compileKotlin {
|
||||
kotlinOptions.javaParameters = true
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
relocate("co.aikar.commands", "nl.kallestruik.dtweaks.acf")
|
||||
relocate("co.aikar.locales", "nl.kallestruik.dtweaks.locales")
|
||||
}
|
||||
|
||||
tasks.build {
|
||||
dependsOn(tasks.shadowJar)
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "11"
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
expand("version" to project.version)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
kotlin.code.style=official
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,185 @@
|
|||
#!/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" "$@"
|
|
@ -0,0 +1,89 @@
|
|||
@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 Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@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 execute
|
||||
|
||||
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 execute
|
||||
|
||||
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
|
||||
|
||||
: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 %*
|
||||
|
||||
: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
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
rootProject.name = "DTweaks"
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package nl.kallestruik.dtweaks
|
||||
|
||||
object Const {
|
||||
const val TRAMPLE_ENABLED_FILE_NAME = "tramplestore.yml"
|
||||
const val TWEAK_STATE_FILE_NAME = "tweak_states.yml"
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package nl.kallestruik.dtweaks
|
||||
|
||||
import co.aikar.commands.ConditionFailedException
|
||||
import co.aikar.commands.PaperCommandManager
|
||||
import nl.kallestruik.dlib.DUtil
|
||||
import nl.kallestruik.dlib.MathHelper
|
||||
import nl.kallestruik.dlib.ReflectionUtil
|
||||
import nl.kallestruik.dtweaks.commands.CommandMobcaps
|
||||
import nl.kallestruik.dtweaks.commands.CommandPlayer
|
||||
import nl.kallestruik.dtweaks.commands.CommandPocketdim
|
||||
import nl.kallestruik.dtweaks.commands.CommandToggletrample
|
||||
import nl.kallestruik.dtweaks.managers.FakePlayerManager
|
||||
import nl.kallestruik.dtweaks.managers.PocketDimensionManager
|
||||
import nl.kallestruik.dtweaks.managers.TrampleManager
|
||||
import nl.kallestruik.dtweaks.managers.TweakManager
|
||||
import nl.kallestruik.dtweaks.tweaks.craftingtweaks.*
|
||||
import nl.kallestruik.dtweaks.tweaks.croptweaks.*
|
||||
import nl.kallestruik.dtweaks.tweaks.dispsensertweaks.DispensersCanPlantSaplings
|
||||
import nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks.ArmorStandArmorSwapping
|
||||
import nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks.CarpetBlockPlacingProtocol
|
||||
import nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks.FakePlayers
|
||||
import nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks.SpaceTimePockets
|
||||
import nl.kallestruik.dtweaks.tweaks.mobtweaks.NoCreeperGrief
|
||||
import nl.kallestruik.dtweaks.tweaks.mobtweaks.NoDoorBreaking
|
||||
import nl.kallestruik.dtweaks.tweaks.mobtweaks.NoEndermanGrief
|
||||
import nl.kallestruik.dtweaks.tweaks.mobtweaks.VillagerInfo
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
|
||||
class DTweaks: JavaPlugin() {
|
||||
companion object {
|
||||
private lateinit var random: Random
|
||||
private lateinit var tweakManager: TweakManager
|
||||
private lateinit var util: DUtil
|
||||
private lateinit var mathHelper: MathHelper
|
||||
lateinit var reflectionUtil: ReflectionUtil
|
||||
private lateinit var trampleManager: TrampleManager
|
||||
private lateinit var commandManager: PaperCommandManager
|
||||
private lateinit var fakePlayerManager: FakePlayerManager
|
||||
private lateinit var pocketDimensionManager: PocketDimensionManager
|
||||
}
|
||||
|
||||
override fun onEnable() {
|
||||
/*
|
||||
* Initialize stuff
|
||||
*/
|
||||
random = Random()
|
||||
tweakManager = TweakManager(this)
|
||||
util = DUtil(random)
|
||||
mathHelper = MathHelper()
|
||||
reflectionUtil = ReflectionUtil()
|
||||
trampleManager = TrampleManager()
|
||||
commandManager = PaperCommandManager(this)
|
||||
fakePlayerManager = FakePlayerManager()
|
||||
pocketDimensionManager = PocketDimensionManager(mathHelper)
|
||||
|
||||
// Enable brigadier support on ACF
|
||||
commandManager.enableUnstableAPI("brigadier")
|
||||
|
||||
registerCommandConditions()
|
||||
|
||||
/*
|
||||
* Commands
|
||||
*/
|
||||
commandManager.registerCommand(CommandMobcaps(reflectionUtil))
|
||||
commandManager.registerCommand(CommandPlayer(fakePlayerManager, tweakManager))
|
||||
commandManager.registerCommand(CommandPocketdim(pocketDimensionManager))
|
||||
commandManager.registerCommand(CommandToggletrample(trampleManager))
|
||||
|
||||
/*
|
||||
* Load data from disk
|
||||
*/
|
||||
tweakManager.loadFromFile(File(dataFolder, Const.TWEAK_STATE_FILE_NAME))
|
||||
trampleManager.loadFromFile(File(dataFolder, Const.TRAMPLE_ENABLED_FILE_NAME))
|
||||
pocketDimensionManager.loadData()
|
||||
|
||||
/*
|
||||
* Crafting tweaks
|
||||
*/
|
||||
tweakManager.registerTweak(AlternativeDispenserRecipe(this))
|
||||
tweakManager.registerTweak(CraftableDragonsBreath(this))
|
||||
tweakManager.registerTweak(CraftableNametag(this))
|
||||
tweakManager.registerTweak(CraftableSaddle(this))
|
||||
tweakManager.registerTweak(CraftableShulkerShell(this))
|
||||
tweakManager.registerTweak(CraftableSponge(this))
|
||||
tweakManager.registerTweak(IceDecompression(this))
|
||||
tweakManager.registerTweak(LogsToChests(this))
|
||||
tweakManager.registerTweak(WoolToString(this))
|
||||
|
||||
/*
|
||||
* Crop Tweaks
|
||||
*/
|
||||
tweakManager.registerTweak(HoeHarvestArea(this))
|
||||
tweakManager.registerTweak(LilypadBonemealing(this, util))
|
||||
tweakManager.registerTweak(MobsCantTrampleCrops(this))
|
||||
tweakManager.registerTweak(PlayersCantTrampleCrops(this, trampleManager))
|
||||
tweakManager.registerTweak(SeedDropPlanting(this))
|
||||
tweakManager.registerTweak(SugarcaneBonemealing(this))
|
||||
|
||||
/*
|
||||
* Dispenser Tweaks
|
||||
*/
|
||||
tweakManager.registerTweak(DispensersCanPlantSaplings(this))
|
||||
|
||||
/*
|
||||
* Miscellaneous Tweaks
|
||||
*/
|
||||
tweakManager.registerTweak(ArmorStandArmorSwapping(this))
|
||||
tweakManager.registerTweak(CarpetBlockPlacingProtocol(this, mathHelper))
|
||||
tweakManager.registerTweak(FakePlayers(fakePlayerManager))
|
||||
tweakManager.registerTweak(SpaceTimePockets(this, pocketDimensionManager))
|
||||
|
||||
/*
|
||||
* Mob Tweaks
|
||||
*/
|
||||
tweakManager.registerTweak(NoCreeperGrief(this))
|
||||
tweakManager.registerTweak(NoDoorBreaking(this))
|
||||
tweakManager.registerTweak(NoEndermanGrief(this))
|
||||
tweakManager.registerTweak(VillagerInfo(this))
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
/*
|
||||
* Save data to disk
|
||||
*/
|
||||
tweakManager.saveToFile(File(dataFolder, Const.TWEAK_STATE_FILE_NAME))
|
||||
trampleManager.saveToFile(File(dataFolder, Const.TRAMPLE_ENABLED_FILE_NAME))
|
||||
pocketDimensionManager.saveData()
|
||||
}
|
||||
|
||||
private fun registerCommandConditions() {
|
||||
commandManager.commandConditions.addCondition("tweakEnabled") { context ->
|
||||
if (!tweakManager.isTweakEnabled(context.getConfigValue("tweak", "")))
|
||||
throw ConditionFailedException("The tweak ${context.getConfigValue("tweak", "")} is not enabled!")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package nl.kallestruik.dtweaks.commands
|
||||
|
||||
import co.aikar.commands.BaseCommand
|
||||
import co.aikar.commands.annotation.*
|
||||
import co.aikar.commands.annotation.Optional
|
||||
import com.mojang.datafixers.util.Pair
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.format.TextColor
|
||||
import net.minecraft.server.v1_16_R3.ChunkMapDistance
|
||||
import net.minecraft.server.v1_16_R3.EnumCreatureType
|
||||
import nl.kallestruik.dlib.ReflectionUtil
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
|
||||
@CommandAlias("mobcaps")
|
||||
class CommandMobcaps(
|
||||
private val reflectionUtil: ReflectionUtil
|
||||
): BaseCommand() {
|
||||
|
||||
@Default
|
||||
@Subcommand("view")
|
||||
@CommandCompletion("@worlds")
|
||||
fun onMobcaps(sender: CommandSender, @Optional worldName: String?) {
|
||||
var craftWorld: CraftWorld? = null
|
||||
|
||||
if (sender is Player)
|
||||
craftWorld = (sender.world as CraftWorld)
|
||||
else if (worldName == null)
|
||||
sender.sendMessage(Component.text("ERROR: You need to be a player or supply a world name!").color(TextColor.color(0x660000)))
|
||||
var name = worldName
|
||||
if (worldName == null) {
|
||||
name = craftWorld?.name
|
||||
} else {
|
||||
val bukkitWorld = Bukkit.getWorld(worldName)
|
||||
if (bukkitWorld == null)
|
||||
name = craftWorld?.name
|
||||
else
|
||||
craftWorld = (bukkitWorld as CraftWorld)
|
||||
}
|
||||
|
||||
val world = craftWorld?.handle ?: return
|
||||
|
||||
val chunkMapDistance = (
|
||||
reflectionUtil.getValueFromField(world.getChunkProvider(), "chunkMapDistance")
|
||||
?: return
|
||||
) as ChunkMapDistance
|
||||
|
||||
val chunks = chunkMapDistance.b()
|
||||
|
||||
// world.getChunkManager().getSpawnInfo();
|
||||
val spawnInfo = world.getChunkProvider()?.k() ?: return
|
||||
|
||||
val mobs: Object2IntMap<EnumCreatureType> = spawnInfo.b()
|
||||
val mobcaps = EnumMap<EnumCreatureType, Pair<Int, Int>>(
|
||||
EnumCreatureType::class.java
|
||||
)
|
||||
for (category in EnumCreatureType.values()) {
|
||||
if (category == EnumCreatureType.MISC) continue
|
||||
val cur: Int = mobs[category]?: 0
|
||||
val max = chunks * category.c() / (17 * 17)
|
||||
mobcaps[category] = Pair(cur, max)
|
||||
}
|
||||
|
||||
sender.sendMessage("=============Mobcaps [${name}]=============")
|
||||
for ((key, value) in mobcaps) {
|
||||
val cur = value.first
|
||||
val max = value.second
|
||||
sender.sendMessage("${key.getName()}: ${cur}/${max}")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package nl.kallestruik.dtweaks.commands
|
||||
|
||||
import co.aikar.commands.BaseCommand
|
||||
import co.aikar.commands.annotation.*
|
||||
import nl.kallestruik.dtweaks.managers.FakePlayerManager
|
||||
import nl.kallestruik.dtweaks.managers.TweakManager
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
@CommandAlias("player")
|
||||
@Conditions("tweakEnabled:tweak=FakePlayers")
|
||||
class CommandPlayer(
|
||||
private val fakePlayerManager: FakePlayerManager,
|
||||
private val tweakManager: TweakManager
|
||||
): BaseCommand() {
|
||||
|
||||
@Subcommand("spawn")
|
||||
@CommandCompletion("@players")
|
||||
fun onSpawn(sender: Player, @Single playerName: String) {
|
||||
fakePlayerManager.spawnFakePlayer(sender.location, playerName)
|
||||
}
|
||||
|
||||
@Subcommand("kill")
|
||||
@CommandCompletion("@players")
|
||||
fun onKill(sender: Player, @Single playerName: String) {
|
||||
fakePlayerManager.killFakePlayer(playerName)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package nl.kallestruik.dtweaks.commands
|
||||
|
||||
import co.aikar.commands.BaseCommand
|
||||
import co.aikar.commands.annotation.CommandAlias
|
||||
import co.aikar.commands.annotation.Conditions
|
||||
import co.aikar.commands.annotation.Subcommand
|
||||
import nl.kallestruik.dtweaks.managers.PocketDimensionManager
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
@CommandAlias("pocketdim")
|
||||
@Conditions("tweakEnabled:tweak=SpaceTimePockets")
|
||||
class CommandPocketdim(
|
||||
private val pocketDimensionManager: PocketDimensionManager
|
||||
): BaseCommand() {
|
||||
|
||||
@Subcommand("create")
|
||||
fun onCreate(sender: Player) {
|
||||
pocketDimensionManager.createPocketForPlayer(sender)
|
||||
}
|
||||
|
||||
@Subcommand("tp")
|
||||
fun onTp(sender: Player) {
|
||||
pocketDimensionManager.teleportPlayerIntoPocket(sender, sender.uniqueId)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package nl.kallestruik.dtweaks.commands
|
||||
|
||||
import co.aikar.commands.BaseCommand
|
||||
import co.aikar.commands.annotation.CommandAlias
|
||||
import co.aikar.commands.annotation.Conditions
|
||||
import co.aikar.commands.annotation.Default
|
||||
import nl.kallestruik.dtweaks.managers.TrampleManager
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
@CommandAlias("toggletrample")
|
||||
@Conditions("tweakEnabled:tweak=PlayersCantTrampleCrops")
|
||||
class CommandToggletrample(
|
||||
private val trampleManager: TrampleManager
|
||||
): BaseCommand() {
|
||||
|
||||
@Default
|
||||
fun onToggle(sender: Player) {
|
||||
if (trampleManager.trampleEnabled.remove(sender.uniqueId)) {
|
||||
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2Crop Trampling: &4&lDisabled"))
|
||||
} else {
|
||||
trampleManager.trampleEnabled.add(sender.uniqueId)
|
||||
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2Crop Trampling: &2&lEnabled"))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import io.netty.util.concurrent.Future
|
||||
import io.netty.util.concurrent.GenericFutureListener
|
||||
import net.minecraft.server.v1_16_R3.EnumProtocolDirection
|
||||
import net.minecraft.server.v1_16_R3.NetworkManager
|
||||
import net.minecraft.server.v1_16_R3.Packet
|
||||
|
||||
class FakeConnection(
|
||||
enumProtocolDirection: EnumProtocolDirection
|
||||
): NetworkManager(enumProtocolDirection) {
|
||||
var open = true
|
||||
|
||||
// isOpen()
|
||||
override fun isConnected(): Boolean {
|
||||
return open
|
||||
}
|
||||
|
||||
// hasChannel()
|
||||
override fun i(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun sendPacket(packet: Packet<*>?, genericfuturelistener: GenericFutureListener<out Future<in Void?>?>?) {}
|
||||
|
||||
// disableAutoRead()
|
||||
override fun stopReading() {}
|
||||
|
||||
override fun handleDisconnection() {}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import com.mojang.authlib.GameProfile
|
||||
import net.minecraft.server.v1_16_R3.*
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld
|
||||
|
||||
class FakePlayer(
|
||||
minecraftServer: MinecraftServer?,
|
||||
worldServer: WorldServer?,
|
||||
gameProfile: GameProfile?,
|
||||
playerInteractManager: PlayerInteractManager?
|
||||
): EntityPlayer(minecraftServer, worldServer, gameProfile, playerInteractManager) {
|
||||
val locale = "en_US"
|
||||
private var hasStartingPos = false
|
||||
private var startingX = 0.0
|
||||
private var startingY = 0.0
|
||||
private var startingZ = 0.0
|
||||
private var startingYaw = 0f
|
||||
private var startingPitch = 0f
|
||||
|
||||
private constructor(
|
||||
server: MinecraftServer,
|
||||
worldIn: WorldServer,
|
||||
profile: GameProfile?,
|
||||
interactionManagerIn: PlayerInteractManager,
|
||||
x: Double,
|
||||
y: Double,
|
||||
z: Double,
|
||||
yaw: Float,
|
||||
pitch: Float
|
||||
) : this(server, worldIn, profile, interactionManagerIn) {
|
||||
this.hasStartingPos = true
|
||||
this.startingX = x
|
||||
this.startingY = y
|
||||
this.startingZ = z
|
||||
this.startingYaw = yaw
|
||||
this.startingPitch = pitch
|
||||
applyStartingPosition()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun atLocation(location: Location, name: String?): FakePlayer? {
|
||||
// Split the location into its parts for use later.
|
||||
val x = location.x
|
||||
val y = location.y
|
||||
val z = location.z
|
||||
val yaw = location.yaw.toDouble()
|
||||
val pitch = location.pitch.toDouble()
|
||||
try {
|
||||
// Get the minecraft server instance.
|
||||
val minecraftServer = MinecraftServer.getServer()
|
||||
// Create an empty variable for the world server.
|
||||
val worldServer = (location.world as CraftWorld).handle
|
||||
// Get the game profile from the cache (or retrieve it if it is not cached)
|
||||
var gameProfile = minecraftServer.userCache.getProfile(name) ?: return null
|
||||
if (gameProfile.properties.containsKey("textures")) {
|
||||
gameProfile = TileEntitySkull.b(gameProfile, null, true).get()
|
||||
}
|
||||
|
||||
// Create a player interact manager using the world server.
|
||||
val playerInteractManager = PlayerInteractManager(worldServer)
|
||||
|
||||
// Create an instance of our fake player.
|
||||
val instance = FakePlayer(
|
||||
minecraftServer, worldServer, gameProfile, playerInteractManager, x, y, z,
|
||||
yaw.toFloat(),
|
||||
pitch.toFloat()
|
||||
)
|
||||
// Create a fake connection for our fake player.
|
||||
val connection = FakeConnection(EnumProtocolDirection.SERVERBOUND)
|
||||
|
||||
// Set access to connected channels so we can add our own connection.
|
||||
val serverConnection = minecraftServer.serverConnection
|
||||
|
||||
(DTweaks.reflectionUtil.getValueFromField(
|
||||
serverConnection!!,
|
||||
"connectedChannels"
|
||||
) as MutableList<NetworkManager?>).add(connection)
|
||||
|
||||
// Connect the fake player to the server using the fake connection.
|
||||
FakePlayerList.a(minecraftServer.playerList, connection, instance)
|
||||
|
||||
// Check if the fake player is not yet in the correct world.
|
||||
if (instance.world.dimensionKey != worldServer.dimensionKey) {
|
||||
// Store the old world of the fake player.
|
||||
val old_world = instance.world as WorldServer
|
||||
// Remove the fake player from the old world.
|
||||
old_world.removePlayer(instance)
|
||||
// Make the fake player not be dead.
|
||||
instance.dead = false
|
||||
// Create the fake player in the new world.
|
||||
worldServer.addEntity(instance)
|
||||
// Spawn the fake player in the new world.
|
||||
instance.spawnIn(worldServer)
|
||||
// Move the fake player to the new world for the server.
|
||||
minecraftServer.playerList.moveToWorld(instance, old_world, true, null, false)
|
||||
// requestTeleport(x, y, z, yaw, pitch)
|
||||
// Request the teleport from the fake player.
|
||||
instance.playerConnection.a(x, y, z, yaw.toFloat(), pitch.toFloat())
|
||||
// Set the fake player's world to the new world.
|
||||
instance.playerInteractManager.world = worldServer
|
||||
instance.teleportTo(worldServer, BlockPosition(x, y, z))
|
||||
}
|
||||
|
||||
/// Set the fake players health to max.
|
||||
instance.health = 20.0f
|
||||
// Make the fake player not be dead.
|
||||
instance.dead = false
|
||||
// a == requestTeleport
|
||||
// Request the teleport from the fake player.
|
||||
instance.playerConnection.a(x, y, z, yaw.toFloat(), pitch.toFloat())
|
||||
// G == stepHeight
|
||||
// Set the fake players step height to 0.6 (The normal value).
|
||||
instance.G = 0.6f
|
||||
// Set the fake players gamemode to survival.
|
||||
playerInteractManager.gameMode = EnumGamemode.SURVIVAL
|
||||
// Tell everyone in the world about the fake player and where he is.
|
||||
minecraftServer.playerList.a(
|
||||
PacketPlayOutEntityHeadRotation(instance, (instance.yaw * 256 / 360).toByte()),
|
||||
instance.world.dimensionKey
|
||||
)
|
||||
minecraftServer.playerList.a(PacketPlayOutEntityTeleport(instance), instance.world.dimensionKey)
|
||||
// Move the fake player for the worlds chunk provider.
|
||||
instance.worldServer.getChunkProvider().movePlayer(instance)
|
||||
// bp == PLAYER_MODEL_PARTS
|
||||
instance.datawatcher.set<Byte>(bj, 0x7f.toByte()) // show all model layers (incl. capes)
|
||||
return instance
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun applyStartingPosition() {
|
||||
if (hasStartingPos) {
|
||||
this.setPositionRotation(startingX, startingY, startingZ, startingYaw, startingPitch)
|
||||
mot = Vec3D(0.0, 0.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun killEntity() {
|
||||
server.a(TickTask(server.ai()) { playerConnection.a(ChatComponentText("Killed")) })
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
if (H()) {
|
||||
I()
|
||||
}
|
||||
movementTick()
|
||||
if (server.ai() % 10 == 0) {
|
||||
playerConnection.syncPosition()
|
||||
this.worldServer.getChunkProvider().movePlayer(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun die(cause: DamageSource?) {
|
||||
super.die(cause)
|
||||
health = 20f
|
||||
foodData = FoodMetaData(this)
|
||||
killEntity()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import net.minecraft.server.v1_16_R3.*
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import java.lang.reflect.Field
|
||||
|
||||
class FakePlayerConnection(
|
||||
minecraftServer: MinecraftServer,
|
||||
networkManager: NetworkManager,
|
||||
entityPlayer: EntityPlayer
|
||||
): PlayerConnection(minecraftServer, networkManager, entityPlayer) {
|
||||
override fun sendPacket(packet: Packet<*>?) {
|
||||
if (packet is PacketPlayOutKeepAlive) {
|
||||
val pong = PacketPlayInKeepAlive()
|
||||
try {
|
||||
val pingId: Field = DTweaks.reflectionUtil.getField(PacketPlayOutKeepAlive::class.java, "a")
|
||||
val pongId: Field = DTweaks.reflectionUtil.getField(PacketPlayInKeepAlive::class.java, "a")
|
||||
pingId.isAccessible = true
|
||||
pongId.isAccessible = true
|
||||
pongId[pong] = pingId[packet]
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
this.a(pong)
|
||||
}
|
||||
}
|
||||
|
||||
override fun disconnect(message: String?) {
|
||||
player.killEntity()
|
||||
}
|
||||
|
||||
override fun a(disconnectReason: IChatBaseComponent?) {
|
||||
super.a(disconnectReason)
|
||||
(this.a() as FakeConnection).open = false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import com.mojang.serialization.DataResult
|
||||
import com.mojang.serialization.Dynamic
|
||||
import io.netty.buffer.Unpooled
|
||||
import net.minecraft.server.v1_16_R3.*
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import org.apache.logging.log4j.Logger
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld
|
||||
import org.bukkit.craftbukkit.v1_16_R3.util.CraftChatMessage
|
||||
import org.bukkit.entity.Player
|
||||
import org.spigotmc.event.player.PlayerSpawnLocationEvent
|
||||
import java.util.*
|
||||
|
||||
object FakePlayerList {
|
||||
fun a(playerList: PlayerList, networkManager: NetworkManager, entityPlayer: EntityPlayer) {
|
||||
// Setup what are normally class level variables
|
||||
val server = DTweaks.reflectionUtil.getValueFromField(playerList, "server") as MinecraftServer
|
||||
val LOGGER = DTweaks.reflectionUtil.getValueFromField(playerList, "LOGGER") as Logger
|
||||
|
||||
val gameProfile = entityPlayer.profile
|
||||
val userCache = server.userCache
|
||||
val oldGameProfile = userCache.getProfile(gameProfile.id)
|
||||
var oldName = if (oldGameProfile == null) gameProfile.name else oldGameProfile.name
|
||||
|
||||
userCache.a(gameProfile)
|
||||
val playerData = playerList.a(entityPlayer)
|
||||
if (playerData != null && playerData.hasKey("bukkit")) {
|
||||
val bukkit = playerData.getCompound("bukkit")
|
||||
oldName = if (bukkit.hasKeyOfType("lastKnownName", 8)) bukkit.getString("lastKnownName") else oldName
|
||||
}
|
||||
val worldKey: ResourceKey<World> = if (playerData != null) {
|
||||
val dataResult: DataResult<ResourceKey<World>> = DimensionManager.a(
|
||||
Dynamic(
|
||||
DynamicOpsNBT.a,
|
||||
playerData["Dimension"]
|
||||
)
|
||||
)
|
||||
dataResult.resultOrPartial { o -> LOGGER.error(o) }
|
||||
.orElse(World.OVERWORLD) as ResourceKey<World>
|
||||
} else {
|
||||
World.OVERWORLD
|
||||
}
|
||||
var worldServer = server.getWorldServer(worldKey) ?: server.E()
|
||||
|
||||
entityPlayer.spawnIn(worldServer)
|
||||
entityPlayer.playerInteractManager.a(entityPlayer.world as WorldServer)
|
||||
var s1 = "local"
|
||||
if (networkManager.getSocketAddress() != null) {
|
||||
s1 = networkManager.getSocketAddress().toString()
|
||||
}
|
||||
val bukkitPlayer: Player = entityPlayer.bukkitEntity
|
||||
val ev = PlayerSpawnLocationEvent(bukkitPlayer, bukkitPlayer.location)
|
||||
Bukkit.getPluginManager().callEvent(ev)
|
||||
val loc = ev.spawnLocation
|
||||
worldServer = (loc.world as CraftWorld).handle
|
||||
entityPlayer.spawnIn(worldServer)
|
||||
entityPlayer.playerInteractManager.a(entityPlayer.world as WorldServer)
|
||||
entityPlayer.setPosition(loc.x, loc.y, loc.z)
|
||||
|
||||
//entityplayer.setYawPitch(loc.getYaw(), loc.getPitch());
|
||||
try {
|
||||
val setYawPitch = Entity::class.java.getDeclaredMethod(
|
||||
"setYawPitch",
|
||||
Float::class.javaPrimitiveType,
|
||||
Float::class.javaPrimitiveType
|
||||
)
|
||||
setYawPitch.isAccessible = true
|
||||
setYawPitch.invoke(entityPlayer, loc.yaw, loc.pitch)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
val worldData = worldServer.getWorldData()
|
||||
|
||||
//playerList.a(entityplayer, (EntityPlayer)null, worldserver1);
|
||||
try {
|
||||
val a = PlayerList::class.java.getDeclaredMethod(
|
||||
"a",
|
||||
EntityPlayer::class.java,
|
||||
EntityPlayer::class.java,
|
||||
WorldServer::class.java
|
||||
)
|
||||
a.isAccessible = true
|
||||
a.invoke(playerList, entityPlayer, null, worldServer)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
//PlayerConnection playerconnection = new PlayerConnection(server, networkmanager, entityplayer);
|
||||
val playerConnection: PlayerConnection =
|
||||
(entityPlayer as? FakePlayer)?.let { FakePlayerConnection(server, networkManager, it) }
|
||||
?: PlayerConnection(server, networkManager, entityPlayer)
|
||||
val gameRules = worldServer.gameRules
|
||||
val doImmediateRespawn = gameRules.getBoolean(GameRules.DO_IMMEDIATE_RESPAWN)
|
||||
val reducedDebugInfo = gameRules.getBoolean(GameRules.REDUCED_DEBUG_INFO)
|
||||
try {
|
||||
playerConnection.sendPacket(
|
||||
PacketPlayOutLogin(
|
||||
entityPlayer.id,
|
||||
entityPlayer.playerInteractManager.gameMode,
|
||||
entityPlayer.playerInteractManager.c(),
|
||||
BiomeManager.a(
|
||||
worldServer.seed
|
||||
),
|
||||
worldData.isHardcore,
|
||||
server.F(),
|
||||
DTweaks.reflectionUtil.getValueFromField(playerList, "s") as IRegistryCustom.Dimension,
|
||||
worldServer.dimensionManager,
|
||||
worldServer.dimensionKey,
|
||||
playerList.maxPlayers,
|
||||
worldServer.spigotConfig.viewDistance,
|
||||
reducedDebugInfo,
|
||||
!doImmediateRespawn,
|
||||
worldServer.isDebugWorld,
|
||||
worldServer.isFlatWorld
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
entityPlayer.bukkitEntity.sendSupportedChannels()
|
||||
playerConnection.sendPacket(
|
||||
PacketPlayOutCustomPayload(
|
||||
PacketPlayOutCustomPayload.a,
|
||||
PacketDataSerializer(Unpooled.buffer()).a(playerList.server.serverModName)
|
||||
)
|
||||
)
|
||||
playerConnection.sendPacket(PacketPlayOutServerDifficulty(worldData.difficulty, worldData.isDifficultyLocked))
|
||||
playerConnection.sendPacket(PacketPlayOutAbilities(entityPlayer.abilities))
|
||||
playerConnection.sendPacket(PacketPlayOutHeldItemSlot(entityPlayer.inventory.itemInHandIndex))
|
||||
playerConnection.sendPacket(PacketPlayOutRecipeUpdate(server.craftingManager.b()))
|
||||
playerConnection.sendPacket(PacketPlayOutTags(server.tagRegistry))
|
||||
playerList.d(entityPlayer)
|
||||
entityPlayer.statisticManager.c()
|
||||
entityPlayer.recipeBook.a(entityPlayer)
|
||||
playerList.sendScoreboard(worldServer.scoreboard, entityPlayer)
|
||||
server.invalidatePingSample()
|
||||
val chatMessage = if (entityPlayer.profile.name.equals(oldName, ignoreCase = true)) {
|
||||
ChatMessage("multiplayer.player.joined", entityPlayer.scoreboardDisplayName)
|
||||
} else {
|
||||
ChatMessage("multiplayer.player.joined.renamed", entityPlayer.scoreboardDisplayName, oldName)
|
||||
}
|
||||
chatMessage.a(EnumChatFormat.YELLOW)
|
||||
var joinMessage = CraftChatMessage.fromComponent(chatMessage)
|
||||
playerConnection.a(
|
||||
entityPlayer.locX(),
|
||||
entityPlayer.locY(),
|
||||
entityPlayer.locZ(),
|
||||
entityPlayer.yaw,
|
||||
entityPlayer.pitch
|
||||
)
|
||||
playerList.players.add(entityPlayer)
|
||||
|
||||
//playerList.playersByName.put(entityplayer.getName().toLowerCase(Locale.ROOT), entityplayer);
|
||||
val playersByName = DTweaks.reflectionUtil.getValueFromField(playerList, "playersByName") as HashMap<String, EntityPlayer>
|
||||
playersByName[entityPlayer.name.toLowerCase(Locale.ROOT)] = entityPlayer
|
||||
|
||||
//playerList.j.put(entityplayer.getUniqueID(), entityplayer);
|
||||
val playersByUUID = DTweaks.reflectionUtil.getValueFromField(playerList, "j") as HashMap<UUID, EntityPlayer>
|
||||
playersByUUID[entityPlayer.uniqueID] = entityPlayer
|
||||
|
||||
if (entityPlayer.playerConnection.networkManager.isConnected) {
|
||||
var i: Int
|
||||
if (joinMessage != null && joinMessage.isNotEmpty()) {
|
||||
var var27: Array<IChatBaseComponent?>
|
||||
val var26 = CraftChatMessage.fromString(joinMessage).also { var27 = it }.size
|
||||
i = 0
|
||||
while (i < var26) {
|
||||
val line = var27[i]
|
||||
server.playerList.sendAll(PacketPlayOutChat(line, ChatMessageType.SYSTEM, SystemUtils.b))
|
||||
++i
|
||||
}
|
||||
}
|
||||
val packet = PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entityPlayer)
|
||||
for (player in playerList.players) {
|
||||
if (player.bukkitEntity.canSee(entityPlayer.bukkitEntity)) {
|
||||
player.playerConnection.sendPacket(packet)
|
||||
}
|
||||
if (entityPlayer.bukkitEntity.canSee(player.bukkitEntity)) {
|
||||
entityPlayer.playerConnection.sendPacket(
|
||||
PacketPlayOutPlayerInfo(
|
||||
PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER,
|
||||
player
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
entityPlayer.sentListPacket = true
|
||||
entityPlayer.playerConnection.sendPacket(
|
||||
PacketPlayOutEntityMetadata(
|
||||
entityPlayer.id,
|
||||
DTweaks.reflectionUtil.getValueFromField(entityPlayer, "datawatcher") as DataWatcher, true
|
||||
)
|
||||
)
|
||||
|
||||
if (entityPlayer.world === worldServer && !worldServer.getPlayers().contains(entityPlayer)) {
|
||||
worldServer.addPlayerJoin(entityPlayer)
|
||||
server.bossBattleCustomData.a(entityPlayer)
|
||||
}
|
||||
|
||||
worldServer = entityPlayer.worldServer
|
||||
playerList.a(entityPlayer, worldServer)
|
||||
if (server.resourcePack.isNotEmpty()) {
|
||||
entityPlayer.setResourcePack(server.resourcePack, server.resourcePackHash)
|
||||
}
|
||||
|
||||
for (mobEffect in entityPlayer.getEffects()) {
|
||||
playerConnection.sendPacket(PacketPlayOutEntityEffect(entityPlayer.id, mobEffect))
|
||||
}
|
||||
|
||||
if (playerData != null && playerData.hasKeyOfType("RootVehicle", 10)) {
|
||||
val rootVehicleData = playerData.getCompound("RootVehicle")
|
||||
val entity = EntityTypes.a(
|
||||
rootVehicleData.getCompound("Entity"), worldServer
|
||||
) { entity1x: Entity? ->
|
||||
if (!worldServer.addEntitySerialized(entity1x)
|
||||
) null else entity1x
|
||||
}
|
||||
if (entity != null) {
|
||||
val uuid: UUID? = if (rootVehicleData.b("Attach")) {
|
||||
rootVehicleData.a("Attach")
|
||||
} else {
|
||||
null
|
||||
}
|
||||
if (entity.uniqueID == uuid) {
|
||||
entityPlayer.a(entity, true)
|
||||
} else {
|
||||
for (passenger in entity.allPassengers) {
|
||||
if (passenger.uniqueID == uuid) {
|
||||
entityPlayer.a(passenger, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!entityPlayer.isPassenger) {
|
||||
LOGGER.warn("Couldn't reattach entity to player")
|
||||
worldServer.removeEntity(entity)
|
||||
for (passenger in entity.allPassengers) {
|
||||
worldServer.removeEntity(passenger)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
entityPlayer.syncInventory()
|
||||
LOGGER.info(
|
||||
"{}[{}] logged in with entity id {} at ([{}]{}, {}, {})",
|
||||
entityPlayer.getDisplayName().string,
|
||||
s1,
|
||||
entityPlayer.id,
|
||||
worldServer?.worldDataServer?.name,
|
||||
entityPlayer.locX(),
|
||||
entityPlayer.locY(),
|
||||
entityPlayer.locZ()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package nl.kallestruik.dtweaks.managers
|
||||
|
||||
import nl.kallestruik.dtweaks.fakeplayer.FakePlayer
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer
|
||||
|
||||
class FakePlayerManager {
|
||||
|
||||
fun spawnFakePlayer(loc: Location, name: String) {
|
||||
val player = Bukkit.getPlayer(name)
|
||||
if (player != null && player.isOnline) return
|
||||
FakePlayer.atLocation(loc, name)
|
||||
}
|
||||
|
||||
fun killFakePlayer(name: String) {
|
||||
val player = Bukkit.getPlayer(name)
|
||||
if (player == null || !player.isOnline) return
|
||||
val entityPlayer = (player as CraftPlayer).handle as? FakePlayer ?: return
|
||||
entityPlayer.killEntity()
|
||||
}
|
||||
|
||||
fun killAllFakePlayers() {
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
if (!player.isOnline) continue
|
||||
val entityPlayer = (player as CraftPlayer).handle as? FakePlayer ?: continue
|
||||
entityPlayer.killEntity()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package nl.kallestruik.dtweaks.managers
|
||||
|
||||
import net.minecraft.server.v1_16_R3.MathHelper
|
||||
import nl.kallestruik.dlib.MathHelper
|
||||
import nl.kallestruik.dtweaks.spacetimepockets.SpaceTimePocketChunkGenerator
|
||||
import org.bukkit.*
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
|
||||
class PocketDimensionManager(
|
||||
private val mathHelper: MathHelper
|
||||
) {
|
||||
val pocketDimension: World = WorldCreator.name("space-time-pockets").generator(SpaceTimePocketChunkGenerator()).createWorld()!!
|
||||
private val data = HashMap<UUID, PocketData>()
|
||||
private var lastCreatedPocket = -1
|
||||
|
||||
fun loadData() {
|
||||
//TODO: Load data from data file on disk.
|
||||
}
|
||||
|
||||
fun saveData() {
|
||||
//TODO: Save data to file on disk.
|
||||
}
|
||||
|
||||
fun teleportPlayerIntoPocket(player: Player, pocketOwner: UUID) {
|
||||
var pocketData = data[pocketOwner]
|
||||
if (pocketData == null) pocketData = if (player.uniqueId == pocketOwner) {
|
||||
createPocketForPlayer(player)
|
||||
} else return
|
||||
player.teleport(
|
||||
Location(
|
||||
pocketDimension, (pocketData.startX + 9).toDouble(), 128.0,
|
||||
(pocketData.startZ + 9).toDouble()
|
||||
)
|
||||
)
|
||||
Bukkit.unloadWorld()
|
||||
}
|
||||
|
||||
fun createPocketForPlayer(player: Player): PocketData {
|
||||
// Find a spot
|
||||
val point = findNextFree()
|
||||
|
||||
// Load the chunks
|
||||
for (x in 0..2) {
|
||||
for (y in 0..2) {
|
||||
pocketDimension.loadChunk(point.x / 16 + x, point.z / 16 + y)
|
||||
}
|
||||
}
|
||||
|
||||
// Build the box
|
||||
for (x in 0..17) {
|
||||
for (z in 0..17) {
|
||||
for (y in 0..255) {
|
||||
if (x == 0 || y == 0 || z == 0 || x == 17 || y == 255 || z == 17) {
|
||||
pocketDimension.getBlockAt(point.x + x, y, point.z + z).type = Material.BLACK_CONCRETE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the spawning platform
|
||||
pocketDimension.getBlockAt(point.x + 8, 127, point.z + 8).type = Material.STONE
|
||||
pocketDimension.getBlockAt(point.x + 8, 127, point.z + 9).type = Material.STONE
|
||||
pocketDimension.getBlockAt(point.x + 9, 127, point.z + 8).type = Material.STONE
|
||||
pocketDimension.getBlockAt(point.x + 9, 127, point.z + 9).type = Material.STONE
|
||||
|
||||
// Unload the chunks
|
||||
for (x in 0..2) {
|
||||
for (y in 0..2) {
|
||||
pocketDimension.unloadChunk(point.x / 16 + x, point.z / 16 + y)
|
||||
}
|
||||
}
|
||||
val pocketData = PocketData(player.uniqueId, point.x, point.z, ArrayList())
|
||||
data[player.uniqueId] = pocketData
|
||||
return pocketData
|
||||
}
|
||||
|
||||
private fun findNextFree(): Point {
|
||||
while (true) {
|
||||
lastCreatedPocket++
|
||||
val toCheck = getXYForIndex(lastCreatedPocket)
|
||||
val chunk = pocketDimension.getChunkAt(
|
||||
Location(
|
||||
pocketDimension,
|
||||
toCheck.x.toDouble(), 0.0, toCheck.z.toDouble()
|
||||
)
|
||||
)
|
||||
val corner = chunk.getBlock(mathHelper.chunkAbs(toCheck.x % 16), 0, mathHelper.chunkAbs(toCheck.z % 16))
|
||||
if (corner.type == Material.AIR) {
|
||||
return toCheck
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getXYForIndex(index: Int): Point {
|
||||
// Space the pockets 256 blocks (16 chunks) from each other with each pocket being 16 blocks (and two for walls)
|
||||
// Also subtract 1 from each point so the interior is chunk aligned.
|
||||
val x = (256 + 16) * (index % 1000) - 1
|
||||
val z = (256 + 16) * (index / 1000) - 1
|
||||
return Point(x, z)
|
||||
}
|
||||
|
||||
class PocketData(var owner: UUID, var startX: Int, var startZ: Int, var queuedGateways: ArrayList<GatewayData?>)
|
||||
|
||||
class GatewayData
|
||||
|
||||
class Point(var x: Int, var y: Int, var z: Int) {
|
||||
constructor(x: Int, z: Int) : this(x, 0, z) {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package nl.kallestruik.dtweaks.managers
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
class TrampleManager {
|
||||
var trampleEnabled = HashSet<UUID>()
|
||||
|
||||
@Throws(IOException::class, InvalidConfigurationException::class)
|
||||
fun loadFromFile(file: File) {
|
||||
file.parentFile.mkdirs()
|
||||
file.createNewFile()
|
||||
val config = YamlConfiguration()
|
||||
config.load(file)
|
||||
for (item in config.getStringList("enabled"))
|
||||
trampleEnabled.add(UUID.fromString(item))
|
||||
}
|
||||
|
||||
@Throws(IOException::class, InvalidConfigurationException::class)
|
||||
fun saveToFile(file: File) {
|
||||
file.parentFile.mkdirs()
|
||||
file.createNewFile()
|
||||
val config = YamlConfiguration()
|
||||
config.load(file)
|
||||
val list: MutableList<String> = ArrayList()
|
||||
for (entry in trampleEnabled)
|
||||
list.add(entry.toString())
|
||||
|
||||
config["enabled"] = list
|
||||
config.save(file)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package nl.kallestruik.dtweaks.managers
|
||||
|
||||
import nl.kallestruik.dtweaks.Const
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class TweakManager(
|
||||
private val plugin: JavaPlugin
|
||||
) {
|
||||
|
||||
// A HashMap containing the tweak identifier mapped to the instance of the tweak.
|
||||
private val tweaks: ConcurrentHashMap<String, ITweak> = ConcurrentHashMap<String, ITweak>()
|
||||
|
||||
// A HashMap containing categories and the tweak identifiers that belong to them.
|
||||
private val tweakCategories = HashMap<String, List<String>>()
|
||||
|
||||
// A HashMap containing the sate of all the known tweaks.
|
||||
private val tweakStates = HashMap<String, Boolean>()
|
||||
|
||||
|
||||
/**
|
||||
* Register a new tweak.
|
||||
*
|
||||
* @param tweak An instance of the tweak.
|
||||
* @return True if the tweak did not yet exist false otherwise.
|
||||
*/
|
||||
fun registerTweak(tweak: ITweak): Boolean {
|
||||
if (tweaks.containsKey(tweak.getIdentifier())) return false
|
||||
tweaks[tweak.getIdentifier()] = tweak
|
||||
tweakCategories[tweak.getIdentifier()] = tweak.getCategories()
|
||||
tweak.onRegister()
|
||||
if (tweakStates.getOrDefault(tweak.getIdentifier(), false)) tweak.onEnable()
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a tweak.
|
||||
*
|
||||
* @param identifier The identifier of the tweak to unregister.
|
||||
* @return True if the tweak was successfully unregistered false otherwise.
|
||||
*/
|
||||
fun unRegisterTweak(identifier: String): Boolean {
|
||||
if (!tweaks.containsKey(identifier)) return false
|
||||
val tweak: ITweak? = tweaks[identifier]
|
||||
tweak?.onDisable()
|
||||
tweak?.onUnRegister()
|
||||
tweaks.remove(identifier)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister every tweak that is currently registered.
|
||||
*/
|
||||
fun unRegisterAllTweaks() {
|
||||
for (identifier in tweaks.keys) {
|
||||
unRegisterTweak(identifier)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a tweak.
|
||||
*
|
||||
* @param identifier The identifier of the tweak.
|
||||
* @return True if the tweak exists false otherwise.
|
||||
*/
|
||||
fun enableTweak(identifier: String): Boolean {
|
||||
if (!tweaks.containsKey(identifier)) return false
|
||||
tweakStates[identifier] = true
|
||||
tweaks[identifier]?.onEnable()
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a tweak.
|
||||
*
|
||||
* @param identifier The identifier of the tweak.
|
||||
* @return True if the tweak exists false otherwise.
|
||||
*/
|
||||
fun disableTweak(identifier: String): Boolean {
|
||||
if (!tweaks.containsKey(identifier)) return false
|
||||
tweakStates[identifier] = false
|
||||
tweaks[identifier]?.onDisable()
|
||||
return true
|
||||
}
|
||||
|
||||
@Throws(IOException::class, InvalidConfigurationException::class)
|
||||
fun loadFromFile(file: File) {
|
||||
if (!file.parentFile.exists()) file.parentFile.mkdirs()
|
||||
if (!file.exists())
|
||||
plugin.saveResource(file.name, false)
|
||||
|
||||
val config = YamlConfiguration()
|
||||
config.load(file)
|
||||
for (key in config.getKeys(false)) {
|
||||
tweakStates[key] = config.getBoolean(key!!)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun saveToFile(file: File) {
|
||||
val config = YamlConfiguration()
|
||||
for ((key, value) in tweakStates.entries) {
|
||||
config[key] = value
|
||||
}
|
||||
config.save(file)
|
||||
}
|
||||
|
||||
fun isTweakEnabled(tweakId: String): Boolean {
|
||||
return tweakStates[tweakId] ?: false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package nl.kallestruik.dtweaks.spacetimepockets
|
||||
|
||||
import org.bukkit.World
|
||||
import org.bukkit.block.Biome
|
||||
import org.bukkit.craftbukkit.v1_16_R3.generator.CraftChunkData
|
||||
import org.bukkit.generator.ChunkGenerator
|
||||
import java.util.*
|
||||
|
||||
class SpaceTimePocketChunkGenerator: ChunkGenerator() {
|
||||
|
||||
override fun generateChunkData(
|
||||
world: World,
|
||||
random: Random,
|
||||
x: Int,
|
||||
z: Int,
|
||||
biome: BiomeGrid
|
||||
): ChunkData {
|
||||
for (cx in 0..15) {
|
||||
for (cz in 0..15) {
|
||||
for (cy in 0..264) {
|
||||
biome.setBiome(cx, cy, cz, Biome.THE_VOID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return CraftChunkData(world)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package nl.kallestruik.dtweaks.tweaks
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
interface ITweak {
|
||||
fun getIdentifier(): String
|
||||
|
||||
fun getCategories(): List<String>
|
||||
|
||||
fun onRegister() {}
|
||||
|
||||
fun onUnRegister() {}
|
||||
|
||||
fun onEnable() {}
|
||||
|
||||
fun onDisable() {}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class AlternativeDispenserRecipe(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "dispenser")
|
||||
|
||||
override fun getIdentifier(): String = "AlternativeDispenserRecipe"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val dispenserRecipe = ShapedRecipe(recipeKey, ItemStack(Material.DISPENSER))
|
||||
dispenserRecipe.shape(" TS", "TDS", " TS")
|
||||
dispenserRecipe.setIngredient('T', Material.STICK)
|
||||
dispenserRecipe.setIngredient('D', Material.DROPPER)
|
||||
dispenserRecipe.setIngredient('S', Material.STRING)
|
||||
|
||||
plugin.server.addRecipe(dispenserRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class CraftableDragonsBreath(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "dragon_breath")
|
||||
|
||||
override fun getIdentifier(): String = "CraftableDragonsBreath"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val dragonBreathRecipe = ShapedRecipe(recipeKey, ItemStack(Material.DRAGON_BREATH, 3))
|
||||
dragonBreathRecipe.shape("GCG", " G ")
|
||||
dragonBreathRecipe.setIngredient('G', Material.GLASS)
|
||||
dragonBreathRecipe.setIngredient('C', Material.POPPED_CHORUS_FRUIT)
|
||||
|
||||
plugin.server.addRecipe(dragonBreathRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class CraftableNametag(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "nametag")
|
||||
|
||||
override fun getIdentifier(): String = "CraftableNametag"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val nametagRecipe = ShapedRecipe(recipeKey, ItemStack(Material.NAME_TAG))
|
||||
nametagRecipe.shape(" IS", " PI", "P ")
|
||||
nametagRecipe.setIngredient('I', Material.IRON_INGOT)
|
||||
nametagRecipe.setIngredient('P', Material.PAPER)
|
||||
nametagRecipe.setIngredient('S', Material.STRING)
|
||||
|
||||
plugin.server.addRecipe(nametagRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class CraftableSaddle(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "saddle")
|
||||
|
||||
override fun getIdentifier(): String = "CraftableSaddle"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val saddleRecipe = ShapedRecipe(recipeKey, ItemStack(Material.SADDLE))
|
||||
saddleRecipe.shape("LLL", "S S", "I I")
|
||||
saddleRecipe.setIngredient('L', Material.LEATHER)
|
||||
saddleRecipe.setIngredient('S', Material.STRING)
|
||||
saddleRecipe.setIngredient('I', Material.IRON_INGOT)
|
||||
|
||||
plugin.server.addRecipe(saddleRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class CraftableShulkerShell(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "shulker_shell")
|
||||
|
||||
override fun getIdentifier(): String = "CraftableShulkerShell"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val shulkerShellRecipe = ShapedRecipe(recipeKey, ItemStack(Material.SHULKER_SHELL))
|
||||
shulkerShellRecipe.shape("BBB", "F F")
|
||||
shulkerShellRecipe.setIngredient('B', Material.PURPUR_SLAB)
|
||||
shulkerShellRecipe.setIngredient('F', Material.POPPED_CHORUS_FRUIT)
|
||||
|
||||
plugin.server.addRecipe(shulkerShellRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class CraftableSponge(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "sponge")
|
||||
|
||||
override fun getIdentifier(): String = "CraftableSponge"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val spongeRecipe = ShapedRecipe(recipeKey, ItemStack(Material.SPONGE))
|
||||
spongeRecipe.shape("KKK", "KDK", "KKK")
|
||||
spongeRecipe.setIngredient('K', Material.KELP)
|
||||
spongeRecipe.setIngredient('D', Material.YELLOW_DYE)
|
||||
|
||||
plugin.server.addRecipe(spongeRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.ShapelessRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class IceDecompression(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var packedIceKey = NamespacedKey(plugin, "packed_ice")
|
||||
private var iceKey = NamespacedKey(plugin, "ice")
|
||||
|
||||
override fun getIdentifier(): String = "IceDecompression"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
// Blue Ice -> Packed Ice
|
||||
val packedIceRecipe = ShapelessRecipe(packedIceKey, ItemStack(Material.PACKED_ICE, 9))
|
||||
packedIceRecipe.addIngredient(Material.BLUE_ICE)
|
||||
plugin.server.addRecipe(packedIceRecipe)
|
||||
|
||||
// Packed Ice -> Ice
|
||||
val iceRecipe = ShapelessRecipe(iceKey, ItemStack(Material.ICE, 9))
|
||||
iceRecipe.addIngredient(Material.PACKED_ICE)
|
||||
plugin.server.addRecipe(iceRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(packedIceKey)
|
||||
plugin.server.removeRecipe(iceKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.Tag
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.RecipeChoice
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class LogsToChests(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "chest")
|
||||
|
||||
override fun getIdentifier(): String = "LogsToChests"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val chestRecipe = ShapedRecipe(recipeKey, ItemStack(Material.CHEST, 4))
|
||||
chestRecipe.shape("WWW", "W W", "WWW")
|
||||
chestRecipe.setIngredient('W', RecipeChoice.MaterialChoice(Tag.LOGS))
|
||||
|
||||
plugin.server.addRecipe(chestRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.RecipeChoice
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class RedyeTerracotta(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private val blackRecipeKey = NamespacedKey(plugin, "black_terracotta")
|
||||
private val blueRecipeKey = NamespacedKey(plugin, "blue_terracotta")
|
||||
private val brownRecipeKey = NamespacedKey(plugin, "brown_terracotta")
|
||||
private val cyanRecipeKey = NamespacedKey(plugin, "cyan_terracotta")
|
||||
private val blueRecipeKey = NamespacedKey(plugin, "blue_terracotta")
|
||||
private val blueRecipeKey = NamespacedKey(plugin, "blue_terracotta")
|
||||
|
||||
private val allTerracotta = RecipeChoice.MaterialChoice(Material.TERRACOTTA, Material.BLACK_TERRACOTTA,
|
||||
Material.BLUE_TERRACOTTA, Material.BROWN_TERRACOTTA, Material.CYAN_TERRACOTTA, Material.GRAY_TERRACOTTA,
|
||||
Material.GREEN_TERRACOTTA, Material.LIGHT_BLUE_TERRACOTTA,
|
||||
Material.LIGHT_GRAY_TERRACOTTA, Material.LIME_TERRACOTTA, Material.MAGENTA_TERRACOTTA,
|
||||
Material.ORANGE_TERRACOTTA, Material.PINK_TERRACOTTA, Material.PURPLE_TERRACOTTA, Material.RED_TERRACOTTA,
|
||||
Material.WHITE_TERRACOTTA, Material.YELLOW_TERRACOTTA)
|
||||
|
||||
override fun getIdentifier(): String = "RedyeTerracotta"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
addRecipe(blackRecipeKey, Material.BLACK_TERRACOTTA, Material.BLACK_DYE)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(blackRecipeKey)
|
||||
}
|
||||
|
||||
private fun addRecipe(key: NamespacedKey, output: Material, dye: Material) {
|
||||
val recipe = ShapedRecipe(key, ItemStack(output))
|
||||
recipe.shape("TTT", "TDT", "TTT")
|
||||
recipe.setIngredient('T', allTerracotta)
|
||||
recipe.setIngredient('D', dye)
|
||||
|
||||
plugin.server.addRecipe(recipe)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.craftingtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.Tag
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.RecipeChoice
|
||||
import org.bukkit.inventory.ShapelessRecipe
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class WoolToString(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak {
|
||||
private var recipeKey = NamespacedKey(plugin, "string")
|
||||
|
||||
override fun getIdentifier(): String = "WoolToString"
|
||||
override fun getCategories(): List<String> = listOf("crafting", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
val stringRecipe = ShapelessRecipe(recipeKey, ItemStack(Material.STRING, 4))
|
||||
stringRecipe.addIngredient(RecipeChoice.MaterialChoice(Tag.WOOL))
|
||||
|
||||
plugin.server.addRecipe(stringRecipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
plugin.server.removeRecipe(recipeKey)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.croptweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.block.data.Ageable
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.BlockBreakEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class HoeHarvestArea(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "HoesHarvestArea"
|
||||
override fun getCategories(): List<String> = listOf("crops", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onHoeBreaksBlock(event: BlockBreakEvent) {
|
||||
val player = event.player
|
||||
val block = event.block
|
||||
val world = block.world
|
||||
val itemInHand = player.inventory.itemInMainHand
|
||||
val range = when(itemInHand.type) {
|
||||
Material.WOODEN_HOE -> 1
|
||||
Material.STONE_HOE -> 1
|
||||
Material.IRON_HOE -> 1
|
||||
Material.GOLDEN_HOE -> 1
|
||||
Material.DIAMOND_HOE -> 2
|
||||
Material.NETHERITE_HOE -> 2
|
||||
else -> return
|
||||
}
|
||||
|
||||
if (!isCrop(block.type)) return
|
||||
|
||||
val startLocation = block.location
|
||||
for (x in -range..range) {
|
||||
for (z in -range..range) {
|
||||
val b = world.getBlockAt(startLocation.clone().add(x.toDouble(), 0.0, z.toDouble()))
|
||||
if (isCrop(b.type)) {
|
||||
val ageable = b.blockData as Ageable
|
||||
if (ageable.age == ageable.maximumAge) {
|
||||
b.breakNaturally()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun isCrop(material: Material): Boolean {
|
||||
return material == Material.WHEAT || material == Material.BEETROOTS || material == Material.CARROTS || material == Material.POTATOES
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.croptweaks
|
||||
|
||||
import nl.kallestruik.dlib.DUtil
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Particle
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.Action
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.inventory.EquipmentSlot
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class LilypadBonemealing(
|
||||
private val plugin: JavaPlugin,
|
||||
private val util: DUtil
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "LilypadBonemealing"
|
||||
override fun getCategories(): List<String> = listOf("crops", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onRightClickBlock(event: PlayerInteractEvent) {
|
||||
val player = event.player
|
||||
if (event.hand != EquipmentSlot.HAND) return
|
||||
if (event.action != Action.RIGHT_CLICK_BLOCK) return
|
||||
if (event.clickedBlock == null) return
|
||||
if (event.clickedBlock!!.type != Material.LILY_PAD) return
|
||||
|
||||
val itemInHand = player.inventory.itemInMainHand
|
||||
if (itemInHand.type != Material.BONE_MEAL) return
|
||||
|
||||
val world = event.clickedBlock!!.world
|
||||
val origin = event.clickedBlock!!.location
|
||||
for (i in 0..5) {
|
||||
val newPos: Location = origin.clone().add(util.getRandomLocationOffset(0, 3, false))
|
||||
val newBlock = world.getBlockAt(newPos)
|
||||
if (newBlock.type != Material.AIR) continue
|
||||
if (newBlock.getRelative(0, -1, 0).type != Material.WATER) continue
|
||||
newBlock.type = Material.LILY_PAD
|
||||
world.spawnParticle(Particle.VILLAGER_HAPPY, newPos, 5, 0.5, 0.5, 0.5)
|
||||
}
|
||||
itemInHand.amount = itemInHand.amount - 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.croptweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class MobsCantTrampleCrops(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "MobsCantTrampleCrops"
|
||||
override fun getCategories(): List<String> = listOf("crops", "mobs", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onBlockBreak(event: EntityChangeBlockEvent) {
|
||||
if (event.block.type != Material.FARMLAND) return
|
||||
if (event.entity is Player) return
|
||||
event.isCancelled = true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.croptweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.managers.TrampleManager
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class PlayersCantTrampleCrops(
|
||||
private val plugin: JavaPlugin,
|
||||
private val trampleManager: TrampleManager
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "PlayersCantTrampleCrops"
|
||||
override fun getCategories(): List<String> = listOf("crops", "survival", "players")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onBlockBreak(event: EntityChangeBlockEvent) {
|
||||
if (event.block.type != Material.FARMLAND) return
|
||||
if (event.entity !is Player) return
|
||||
if (trampleManager.trampleEnabled.contains(event.entity.uniqueId)) return
|
||||
event.isCancelled = true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.croptweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Particle
|
||||
import org.bukkit.World
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.Item
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import org.bukkit.scheduler.BukkitTask
|
||||
|
||||
class SeedDropPlanting(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
private lateinit var task: BukkitTask
|
||||
|
||||
override fun getIdentifier(): String = "SeedDropPlanting"
|
||||
override fun getCategories(): List<String> = listOf("crops", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
task = Bukkit.getScheduler().runTaskTimer(plugin, SeedPlantTask(plugin), (20 * 10).toLong(), (20 * 10).toLong())
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
task.cancel()
|
||||
}
|
||||
|
||||
private class SeedPlantTask(
|
||||
private val plugin: JavaPlugin
|
||||
): Runnable {
|
||||
override fun run() {
|
||||
for (world in plugin.server.worlds) {
|
||||
for (entity in world.entities) {
|
||||
if (entity is Item) {
|
||||
val b = world.getBlockAt(entity.location)
|
||||
val above = world.getBlockAt(entity.location.add(0.0, 1.0, 0.0))
|
||||
if (b.type == Material.FARMLAND && above.type == Material.AIR) {
|
||||
when (entity.itemStack.type) {
|
||||
Material.WHEAT_SEEDS -> plantSeed(entity, world, above, Material.WHEAT)
|
||||
Material.BEETROOT_SEEDS -> plantSeed(entity, world, above, Material.BEETROOTS)
|
||||
Material.MELON_SEEDS -> plantSeed(entity, world, above, Material.MELON_STEM)
|
||||
Material.PUMPKIN_SEEDS -> plantSeed(entity, world, above, Material.PUMPKIN_STEM)
|
||||
Material.POTATO -> plantSeed(entity, world, above, Material.POTATOES)
|
||||
Material.CARROT -> plantSeed(entity, world, above, Material.CARROTS)
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun plantSeed(entity: Item, world: World, block: Block, material: Material) {
|
||||
block.type = material
|
||||
world.spawnParticle(Particle.VILLAGER_HAPPY, entity.location, 10)
|
||||
if (entity.itemStack.amount == 1) {
|
||||
entity.remove()
|
||||
} else {
|
||||
entity.itemStack.amount = entity.itemStack.amount - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.croptweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Particle
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.Action
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.inventory.EquipmentSlot
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class SugarcaneBonemealing(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "SugarcaneBonemealing"
|
||||
override fun getCategories(): List<String> = listOf("crops", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onRightClickBlock(event: PlayerInteractEvent) {
|
||||
val player = event.player
|
||||
|
||||
if (event.hand != EquipmentSlot.HAND) return
|
||||
if (event.action != Action.RIGHT_CLICK_BLOCK) return
|
||||
if (event.clickedBlock == null) return
|
||||
if (event.clickedBlock!!.type != Material.SUGAR_CANE) return
|
||||
val itemInHand = player.inventory.itemInMainHand
|
||||
if (itemInHand.type != Material.BONE_MEAL) return
|
||||
|
||||
val world = event.clickedBlock!!.world
|
||||
val origin = event.clickedBlock!!.location
|
||||
|
||||
for (i in 0..3) {
|
||||
val newPos = origin.clone().add(0.0, i.toDouble(), 0.0)
|
||||
val newBlock = world.getBlockAt(newPos)
|
||||
if (newBlock.type != Material.AIR) continue
|
||||
if (newBlock.getRelative(0, -1, 0).type != Material.SUGAR_CANE) continue
|
||||
newBlock.type = Material.SUGAR_CANE
|
||||
world.spawnParticle(Particle.VILLAGER_HAPPY, newPos, 5, 0.5, 0.5, 0.5)
|
||||
itemInHand.amount = itemInHand.amount - 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.dispsensertweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Particle
|
||||
import org.bukkit.Tag
|
||||
import org.bukkit.block.BlockFace
|
||||
import org.bukkit.block.data.type.Dispenser
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.BlockDispenseEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class DispensersCanPlantSaplings(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
private val treePlantable = setOf(Material.DIRT, Material.COARSE_DIRT, Material.GRASS_BLOCK, Material.PODZOL, Material.MYCELIUM)
|
||||
|
||||
override fun getIdentifier(): String = "DispensersCanPlantSaplings"
|
||||
override fun getCategories(): List<String> = listOf("dispenser", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onDispenserDispense(event: BlockDispenseEvent) {
|
||||
if (event.block.type != Material.DISPENSER) return
|
||||
if (Tag.SAPLINGS.isTagged(event.item.type)) {
|
||||
val dispenser = event.block.blockData as Dispenser
|
||||
val facing = dispenser.facing
|
||||
val targetBlock = if (facing == BlockFace.UP) {
|
||||
event.block.world.getBlockAt(event.block.location.add(0.0, 2.0, 0.0))
|
||||
} else {
|
||||
event.block.world.getBlockAt(
|
||||
event.block.location.add(
|
||||
facing.modX.toDouble(),
|
||||
facing.modY.toDouble(),
|
||||
facing.modZ.toDouble()
|
||||
)
|
||||
)
|
||||
}
|
||||
if (targetBlock.type == Material.AIR
|
||||
&& treePlantable.contains(
|
||||
event.block.world.getBlockAt(
|
||||
targetBlock.location.add(
|
||||
0.0,
|
||||
-1.0,
|
||||
0.0
|
||||
)
|
||||
).type
|
||||
)
|
||||
) {
|
||||
targetBlock.type = event.item.type
|
||||
event.isCancelled = true
|
||||
val dispenserInventory = (event.block.state as org.bukkit.block.Dispenser).inventory
|
||||
var slot = 0
|
||||
for (`is` in dispenserInventory.contents) {
|
||||
if (`is` != null && `is`.type == event.item.type) break
|
||||
slot++
|
||||
}
|
||||
val newItemStack = dispenserInventory.getItem(slot)
|
||||
newItemStack!!.amount = newItemStack.amount - 1
|
||||
dispenserInventory.setItem(slot, newItemStack)
|
||||
event.block.world.spawnParticle(Particle.VILLAGER_HAPPY, targetBlock.location, 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.entity.ArmorStand
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent
|
||||
import org.bukkit.inventory.EquipmentSlot
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class ArmorStandArmorSwapping(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "ArmorStandArmorSwapping"
|
||||
override fun getCategories(): List<String> = listOf("miscellaneous", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onClickEntity(event: PlayerInteractAtEntityEvent) {
|
||||
if (event.player.isSneaking) {
|
||||
if (event.rightClicked is ArmorStand) {
|
||||
val armorStand = event.rightClicked as ArmorStand
|
||||
val standEquipment = armorStand.equipment
|
||||
val player = event.player
|
||||
val playerEquipment = player.equipment
|
||||
if (standEquipment == null || playerEquipment == null) return
|
||||
|
||||
val playerHelmet = playerEquipment.helmet
|
||||
val playerChestplate = playerEquipment.chestplate
|
||||
val playerLeggings = playerEquipment.leggings
|
||||
val playerBoots = playerEquipment.boots
|
||||
player.inventory.helmet = standEquipment.helmet
|
||||
player.inventory.chestplate = standEquipment.chestplate
|
||||
player.inventory.leggings = standEquipment.leggings
|
||||
player.inventory.boots = standEquipment.boots
|
||||
armorStand.setItem(EquipmentSlot.HEAD, playerHelmet)
|
||||
armorStand.setItem(EquipmentSlot.CHEST, playerChestplate)
|
||||
armorStand.setItem(EquipmentSlot.LEGS, playerLeggings)
|
||||
armorStand.setItem(EquipmentSlot.FEET, playerBoots)
|
||||
event.isCancelled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks
|
||||
|
||||
import com.comphenix.protocol.PacketType
|
||||
import com.comphenix.protocol.ProtocolLibrary
|
||||
import com.comphenix.protocol.events.PacketAdapter
|
||||
import com.comphenix.protocol.events.PacketEvent
|
||||
import com.comphenix.protocol.wrappers.BlockPosition
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Hand
|
||||
import nl.kallestruik.dlib.MathHelper
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.block.BlockFace
|
||||
import org.bukkit.block.data.Bisected
|
||||
import org.bukkit.block.data.BlockData
|
||||
import org.bukkit.block.data.Directional
|
||||
import org.bukkit.block.data.type.Comparator
|
||||
import org.bukkit.block.data.type.Repeater
|
||||
import org.bukkit.block.data.type.Stairs
|
||||
import org.bukkit.block.data.type.TrapDoor
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class CarpetBlockPlacingProtocol(
|
||||
private val plugin: JavaPlugin,
|
||||
private val mathHelper: MathHelper
|
||||
): ITweak, Listener {
|
||||
private val protocolManager = ProtocolLibrary.getProtocolManager()
|
||||
private var packetListener: PacketListener? = null
|
||||
|
||||
override fun getIdentifier(): String = "CarpetBlockPlacingProtocol"
|
||||
override fun getCategories(): List<String> = listOf("player", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
this.packetListener = PacketListener(plugin, PacketType.Play.Client.USE_ITEM, mathHelper)
|
||||
protocolManager.addPacketListener(this.packetListener)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
protocolManager.removePacketListener(this.packetListener)
|
||||
}
|
||||
|
||||
internal class PacketListener(
|
||||
plugin: JavaPlugin?,
|
||||
packetType: PacketType?,
|
||||
private val mathHelper: MathHelper
|
||||
): PacketAdapter(plugin, packetType) {
|
||||
override fun onPacketReceiving(event: PacketEvent) {
|
||||
// Make sure the packet is the one we expect.
|
||||
if (event.packetType !== PacketType.Play.Client.USE_ITEM) return
|
||||
|
||||
// Get the hand that the player used.
|
||||
val hand = event.packet.hands.values[0] ?: return
|
||||
|
||||
// Get the MovingObjectPositionBlock and make sure it is not null.
|
||||
val mopd = event.packet.movingBlockPositions.values[0] ?: return
|
||||
val player = event.player
|
||||
|
||||
// Get the item stack that was clicked with.
|
||||
val itemStack =
|
||||
if (hand == Hand.MAIN_HAND) player.inventory.itemInMainHand else player.inventory.itemInOffHand
|
||||
|
||||
// Get the hitPos and BlockPos from the mopd.
|
||||
val hitPos = mopd.posVector
|
||||
val pos = mopd.blockPosition
|
||||
|
||||
// Calculate hitX.
|
||||
val hitX = hitPos.x - pos.x
|
||||
|
||||
// Nothing special so ignore this packet.
|
||||
if (hitX < 2) return
|
||||
val code = (hitX - 2).toInt() / 2
|
||||
val blockData: BlockData = getBlockDataFromCode(code, itemStack, player, pos) ?: return
|
||||
Bukkit.getScheduler().runTask(plugin, Runnable {
|
||||
val blockToChange = player.world.getBlockAt(pos.x, pos.y, pos.z)
|
||||
blockToChange.blockData = blockData
|
||||
|
||||
// Cancel any further processing
|
||||
event.isCancelled = true
|
||||
|
||||
// Take one item from the players inventory.
|
||||
itemStack.amount = itemStack.amount - 1
|
||||
})
|
||||
}
|
||||
|
||||
private fun getBlockDataFromCode(code: Int, itemStack: ItemStack, player: Player, pos: BlockPosition): BlockData? {
|
||||
val blockData = Bukkit.createBlockData(itemStack.type)
|
||||
if (blockData is Repeater) {
|
||||
val repeater = blockData
|
||||
val delay: Int = mathHelper.clamp(code shr 4, 1, 4)
|
||||
repeater.facing = horizontalBlockFaceFromCode(code and 0xF, player)!!
|
||||
repeater.delay = delay
|
||||
return repeater
|
||||
} else if (blockData is TrapDoor) {
|
||||
val trapDoor = blockData
|
||||
val block = player.world.getBlockAt(pos.x, pos.y, pos.z)
|
||||
trapDoor.facing = blockFaceFromCode(code and 0xF)
|
||||
trapDoor.half = if (code > 0xF) Bisected.Half.TOP else Bisected.Half.BOTTOM
|
||||
trapDoor.isOpen = block.isBlockPowered || block.isBlockIndirectlyPowered
|
||||
return trapDoor
|
||||
} else if (blockData is Comparator) {
|
||||
val comparator = blockData
|
||||
val mode = if (code > 0xF) Comparator.Mode.SUBTRACT else Comparator.Mode.COMPARE
|
||||
comparator.facing = horizontalBlockFaceFromCode(code and 0xF, player)!!
|
||||
comparator.mode = mode
|
||||
return comparator
|
||||
} else if (blockData is Stairs) {
|
||||
val stairs = blockData
|
||||
stairs.facing = blockFaceFromCode(code and 0xF)
|
||||
stairs.half = if (code > 0xF) Bisected.Half.TOP else Bisected.Half.BOTTOM
|
||||
return stairs
|
||||
} else if (blockData is Directional) {
|
||||
val directional = blockData
|
||||
val possibilities = directional.faces
|
||||
|
||||
// Check what type of directional we are dealing with.
|
||||
if (possibilities.contains(BlockFace.UP)) {
|
||||
directional.facing = blockFaceFromCode(code)
|
||||
} else {
|
||||
directional.facing = horizontalBlockFaceFromCode(code, player)!!
|
||||
}
|
||||
return directional
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun blockFaceFromCode(code: Int): BlockFace {
|
||||
return when (code) {
|
||||
0 -> BlockFace.DOWN
|
||||
1 -> BlockFace.UP
|
||||
2 -> BlockFace.NORTH
|
||||
3 -> BlockFace.SOUTH
|
||||
4 -> BlockFace.WEST
|
||||
5 -> BlockFace.EAST
|
||||
else -> BlockFace.SELF
|
||||
}
|
||||
}
|
||||
|
||||
private fun blockFaceFromRotation(rotation: Float): BlockFace? {
|
||||
return if (rotation < 45 && rotation >= -45) BlockFace.SOUTH else if (rotation < 135 && rotation >= 45) BlockFace.WEST else if (rotation >= 135 && rotation < -135) BlockFace.NORTH else BlockFace.EAST
|
||||
}
|
||||
|
||||
private fun horizontalBlockFaceFromCode(code: Int, player: Player): BlockFace? {
|
||||
val face = blockFaceFromCode(code)
|
||||
return if (face == BlockFace.UP || face == BlockFace.DOWN) {
|
||||
blockFaceFromRotation(player.location.yaw)
|
||||
} else face
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.managers.FakePlayerManager
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
|
||||
class FakePlayers(
|
||||
private val fakePlayerManager: FakePlayerManager
|
||||
): ITweak {
|
||||
override fun getIdentifier(): String = "FakePlayers"
|
||||
override fun getCategories(): List<String> = listOf("players")
|
||||
|
||||
override fun onDisable() {
|
||||
fakePlayerManager.killAllFakePlayers()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.managers.PocketDimensionManager
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.BlockBreakEvent
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent
|
||||
import org.bukkit.event.entity.EntityDamageEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class SpaceTimePockets(
|
||||
private val plugin: JavaPlugin,
|
||||
private val pocketDimensionManager: PocketDimensionManager
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "SpaceTimePockets"
|
||||
override fun getCategories(): List<String> = listOf("miscellaneous", "survival")
|
||||
|
||||
override fun onRegister() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onUnRegister() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
fun onBlockBreak(event: BlockBreakEvent) {
|
||||
if (event.player.world != pocketDimensionManager.pocketDimension) {
|
||||
return
|
||||
}
|
||||
if (event.block.location.chunk == event.player.location.chunk && event.block.y != 0 && event.block.y != 255) return
|
||||
event.isCancelled = true
|
||||
event.player.sendMessage("It seems like a bad idea to break the only thing keeping you from getting lost into the endlessness around you.")
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onMobSpawn(event: CreatureSpawnEvent) {
|
||||
if (pocketDimensionManager.pocketDimension != event.location.world) return
|
||||
event.isCancelled = true
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onPlayerDamage(event: EntityDamageEvent) {
|
||||
if (event.entity !is Player) return
|
||||
if (pocketDimensionManager.pocketDimension != event.entity.world) return
|
||||
event.isCancelled = true
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onPlayerFall(event: PlayerMoveEvent) {
|
||||
if (pocketDimensionManager.pocketDimension != event.from.world
|
||||
|| pocketDimensionManager.pocketDimension != event.to.world
|
||||
) return
|
||||
if (event.from.chunk != event.to.chunk) {
|
||||
event.player.sendMessage("Something pulls you back from the darkness.")
|
||||
event.isCancelled = true
|
||||
}
|
||||
if (event.to.blockY < 0 || event.to.blockY > 256) {
|
||||
event.player.sendMessage("Something pulls you back from the darkness.")
|
||||
val safeLocation = event.player.location
|
||||
safeLocation.y = 128.0
|
||||
event.player.teleport(safeLocation)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.mobtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.entity.Creeper
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.entity.EntityExplodeEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class NoCreeperGrief(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "NoCreeperGrief"
|
||||
override fun getCategories(): List<String> = listOf("mobs", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onCreeperExplode(event: EntityExplodeEvent) {
|
||||
if (event.entityType != EntityType.CREEPER) return
|
||||
val creeper = event.entity as Creeper
|
||||
creeper.world.createExplosion(creeper.location, event.yield, false, false)
|
||||
event.isCancelled = true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.mobtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.entity.EntityBreakDoorEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class NoDoorBreaking(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "NoDoorBreaking"
|
||||
override fun getCategories(): List<String> = listOf("mobs", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onDoorBreak(event: EntityBreakDoorEvent) {
|
||||
event.isCancelled = true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.mobtweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class NoEndermanGrief(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "NoEndermanGrief"
|
||||
override fun getCategories(): List<String> = listOf("mobs", "survival")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onEndermanPickupBlock(event: EntityChangeBlockEvent) {
|
||||
if (event.entityType != EntityType.ENDERMAN) return
|
||||
event.isCancelled = true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.mobtweaks
|
||||
|
||||
import net.minecraft.server.v1_16_R3.Activity
|
||||
import net.minecraft.server.v1_16_R3.EntityVillager
|
||||
import net.minecraft.server.v1_16_R3.GlobalPos
|
||||
import net.minecraft.server.v1_16_R3.MemoryModuleType
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftVillager
|
||||
import org.bukkit.entity.Villager
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class VillagerInfo(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "VillagerInfo"
|
||||
override fun getCategories(): List<String> = listOf("mobs")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onInteractEvent(event: PlayerInteractEntityEvent) {
|
||||
if (!event.player.isSneaking) return
|
||||
val clicked = event.rightClicked as? Villager ?: return
|
||||
val eVillager: EntityVillager = (clicked as CraftVillager).handle
|
||||
val homePos: AtomicReference<GlobalPos?> = AtomicReference(null)
|
||||
eVillager.behaviorController.getMemory(MemoryModuleType.HOME)
|
||||
.ifPresent { newValue -> homePos.set(newValue) }
|
||||
val workPos: AtomicReference<GlobalPos?> = AtomicReference(null)
|
||||
eVillager.behaviorController.getMemory(MemoryModuleType.JOB_SITE).ifPresent { newValue ->
|
||||
workPos.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val meetingPos: AtomicReference<GlobalPos?> = AtomicReference(null)
|
||||
eVillager.behaviorController.getMemory(MemoryModuleType.MEETING_POINT).ifPresent { newValue ->
|
||||
meetingPos.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val lastWork: AtomicReference<Long?> = AtomicReference(null)
|
||||
eVillager.behaviorController.getMemory(MemoryModuleType.LAST_WORKED_AT_POI).ifPresent { newValue ->
|
||||
lastWork.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val lastSleep: AtomicReference<Long?> = AtomicReference(null)
|
||||
eVillager.behaviorController.getMemory(MemoryModuleType.LAST_SLEPT).ifPresent { newValue ->
|
||||
lastSleep.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val seenIGRecently: AtomicReference<Boolean?> = AtomicReference(null)
|
||||
eVillager.behaviorController.getMemory(MemoryModuleType.GOLEM_DETECTED_RECENTLY).ifPresent { newValue ->
|
||||
seenIGRecently.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
|
||||
val isPanicking: Boolean = eVillager.behaviorController.c(Activity.PANIC)
|
||||
val player = event.player
|
||||
|
||||
player.sendMessage("=====Villager Info=====")
|
||||
player.sendMessage("Type: " + clicked.villagerType)
|
||||
player.sendMessage("Profession: " + clicked.profession)
|
||||
player.sendMessage("Level: " + clicked.villagerLevel + "(" + clicked.villagerExperience + " xp)")
|
||||
player.sendMessage("Panic: $isPanicking")
|
||||
|
||||
if (homePos.get() != null) player.sendMessage(
|
||||
java.lang.String.format(
|
||||
"Home: %s, %s, %s",
|
||||
homePos.get()?.blockPosition?.x,
|
||||
homePos.get()?.blockPosition?.y,
|
||||
homePos.get()?.blockPosition?.z
|
||||
)
|
||||
)
|
||||
|
||||
if (workPos.get() != null) player.sendMessage(
|
||||
java.lang.String.format(
|
||||
"Work: %s, %s, %s",
|
||||
workPos.get()?.blockPosition?.x,
|
||||
workPos.get()?.blockPosition?.y,
|
||||
workPos.get()?.blockPosition?.z
|
||||
)
|
||||
)
|
||||
|
||||
if (homePos.get() != null) player.sendMessage(
|
||||
java.lang.String.format(
|
||||
"Meeting point: %s, %s, %s",
|
||||
meetingPos.get()?.blockPosition?.x,
|
||||
meetingPos.get()?.blockPosition?.y,
|
||||
meetingPos.get()?.blockPosition?.z
|
||||
)
|
||||
)
|
||||
|
||||
if (lastSleep.get() != null)
|
||||
player.sendMessage("Last slept: ${lastSleep.get()}")
|
||||
|
||||
if (seenIGRecently.get() != null)
|
||||
player.sendMessage("Seen iron golem Recently: ${seenIGRecently.get()}")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
name: DTweaks
|
||||
version: ${version}
|
||||
main: nl.kallestruik.dtweaks.DTweaks
|
||||
api-version: 1.16
|
||||
depend:
|
||||
- "ProtocolLib"
|
||||
- "DLib"
|
||||
commands:
|
||||
toggletrample:
|
||||
description: "Toggles whether you can trample crops."
|
||||
player:
|
||||
description: "Interact with fake players."
|
||||
permission: op
|
||||
mobcaps:
|
||||
description: "Display mobcap information from your current dimension."
|
||||
pocketdim:
|
||||
description: "Interact with pocket dimensions. Testing command."
|
|
@ -0,0 +1,24 @@
|
|||
CraftableNametag: true
|
||||
CraftableSaddle: true
|
||||
AlternativeDispenserRecipe: true
|
||||
DispensersCanPlantSaplings: true
|
||||
CraftableShulkerShell: true
|
||||
IceDecompression: true
|
||||
LogsToChests: true
|
||||
CraftableSponge: true
|
||||
PlayersCantTrampleCrops: true
|
||||
WoolToString: true
|
||||
LilypadBonemealing: true
|
||||
SeedDropPlanting: true
|
||||
MobsCantTrampleCrops: true
|
||||
CraftableDragonsBreath: true
|
||||
ArmorSwapping: true
|
||||
HoesHarvestArea: true
|
||||
FakePlayers: true
|
||||
CarpetBlockPlacingProtocol: true
|
||||
NoDoorBreaking: true
|
||||
NoCreeperGrief: true
|
||||
NoEndermanGrief: true
|
||||
SugarcaneBonemealing: true
|
||||
SpaceTimePockets: true
|
||||
VillagerInfo: true
|
Loading…
Reference in New Issue