Update to 1.19
parent
10145032e2
commit
247159970c
|
@ -1,10 +1,10 @@
|
|||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.5.31"
|
||||
kotlin("jvm") version "1.7.0-RC"
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("xyz.jpenilla.run-paper") version "1.0.6" // Adds runServer and runMojangMappedServer tasks for testing
|
||||
id("io.papermc.paperweight.userdev") version "1.3.4"
|
||||
id("io.papermc.paperweight.userdev") version "1.3.7"
|
||||
}
|
||||
|
||||
group = "nl.kallestruik"
|
||||
|
@ -20,12 +20,13 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
paperDevBundle("1.19-R0.1-SNAPSHOT")
|
||||
|
||||
implementation("co.aikar:acf-paper:0.5.0-SNAPSHOT")
|
||||
paperDevBundle("1.18.1-R0.1-SNAPSHOT")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.6.0")
|
||||
compileOnly(kotlin("stdlib-jdk8"))
|
||||
|
||||
compileOnly("nl.kallestruik:DLib:1.3.6")
|
||||
compileOnly("nl.kallestruik:DLib:1.4.4")
|
||||
|
||||
testImplementation(kotlin("test-junit5"))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
|
||||
|
|
|
@ -1,89 +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
|
||||
@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
|
||||
|
|
|
@ -22,16 +22,4 @@ class CommandPlayer(
|
|||
fun onKill(sender: Player, @Single playerName: String) {
|
||||
fakePlayerManager.killFakePlayer(playerName)
|
||||
}
|
||||
|
||||
@Subcommand("attack")
|
||||
@CommandCompletion("@players")
|
||||
fun onAttack(sender: Player, @Single playerName: String) {
|
||||
fakePlayerManager.attack(playerName)
|
||||
}
|
||||
|
||||
@Subcommand("use")
|
||||
@CommandCompletion("@players")
|
||||
fun onUse(sender: Player, @Single playerName: String) {
|
||||
fakePlayerManager.use(playerName)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import com.mojang.authlib.GameProfile
|
||||
import net.minecraft.network.chat.TextComponent
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.protocol.PacketFlow
|
||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket
|
||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket
|
||||
|
@ -10,18 +10,18 @@ import net.minecraft.server.TickTask
|
|||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.damagesource.DamageSource
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.food.FoodData
|
||||
import net.minecraft.world.level.block.entity.SkullBlockEntity
|
||||
import nl.kallestruik.dtweaks.fakeplayer.FakePlayerList.placeFakePlayer
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class FakePlayer(
|
||||
server: MinecraftServer,
|
||||
val serverLevel: ServerLevel,
|
||||
private val serverLevel: ServerLevel,
|
||||
gameProfile: GameProfile
|
||||
): ServerPlayer(server, serverLevel, gameProfile) {
|
||||
): ServerPlayer(server, serverLevel, gameProfile, null) {
|
||||
val locale = "en_US"
|
||||
|
||||
companion object {
|
||||
|
@ -43,7 +43,7 @@ class FakePlayer(
|
|||
|
||||
// Create a fake connection for our fake player.
|
||||
val connection = FakeConnection(PacketFlow.SERVERBOUND)
|
||||
FakePlayerList.placeNewPlayer(minecraftServer.playerList, minecraftServer, connection, instance)
|
||||
minecraftServer.playerList.placeFakePlayer(connection, instance)
|
||||
|
||||
instance.respawn()
|
||||
instance.teleportTo(serverLevel, location.x, location.y, location.z, location.yaw, location.pitch)
|
||||
|
@ -119,7 +119,9 @@ class FakePlayer(
|
|||
}
|
||||
|
||||
override fun kill() {
|
||||
server.tell(TickTask(server.tickCount) {connection.onDisconnect(TextComponent("Killed"))})
|
||||
server.tell(TickTask(server.tickCount) {
|
||||
connection.onDisconnect(Component.literal("Killed"))
|
||||
})
|
||||
}
|
||||
|
||||
override fun die(source: DamageSource) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package nl.kallestruik.dtweaks.fakeplayer
|
|||
import io.netty.util.concurrent.Future
|
||||
import io.netty.util.concurrent.GenericFutureListener
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.network.protocol.Packet
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl
|
||||
|
@ -18,10 +17,7 @@ class FakePlayerConnection(
|
|||
override fun send(packet: Packet<*>, listener: GenericFutureListener<out Future<in Void>>?) {}
|
||||
|
||||
override fun disconnect(message: Component) {
|
||||
if (message is TranslatableComponent && (message.key.equals("multiplayer.disconnect.idling") || message.equals("multiplayer.disconnect.duplicate_login")))
|
||||
{
|
||||
player.kill()
|
||||
}
|
||||
player.kill()
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
|
|
|
@ -1,23 +1,29 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import com.destroystokyo.paper.PaperConfig
|
||||
import com.destroystokyo.paper.event.player.PlayerInitialSpawnEvent
|
||||
import com.mojang.authlib.GameProfile
|
||||
import com.mojang.datafixers.util.Either
|
||||
import com.mojang.serialization.Dynamic
|
||||
import io.netty.buffer.Unpooled
|
||||
import io.papermc.paper.configuration.GlobalConfiguration
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.NbtOps
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.network.Connection
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.protocol.game.*
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.*
|
||||
import net.minecraft.server.level.ChunkHolder.ChunkLoadingFailure
|
||||
import net.minecraft.server.level.DistanceManager
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.level.TicketType
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl
|
||||
import net.minecraft.server.players.GameProfileCache
|
||||
import net.minecraft.server.players.PlayerList
|
||||
import net.minecraft.tags.TagNetworkSerialization
|
||||
import net.minecraft.world.level.ChunkPos
|
||||
import net.minecraft.world.level.GameRules
|
||||
import net.minecraft.world.level.Level
|
||||
|
@ -25,18 +31,185 @@ import net.minecraft.world.level.biome.BiomeManager
|
|||
import net.minecraft.world.level.chunk.ChunkAccess
|
||||
import net.minecraft.world.level.dimension.DimensionType
|
||||
import nl.kallestruik.dlib.ReflectionUtil
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import org.apache.logging.log4j.Logger
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld
|
||||
import org.bukkit.entity.Player
|
||||
import org.spigotmc.event.player.PlayerSpawnLocationEvent
|
||||
import java.util.*
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.function.Consumer
|
||||
|
||||
object FakePlayerList {
|
||||
|
||||
fun PlayerList.placeFakePlayer(connection: Connection, player: ServerPlayer) {
|
||||
player.isRealPlayer = true // Paper - Chunk priority
|
||||
player.networkManager = connection // Paper
|
||||
player.loginTime = System.currentTimeMillis() // Paper
|
||||
|
||||
val gameprofile = player.getGameProfile()
|
||||
val usercache = server.profileCache
|
||||
val optional = usercache[gameprofile.id]
|
||||
var s: String? = optional.map { obj: GameProfile -> obj.name }.orElse(gameprofile.name)
|
||||
|
||||
usercache.add(gameprofile)
|
||||
val nbttagcompound = load(player)
|
||||
// CraftBukkit start - Better rename detection
|
||||
// CraftBukkit start - Better rename detection
|
||||
if (nbttagcompound != null && nbttagcompound.contains("bukkit")) {
|
||||
val bukkit = nbttagcompound.getCompound("bukkit")
|
||||
s = if (bukkit.contains("lastKnownName", 8)) bukkit.getString("lastKnownName") else s
|
||||
}
|
||||
val lastKnownName = s // Paper
|
||||
|
||||
// CraftBukkit end
|
||||
|
||||
// Paper start - move logic in Entity to here, to use bukkit supplied world UUID.
|
||||
// CraftBukkit end
|
||||
|
||||
// Paper start - move logic in Entity to here, to use bukkit supplied world UUID.
|
||||
val resourcekey =
|
||||
if (nbttagcompound != null && nbttagcompound.contains("WorldUUIDMost") && nbttagcompound.contains("WorldUUIDLeast")) {
|
||||
val uid = UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast"))
|
||||
val bWorld = Bukkit.getServer().getWorld(uid)
|
||||
if (bWorld != null) {
|
||||
(bWorld as CraftWorld).handle.dimension()
|
||||
} else {
|
||||
Level.OVERWORLD
|
||||
}
|
||||
} else if (nbttagcompound != null) {
|
||||
// Vanilla migration support
|
||||
// Paper end
|
||||
val dataresult = DimensionType.parseLegacy(
|
||||
Dynamic(
|
||||
NbtOps.INSTANCE,
|
||||
nbttagcompound["Dimension"]
|
||||
)
|
||||
) // CraftBukkit - decompile error
|
||||
dataresult.resultOrPartial { msg: String? ->
|
||||
|
||||
}.orElse(Level.OVERWORLD)
|
||||
} else {
|
||||
Level.OVERWORLD
|
||||
}
|
||||
|
||||
val resourcekey1: ResourceKey<Level> = resourcekey
|
||||
val worldserver = server.getLevel(resourcekey1)
|
||||
var worldserver1: ServerLevel
|
||||
|
||||
worldserver1 = if (worldserver == null) {
|
||||
server.overworld()
|
||||
} else {
|
||||
worldserver
|
||||
}
|
||||
|
||||
if (nbttagcompound == null) player.fudgeSpawnLocation(worldserver1) // Paper - only move to spawn on first login, otherwise, stay where you are....
|
||||
|
||||
|
||||
player.setLevel(worldserver1)
|
||||
// Paper start - make s1 final
|
||||
// Paper start - make s1 final
|
||||
val s1: String
|
||||
|
||||
s1 = if (connection.remoteAddress != null) {
|
||||
if (GlobalConfiguration.get().logging.logPlayerIpAddresses) connection.remoteAddress.toString() else "<ip address withheld>" // Paper
|
||||
} else {
|
||||
"local"
|
||||
}
|
||||
// Paper end
|
||||
|
||||
// Spigot start - spawn location event
|
||||
// Paper end
|
||||
|
||||
// Spigot start - spawn location event
|
||||
val spawnPlayer: Player = player.bukkitEntity
|
||||
val ev: PlayerSpawnLocationEvent =
|
||||
PlayerInitialSpawnEvent(spawnPlayer, spawnPlayer.location) // Paper use our duplicate event
|
||||
|
||||
val cserver = ReflectionUtil().getValueFromField(this, "cserver") as CraftServer
|
||||
|
||||
cserver.pluginManager.callEvent(ev)
|
||||
|
||||
val loc = ev.spawnLocation
|
||||
worldserver1 = (loc.world as CraftWorld).handle
|
||||
|
||||
player.spawnIn(worldserver1)
|
||||
player.gameMode.setLevel(player.level as ServerLevel)
|
||||
player.setPosRaw(loc.x, loc.y, loc.z)
|
||||
player.setRot(loc.yaw, loc.pitch)
|
||||
|
||||
val worlddata = worldserver1.getLevelData()
|
||||
|
||||
player.loadGameTypes(nbttagcompound)
|
||||
val playerconnection = ServerGamePacketListenerImpl(server, connection, player)
|
||||
val gamerules = worldserver1.gameRules
|
||||
val flag = gamerules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN)
|
||||
val flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO)
|
||||
|
||||
val registryHolder = ReflectionUtil().getValueFromField(this, "t" /* registryHolder -> t */) as RegistryAccess.Frozen
|
||||
|
||||
playerconnection.send(
|
||||
ClientboundLoginPacket(
|
||||
player.id,
|
||||
worlddata.isHardcore,
|
||||
player.gameMode.gameModeForPlayer,
|
||||
player.gameMode.previousGameModeForPlayer,
|
||||
server.levelKeys(),
|
||||
registryHolder,
|
||||
worldserver1.dimensionTypeId(),
|
||||
worldserver1.dimension(),
|
||||
BiomeManager.obfuscateSeed(worldserver1.seed),
|
||||
maxPlayers,
|
||||
worldserver1.getChunkSource().chunkMap.playerChunkManager.targetSendDistance,
|
||||
worldserver1.getChunkSource().chunkMap.playerChunkManager.targetTickViewDistance,
|
||||
flag1,
|
||||
!flag,
|
||||
worldserver1.isDebug,
|
||||
worldserver1.isFlat,
|
||||
player.lastDeathLocation
|
||||
)
|
||||
)
|
||||
|
||||
player.bukkitEntity.sendSupportedChannels() // CraftBukkit
|
||||
|
||||
playerconnection.send(
|
||||
ClientboundCustomPayloadPacket(
|
||||
ClientboundCustomPayloadPacket.BRAND, FriendlyByteBuf(Unpooled.buffer()).writeUtf(
|
||||
server.serverModName
|
||||
)
|
||||
)
|
||||
)
|
||||
playerconnection.send(ClientboundChangeDifficultyPacket(worlddata.difficulty, worlddata.isDifficultyLocked))
|
||||
playerconnection.send(ClientboundPlayerAbilitiesPacket(player.abilities))
|
||||
playerconnection.send(ClientboundSetCarriedItemPacket(player.inventory.selected))
|
||||
playerconnection.send(ClientboundUpdateRecipesPacket(server.recipeManager.getRecipes()))
|
||||
playerconnection.send(ClientboundUpdateTagsPacket(TagNetworkSerialization.serializeTagsToNetwork(registryHolder)))
|
||||
this.sendPlayerPermissionLevel(player)
|
||||
player.stats.markAllDirty()
|
||||
player.recipeBook.sendInitialRecipeBook(player)
|
||||
updateEntireScoreboard(worldserver1.scoreboard, player)
|
||||
server.invalidateStatus()
|
||||
// Paper start - async load spawn in chunk
|
||||
// Paper start - async load spawn in chunk
|
||||
val finalWorldserver = worldserver1
|
||||
val chunkX = loc.blockX shr 4
|
||||
val chunkZ = loc.blockZ shr 4
|
||||
val pos = ChunkPos(chunkX, chunkZ)
|
||||
val playerChunkMap = worldserver1.getChunkSource().chunkMap
|
||||
val distanceManager: DistanceManager = playerChunkMap.distanceManager
|
||||
distanceManager.addTicket(TicketType.LOGIN, pos, 31, pos.toLong())
|
||||
worldserver1.getChunkSource().markAreaHighPriority(pos, 28, 3) // Paper - Chunk priority
|
||||
|
||||
val postChunkLoadJoin = this::class.java.superclass.getDeclaredMethod("postChunkLoadJoin", ServerPlayer::class.java, ServerLevel::class.java, Connection::class.java, ServerGamePacketListenerImpl::class.java, CompoundTag::class.java, String::class.java, String::class.java)
|
||||
postChunkLoadJoin.isAccessible = true
|
||||
postChunkLoadJoin.invoke(this, player, finalWorldserver, connection, playerconnection,
|
||||
nbttagcompound, "127.0.0.1", lastKnownName)
|
||||
}
|
||||
|
||||
fun placeNewPlayer(playerList: PlayerList, server: MinecraftServer, connection: FakeConnection, player: FakePlayer) {
|
||||
|
||||
}
|
||||
|
||||
fun placeNewPlayerOld(playerList: PlayerList, server: MinecraftServer, connection: FakeConnection, player: FakePlayer) {
|
||||
player.isRealPlayer = true // Paper - Chunk priority
|
||||
|
||||
player.networkManager = connection // Paper
|
||||
|
@ -139,7 +312,7 @@ object FakePlayerList {
|
|||
val pos = ChunkPos(chunkX, chunkZ)
|
||||
val playerChunkMap = worldServer.getChunkSource().chunkMap
|
||||
val distanceManager: DistanceManager = playerChunkMap.distanceManager
|
||||
distanceManager.addTicketAtLevel(TicketType.LOGIN, pos, 31, pos.toLong())
|
||||
// distanceManager.addTicket(TicketType.LOGIN, pos, 31, pos.toLong())
|
||||
worldServer.getChunkSource().markAreaHighPriority(pos, 28, 3) // Paper - Chunk priority
|
||||
|
||||
val postChunkLoadJoin = playerList::class.java.superclass.getDeclaredMethod("postChunkLoadJoin", ServerPlayer::class.java, ServerLevel::class.java, Connection::class.java, ServerGamePacketListenerImpl::class.java, CompoundTag::class.java, String::class.java, String::class.java)
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
package nl.kallestruik.dtweaks.managers
|
||||
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.level.ClipContext
|
||||
import net.minecraft.world.phys.*
|
||||
import nl.kallestruik.dlib.ReflectionUtil
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import nl.kallestruik.dtweaks.fakeplayer.FakePlayer
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
|
||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer
|
||||
import org.bukkit.scheduler.BukkitRunnable
|
||||
import org.bukkit.scheduler.BukkitTask
|
||||
import java.util.function.Predicate
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
|
||||
|
||||
|
||||
/*
|
||||
|
@ -24,12 +15,6 @@ import java.util.function.Predicate
|
|||
class FakePlayerManager(
|
||||
val plugin: DTweaks,
|
||||
) {
|
||||
|
||||
init {
|
||||
// Tick all fake players.
|
||||
FakePlayerTickTask().runTaskTimer(plugin, 10, 10)
|
||||
}
|
||||
|
||||
fun getPlayerByName(name: String): FakePlayer? {
|
||||
val player = Bukkit.getPlayer(name)
|
||||
if (player == null || !player.isOnline) return null
|
||||
|
@ -57,166 +42,4 @@ class FakePlayerManager(
|
|||
fakePlayer.kill()
|
||||
}
|
||||
}
|
||||
|
||||
private fun tickAll() {
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
if (!player.isOnline) continue
|
||||
val fakePlayer = (player as CraftPlayer).handle as? FakePlayer ?: continue
|
||||
fakePlayer.doTick()
|
||||
}
|
||||
}
|
||||
|
||||
// fun attackInterval(name: String, interval: Int) {
|
||||
//
|
||||
//
|
||||
// fakePlayer.swing()
|
||||
// }
|
||||
|
||||
fun attack(name: String) {
|
||||
val player = getPlayerByName(name) ?: return
|
||||
val target = getTarget(player) ?: return
|
||||
|
||||
when (target.type) {
|
||||
HitResult.Type.BLOCK -> {/*TODO: Not implemented*/}
|
||||
HitResult.Type.ENTITY -> {
|
||||
if (target !is EntityHitResult) return
|
||||
|
||||
player.attack(target.entity);
|
||||
player.swing(InteractionHand.MAIN_HAND);
|
||||
player.resetLastActionTime();
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
|
||||
fun use(name: String) {
|
||||
val player = getPlayerByName(name) ?: return
|
||||
val target = getTarget(player) ?: return
|
||||
|
||||
for (hand in InteractionHand.values()) {
|
||||
when (target.type) {
|
||||
HitResult.Type.BLOCK -> {
|
||||
if (target !is BlockHitResult) return
|
||||
|
||||
player.resetLastActionTime()
|
||||
val world = player.getLevel()
|
||||
val pos = target.blockPos
|
||||
val side = target.direction
|
||||
if (pos.y < player.getLevel().maxBuildHeight - (if (side === Direction.UP) 1 else 0)
|
||||
&& world.mayInteract(player, pos)) {
|
||||
val result = player.gameMode.useItemOn(player, world, player.getItemInHand(hand), hand, target)
|
||||
if (result.consumesAction()) {
|
||||
if (result.shouldSwing()) player.swing(hand)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
HitResult.Type.ENTITY -> {
|
||||
if (target !is EntityHitResult) return
|
||||
|
||||
player.resetLastActionTime()
|
||||
val entity = target.entity
|
||||
val relativeHitPos: Vec3 = target.getLocation().subtract(entity.x, entity.y, entity.z)
|
||||
|
||||
entity.interactAt(player, relativeHitPos, hand).consumesAction()
|
||||
|
||||
// fix for SS itemframe always returns CONSUME even if no action is performed
|
||||
player.interactOn(entity, hand).consumesAction()
|
||||
}
|
||||
}
|
||||
|
||||
player.gameMode.useItem(player, player.getLevel(), player.getItemInHand(hand), hand)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Ray tracing code borrowed from carpet mod: https://github.com/gnembon/fabric-carpet/blob/master/src/main/java/carpet/helpers/Tracer.java
|
||||
//
|
||||
|
||||
fun getTarget(player: FakePlayer): HitResult? {
|
||||
val reach: Double = if (player.gameMode.isCreative) 5.0 else 4.5f.toDouble()
|
||||
return rayTrace(player, 1F, reach, false)
|
||||
}
|
||||
|
||||
fun rayTrace(source: FakePlayer, partialTicks: Float, reach: Double, fluids: Boolean): HitResult? {
|
||||
val blockHit = rayTraceBlocks(source, partialTicks, reach, fluids)
|
||||
var maxSqDist = reach * reach
|
||||
if (blockHit != null) {
|
||||
maxSqDist = blockHit.location.distanceToSqr(source.getEyePosition(partialTicks))
|
||||
}
|
||||
val entityHit = rayTraceEntities(source, partialTicks, reach, maxSqDist)
|
||||
return entityHit ?: blockHit
|
||||
}
|
||||
|
||||
fun rayTraceBlocks(source: FakePlayer, partialTicks: Float, reach: Double, fluids: Boolean): BlockHitResult? {
|
||||
val pos: Vec3 = source.getEyePosition(partialTicks)
|
||||
val rotation: Vec3 = source.getViewVector(partialTicks)
|
||||
val reachEnd = pos.add(rotation.x * reach, rotation.y * reach, rotation.z * reach)
|
||||
return source.level.clip(
|
||||
ClipContext(
|
||||
pos,
|
||||
reachEnd,
|
||||
ClipContext.Block.OUTLINE,
|
||||
if (fluids) ClipContext.Fluid.ANY else ClipContext.Fluid.NONE,
|
||||
source
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun rayTraceEntities(source: FakePlayer, partialTicks: Float, reach: Double, maxSqDist: Double): EntityHitResult? {
|
||||
val pos = source.getEyePosition(partialTicks)
|
||||
val reachVec = source.getViewVector(partialTicks).scale(reach)
|
||||
val box = source.boundingBox.expandTowards(reachVec).inflate(1.0)
|
||||
return rayTraceEntities(source, pos, pos.add(reachVec), box, maxSqDist) {
|
||||
e -> !e.isSpectator && e.isPickable
|
||||
}
|
||||
}
|
||||
|
||||
fun rayTraceEntities(
|
||||
source: FakePlayer,
|
||||
start: Vec3,
|
||||
end: Vec3,
|
||||
box: AABB,
|
||||
maxSqDistance: Double,
|
||||
predicate: Predicate<Entity>,
|
||||
): EntityHitResult? {
|
||||
val world = source.level
|
||||
var targetDistance = maxSqDistance
|
||||
var target: Entity? = null
|
||||
var targetHitPos: Vec3? = null
|
||||
for (current in world.getEntities(source, box, predicate)) {
|
||||
val currentBox = current.boundingBox.inflate(current.pickRadius.toDouble())
|
||||
val currentHit = currentBox.clip(start, end)
|
||||
if (currentBox.contains(start)) {
|
||||
if (targetDistance >= 0) {
|
||||
target = current
|
||||
targetHitPos = currentHit.orElse(start)
|
||||
targetDistance = 0.0
|
||||
}
|
||||
} else if (currentHit.isPresent) {
|
||||
val currentHitPos: Vec3 = currentHit.get()
|
||||
val currentDistance = start.distanceToSqr(currentHitPos)
|
||||
if (currentDistance < targetDistance || targetDistance == 0.0) {
|
||||
if (current.rootVehicle === source.rootVehicle) {
|
||||
if (targetDistance == 0.0) {
|
||||
target = current
|
||||
targetHitPos = currentHitPos
|
||||
}
|
||||
} else {
|
||||
target = current
|
||||
targetHitPos = currentHitPos
|
||||
targetDistance = currentDistance
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (target == null) null else EntityHitResult(target, targetHitPos!!)
|
||||
}
|
||||
|
||||
inner class FakePlayerTickTask: BukkitRunnable() {
|
||||
override fun run() {
|
||||
tickAll()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,9 +4,7 @@ import nl.kallestruik.dtweaks.DTweaks
|
|||
import nl.kallestruik.dtweaks.fakeplayer.FakePlayer
|
||||
import nl.kallestruik.dtweaks.managers.FakePlayerManager
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer
|
||||
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.mobtweaks
|
||||
|
||||
import net.minecraft.core.GlobalPos
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
import nl.kallestruik.dtweaks.managers.NoSpawnZoneManager
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.craftbukkit.v1_18_R1.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.entity.CreatureSpawnEvent
|
||||
import org.bukkit.event.entity.EntitySpawnEvent
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class NoSpawnZones(
|
||||
private val plugin: JavaPlugin,
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.core.GlobalPos
|
|||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftVillager
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftVillager
|
||||
import org.bukkit.entity.Villager
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
|
|
Loading…
Reference in New Issue