|
|
|
@ -5,7 +5,10 @@ import com.comphenix.protocol.ProtocolLibrary
|
|
|
|
import com.comphenix.protocol.events.PacketContainer
|
|
|
|
import com.comphenix.protocol.events.PacketContainer
|
|
|
|
import com.comphenix.protocol.wrappers.*
|
|
|
|
import com.comphenix.protocol.wrappers.*
|
|
|
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry
|
|
|
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntList
|
|
|
|
import com.pobnellion.aoe.Aoe
|
|
|
|
|
|
|
|
import com.sk89q.worldedit.bukkit.BukkitAdapter
|
|
|
|
|
|
|
|
import com.sk89q.worldedit.extent.clipboard.Clipboard
|
|
|
|
|
|
|
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats
|
|
|
|
import org.bukkit.Bukkit
|
|
|
|
import org.bukkit.Bukkit
|
|
|
|
import org.bukkit.Location
|
|
|
|
import org.bukkit.Location
|
|
|
|
import org.bukkit.Material
|
|
|
|
import org.bukkit.Material
|
|
|
|
@ -16,18 +19,17 @@ import org.bukkit.event.Listener
|
|
|
|
import org.bukkit.event.block.Action
|
|
|
|
import org.bukkit.event.block.Action
|
|
|
|
import org.bukkit.event.player.PlayerInteractEvent
|
|
|
|
import org.bukkit.event.player.PlayerInteractEvent
|
|
|
|
import org.bukkit.event.player.PlayerMoveEvent
|
|
|
|
import org.bukkit.event.player.PlayerMoveEvent
|
|
|
|
import org.bukkit.potion.PotionEffectType
|
|
|
|
|
|
|
|
import org.joml.Math
|
|
|
|
import org.joml.Math
|
|
|
|
import org.joml.Vector3f
|
|
|
|
import org.joml.Vector3f
|
|
|
|
|
|
|
|
import java.io.File
|
|
|
|
|
|
|
|
import java.io.FileInputStream
|
|
|
|
import java.util.*
|
|
|
|
import java.util.*
|
|
|
|
import kotlin.math.floor
|
|
|
|
import kotlin.math.floor
|
|
|
|
import kotlin.math.min
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PlaceHint : Listener {
|
|
|
|
class PlaceHint {
|
|
|
|
|
|
|
|
companion object : Listener {
|
|
|
|
companion object {
|
|
|
|
|
|
|
|
private const val MAX_TARGET_DISTANCE = 64
|
|
|
|
private const val MAX_TARGET_DISTANCE = 64
|
|
|
|
private val playerHints = HashMap<UUID, HintMarker>();
|
|
|
|
private val playerHints = HashMap<UUID, PlaceHint>();
|
|
|
|
|
|
|
|
|
|
|
|
fun add(
|
|
|
|
fun add(
|
|
|
|
player: Player,
|
|
|
|
player: Player,
|
|
|
|
@ -36,12 +38,25 @@ class PlaceHint : Listener {
|
|
|
|
sizeZ: Float,
|
|
|
|
sizeZ: Float,
|
|
|
|
onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
|
|
onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
|
|
validate: (Location, Float, Float, Float) -> Boolean,
|
|
|
|
validate: (Location, Float, Float, Float) -> Boolean,
|
|
|
|
materialValid: Material = Material.LIME_STAINED_GLASS,
|
|
|
|
|
|
|
|
materialInvalid: Material = Material.RED_STAINED_GLASS,
|
|
|
|
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
remove(player)
|
|
|
|
remove(player)
|
|
|
|
createOutlineTeam(player)
|
|
|
|
createOutlineTeam(player)
|
|
|
|
playerHints[player.uniqueId] = HintMarker(player, sizeX, sizeY, sizeZ, onConfirm, validate, materialValid, materialInvalid)
|
|
|
|
|
|
|
|
|
|
|
|
playerHints[player.uniqueId] = PlaceHint(player, sizeX, sizeY, sizeZ, onConfirm, validate)
|
|
|
|
|
|
|
|
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE);
|
|
|
|
|
|
|
|
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun add(
|
|
|
|
|
|
|
|
player: Player,
|
|
|
|
|
|
|
|
schematicName: String,
|
|
|
|
|
|
|
|
onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
|
|
|
|
|
|
validate: (Location, Float, Float, Float) -> Boolean,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
remove(player)
|
|
|
|
|
|
|
|
createOutlineTeam(player)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
playerHints[player.uniqueId] = PlaceHint(player, schematicName, onConfirm, validate)
|
|
|
|
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE);
|
|
|
|
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE);
|
|
|
|
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
|
|
|
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -63,107 +78,129 @@ class PlaceHint : Listener {
|
|
|
|
val packet = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
|
|
|
val packet = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
|
|
|
packet.strings.write(0, "placeValid")
|
|
|
|
packet.strings.write(0, "placeValid")
|
|
|
|
packet.integers.write(0, 0)
|
|
|
|
packet.integers.write(0, 0)
|
|
|
|
packet.optionalTeamParameters.write(0, Optional.of(Utils.teamParams))
|
|
|
|
packet.optionalTeamParameters.write(0, Optional.of(teamParamsTemplate))
|
|
|
|
|
|
|
|
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@EventHandler
|
|
|
|
|
|
|
|
fun onPlayerLook(event: PlayerMoveEvent) {
|
|
|
|
|
|
|
|
if (!playerHints.containsKey(event.player.uniqueId))
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val block = event.player.getTargetBlockExact(MAX_TARGET_DISTANCE);
|
|
|
|
|
|
|
|
playerHints[event.player.uniqueId]!!.moveTo(block?.location)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@EventHandler
|
|
|
|
|
|
|
|
fun onLeftClick(event: PlayerInteractEvent) {
|
|
|
|
|
|
|
|
if (!playerHints.containsKey(event.player.uniqueId) || (event.action != Action.LEFT_CLICK_BLOCK && event.action != Action.LEFT_CLICK_AIR))
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!playerHints[event.player.uniqueId]!!.isValid)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val marker = playerHints[event.player.uniqueId]!!
|
|
|
|
|
|
|
|
marker.onConfirm(marker.currentLocation!!, marker.sizeX, marker.sizeY, marker.sizeZ)
|
|
|
|
|
|
|
|
remove(event.player)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private val teamParamsTemplate: WrappedTeamParameters = WrappedTeamParameters.newBuilder()
|
|
|
|
|
|
|
|
.displayName(WrappedChatComponent.fromText(""))
|
|
|
|
|
|
|
|
.collisionRule("never")
|
|
|
|
|
|
|
|
.nametagVisibility("never")
|
|
|
|
|
|
|
|
.options(0)
|
|
|
|
|
|
|
|
.color(EnumWrappers.ChatFormatting.RED)
|
|
|
|
|
|
|
|
.prefix(WrappedChatComponent.fromText(""))
|
|
|
|
|
|
|
|
.suffix(WrappedChatComponent.fromText(""))
|
|
|
|
|
|
|
|
.build()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@EventHandler
|
|
|
|
private val player: Player
|
|
|
|
fun onPlayerLook(event: PlayerMoveEvent) {
|
|
|
|
private val sizeX: Float
|
|
|
|
if (!playerHints.containsKey(event.player.uniqueId))
|
|
|
|
private val sizeY: Float
|
|
|
|
return
|
|
|
|
private val sizeZ: Float
|
|
|
|
|
|
|
|
val onConfirm: (Location, Float, Float, Float) -> Unit
|
|
|
|
val block = event.player.getTargetBlockExact(MAX_TARGET_DISTANCE);
|
|
|
|
val validate: (Location, Float, Float, Float) -> Boolean
|
|
|
|
playerHints[event.player.uniqueId]!!.moveTo(block?.location)
|
|
|
|
private val schematic: Clipboard?
|
|
|
|
}
|
|
|
|
private var marker: Pair<Int, UUID> = Pair((Math.random() * Int.MAX_VALUE).toInt(), UUID.randomUUID())
|
|
|
|
|
|
|
|
private var base: Pair<Int, UUID> = Pair((Math.random() * Int.MAX_VALUE).toInt(), UUID.randomUUID())
|
|
|
|
@EventHandler
|
|
|
|
private val displayIds: MutableList<Pair<Int, UUID>> = mutableListOf()
|
|
|
|
fun onLeftClick(event: PlayerInteractEvent) {
|
|
|
|
|
|
|
|
if (!playerHints.containsKey(event.player.uniqueId) || (event.action != Action.LEFT_CLICK_BLOCK && event.action != Action.LEFT_CLICK_AIR))
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!playerHints[event.player.uniqueId]!!.isValid)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val marker = playerHints[event.player.uniqueId]!!
|
|
|
|
|
|
|
|
marker.onConfirm(marker.currentLocation!!, marker.sizeX, marker.sizeY, marker.sizeZ)
|
|
|
|
|
|
|
|
remove(event.player)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class HintMarker(
|
|
|
|
|
|
|
|
val player: Player,
|
|
|
|
|
|
|
|
val sizeX: Float,
|
|
|
|
|
|
|
|
val sizeY: Float,
|
|
|
|
|
|
|
|
val sizeZ: Float,
|
|
|
|
|
|
|
|
val onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
|
|
|
|
|
|
val validate: (Location, Float, Float, Float) -> Boolean,
|
|
|
|
|
|
|
|
val materialValid: Material,
|
|
|
|
|
|
|
|
val materialInvalid: Material,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
private val markerUuid = UUID.randomUUID()
|
|
|
|
|
|
|
|
private val outlineUuid = UUID.randomUUID()
|
|
|
|
|
|
|
|
private val markerId = (Math.random() * Int.MAX_VALUE).toInt()
|
|
|
|
|
|
|
|
private val outlineId = markerId + 1
|
|
|
|
|
|
|
|
var currentLocation: Location? = null
|
|
|
|
var currentLocation: Location? = null
|
|
|
|
var isValid = false
|
|
|
|
var isValid = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(player: Player, sizeX: Float, sizeY: Float, sizeZ: Float,
|
|
|
|
|
|
|
|
onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
|
|
|
|
|
|
validate: (Location, Float, Float, Float) -> Boolean) {
|
|
|
|
|
|
|
|
this.player = player
|
|
|
|
|
|
|
|
this.sizeX = sizeX
|
|
|
|
|
|
|
|
this.sizeY = sizeY
|
|
|
|
|
|
|
|
this.sizeZ = sizeZ
|
|
|
|
|
|
|
|
this.onConfirm = onConfirm
|
|
|
|
|
|
|
|
this.validate = validate
|
|
|
|
|
|
|
|
this.schematic = null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(player: Player, schematicName: String,
|
|
|
|
|
|
|
|
onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
|
|
|
|
|
|
validate: (Location, Float, Float, Float) -> Boolean) {
|
|
|
|
|
|
|
|
this.player = player
|
|
|
|
|
|
|
|
this.onConfirm = onConfirm
|
|
|
|
|
|
|
|
this.validate = validate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val file = File(Aoe.getSchematicsFolder(),
|
|
|
|
|
|
|
|
if (schematicName.endsWith(".schem")) schematicName else "$schematicName.schem")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val format = ClipboardFormats.findByFile(file)
|
|
|
|
|
|
|
|
val reader = format?.getReader(FileInputStream(file))
|
|
|
|
|
|
|
|
val clipboard = reader?.read()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.schematic = clipboard
|
|
|
|
|
|
|
|
this.sizeX = clipboard!!.dimensions.x().toFloat()
|
|
|
|
|
|
|
|
this.sizeY = clipboard.dimensions.y().toFloat()
|
|
|
|
|
|
|
|
this.sizeZ = clipboard.dimensions.z().toFloat()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun show(initialLocation: Location) {
|
|
|
|
private fun show(initialLocation: Location) {
|
|
|
|
initialLocation.add(-floor(sizeX / 2.0), 1.0, -floor(sizeZ / 2.0))
|
|
|
|
initialLocation.add(-floor(sizeX / 2.0), 1.0, -floor(sizeZ / 2.0))
|
|
|
|
|
|
|
|
|
|
|
|
spawnBlockDisplay(markerId, markerUuid, initialLocation, Material.GRAY_STAINED_GLASS, Vector3f(sizeX, 0.2f, sizeZ), 0b01000000)
|
|
|
|
val spawnMarkerPacket = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY)
|
|
|
|
// spawnBlockDisplay(outlineId, outlineUuid, initialLocation, Material.STONE, Vector3f(sizeX, sizeY, sizeZ), 0b00100000)
|
|
|
|
spawnMarkerPacket.integers.write(0, marker.first)
|
|
|
|
|
|
|
|
spawnMarkerPacket.uuiDs.write(0, marker.second)
|
|
|
|
val spawnSlimePacket = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY)
|
|
|
|
spawnMarkerPacket.entityTypeModifier.write(0, EntityType.BLOCK_DISPLAY)
|
|
|
|
spawnSlimePacket.integers.write(0, outlineId)
|
|
|
|
spawnMarkerPacket.doubles
|
|
|
|
spawnSlimePacket.uuiDs.write(0, outlineUuid)
|
|
|
|
|
|
|
|
spawnSlimePacket.entityTypeModifier.write(0, EntityType.SLIME)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
spawnSlimePacket.doubles
|
|
|
|
|
|
|
|
.write(0, initialLocation.x)
|
|
|
|
.write(0, initialLocation.x)
|
|
|
|
.write(1, initialLocation.y)
|
|
|
|
.write(1, initialLocation.y)
|
|
|
|
.write(2, initialLocation.z)
|
|
|
|
.write(2, initialLocation.z)
|
|
|
|
|
|
|
|
|
|
|
|
val dataPacket = PacketContainer(PacketType.Play.Server.ENTITY_METADATA)
|
|
|
|
base = spawnBlockDisplay(initialLocation, Material.GRAY_STAINED_GLASS, scale = Vector3f(sizeX + 0.05f, 0.2f, sizeZ + 0.05f))
|
|
|
|
dataPacket.integers.write(0, outlineId)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: 1 - display riding slime for nicer movement
|
|
|
|
schematic?.iterator()?.forEach {
|
|
|
|
// TODO: 2 - slime riding display for nicer movement
|
|
|
|
val material = BukkitAdapter.adapt(schematic.getBlock(it)).material
|
|
|
|
// TODO: 3 - resource pack for outline with really low opacity
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val watcher = WrappedDataWatcher()
|
|
|
|
val x = (it.x() - schematic.minimumPoint.x()).toFloat()
|
|
|
|
watcher.setObject(0, Registry.get(Byte::class.javaObjectType), 0b01100000.toByte())
|
|
|
|
val y = (it.y() - schematic.minimumPoint.y()).toFloat()
|
|
|
|
// watcher.setObject(5, Registry.get(Boolean::class.javaObjectType), true)
|
|
|
|
val z = (it.z() - schematic.minimumPoint.z()).toFloat()
|
|
|
|
watcher.setObject(16, Registry.get(Int::class.javaObjectType), min(sizeX, min(sizeY, sizeZ)).toInt())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dataPacket.dataValueCollectionModifier.write(0, watcher.watchableObjects
|
|
|
|
if (!material.isAir && !material.isEmpty)
|
|
|
|
.map { WrappedDataValue(it.watcherObject.index, it.watcherObject.serializer, it.rawValue) })
|
|
|
|
displayIds.add(spawnBlockDisplay(initialLocation, material, offset = Vector3f(x, y, z), options = 0b01000000))
|
|
|
|
|
|
|
|
}
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, spawnSlimePacket)
|
|
|
|
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, dataPacket)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val ridingPacket = PacketContainer(PacketType.Play.Server.MOUNT)
|
|
|
|
|
|
|
|
ridingPacket.integers.write(0, outlineId)
|
|
|
|
|
|
|
|
ridingPacket.integerArrays.write(0, intArrayOf(markerId))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
|
|
|
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
|
|
|
outlineTeamPacket.strings.write(0, "placeValid")
|
|
|
|
outlineTeamPacket.strings.write(0, "placeValid")
|
|
|
|
outlineTeamPacket.integers.write(0, 3)
|
|
|
|
outlineTeamPacket.integers.write(0, 3)
|
|
|
|
outlineTeamPacket.getSpecificModifier(Collection::class.java).write(0, listOf(outlineUuid.toString()))
|
|
|
|
outlineTeamPacket.getSpecificModifier(Collection::class.java).write(0, displayIds.map { it.second.toString() })
|
|
|
|
|
|
|
|
|
|
|
|
// val outlineInvisiblePacket = PacketContainer(PacketType.Play.Server.ENTITY_EFFECT)
|
|
|
|
val ids = displayIds.map { it.first }.toMutableList()
|
|
|
|
// outlineInvisiblePacket.integers
|
|
|
|
ids.add(base.first)
|
|
|
|
// .write(0, outlineId)
|
|
|
|
|
|
|
|
// .write(1, 1)
|
|
|
|
|
|
|
|
// .write(2, -1)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// outlineInvisiblePacket.effectTypes.write(0, PotionEffectType.INVISIBILITY)
|
|
|
|
|
|
|
|
// outlineInvisiblePacket.bytes.write(0, 0b0000.toByte())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val passengerPacket = PacketContainer(PacketType.Play.Server.MOUNT)
|
|
|
|
|
|
|
|
passengerPacket.integers.write(0, marker.first)
|
|
|
|
|
|
|
|
passengerPacket.integerArrays.write(0, ids.toIntArray())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, spawnMarkerPacket)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, outlineTeamPacket)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, outlineTeamPacket)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, ridingPacket)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, passengerPacket)
|
|
|
|
// ProtocolLibrary.getProtocolManager().sendServerPacket(player, outlineInvisiblePacket)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isValid = validate(initialLocation, sizeX, sizeY, sizeZ)
|
|
|
|
isValid = validate(initialLocation, sizeX, sizeY, sizeZ)
|
|
|
|
updateColour()
|
|
|
|
updateColour()
|
|
|
|
@ -173,7 +210,10 @@ private class HintMarker(
|
|
|
|
|
|
|
|
|
|
|
|
private fun hide() {
|
|
|
|
private fun hide() {
|
|
|
|
val packet = PacketContainer(PacketType.Play.Server.ENTITY_DESTROY)
|
|
|
|
val packet = PacketContainer(PacketType.Play.Server.ENTITY_DESTROY)
|
|
|
|
packet.intLists.write(0, IntList.of(markerId, outlineId))
|
|
|
|
val ids = displayIds.map { it.first }.toMutableList()
|
|
|
|
|
|
|
|
ids.add(marker.first)
|
|
|
|
|
|
|
|
ids.add(base.first)
|
|
|
|
|
|
|
|
packet.intLists.write(0, ids)
|
|
|
|
|
|
|
|
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet)
|
|
|
|
|
|
|
|
|
|
|
|
@ -194,28 +234,17 @@ private class HintMarker(
|
|
|
|
|
|
|
|
|
|
|
|
newLocation.add(-floor(sizeX / 2.0), 1.0, -floor(sizeZ / 2.0))
|
|
|
|
newLocation.add(-floor(sizeX / 2.0), 1.0, -floor(sizeZ / 2.0))
|
|
|
|
|
|
|
|
|
|
|
|
// val markerPacket = PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT)
|
|
|
|
val basePacket = PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT)
|
|
|
|
// markerPacket.integers.write(0, markerId)
|
|
|
|
basePacket.integers.write(0, marker.first)
|
|
|
|
//
|
|
|
|
|
|
|
|
// markerPacket.doubles
|
|
|
|
|
|
|
|
// .write(0, newLocation.x)
|
|
|
|
|
|
|
|
// .write(1, newLocation.y)
|
|
|
|
|
|
|
|
// .write(2, newLocation.z)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// markerPacket.booleans.write(0, true)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// ProtocolLibrary.getProtocolManager().sendServerPacket(player, markerPacket)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val outlinePacket = PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT)
|
|
|
|
basePacket.doubles
|
|
|
|
outlinePacket.integers.write(0, outlineId)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
outlinePacket.doubles
|
|
|
|
|
|
|
|
.write(0, newLocation.x)
|
|
|
|
.write(0, newLocation.x)
|
|
|
|
.write(1, newLocation.y)
|
|
|
|
.write(1, newLocation.y)
|
|
|
|
.write(2, newLocation.z)
|
|
|
|
.write(2, newLocation.z)
|
|
|
|
|
|
|
|
|
|
|
|
outlinePacket.booleans.write(0, true)
|
|
|
|
basePacket.booleans.write(0, true)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, outlinePacket)
|
|
|
|
|
|
|
|
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, basePacket)
|
|
|
|
|
|
|
|
|
|
|
|
currentLocation = newLocation
|
|
|
|
currentLocation = newLocation
|
|
|
|
|
|
|
|
|
|
|
|
@ -230,7 +259,16 @@ private class HintMarker(
|
|
|
|
|
|
|
|
|
|
|
|
// region helper functions
|
|
|
|
// region helper functions
|
|
|
|
|
|
|
|
|
|
|
|
private fun spawnBlockDisplay(id: Int, uuid: UUID, location: Location, material: Material, scale: Vector3f, options: Byte) {
|
|
|
|
private fun spawnBlockDisplay(
|
|
|
|
|
|
|
|
location: Location,
|
|
|
|
|
|
|
|
material: Material,
|
|
|
|
|
|
|
|
scale: Vector3f = Vector3f(1f, 1f, 1f),
|
|
|
|
|
|
|
|
offset: Vector3f = Vector3f(0f, 0f, 0f),
|
|
|
|
|
|
|
|
options: Byte = 0b00000000
|
|
|
|
|
|
|
|
): Pair<Int, UUID> {
|
|
|
|
|
|
|
|
val id = (Math.random() * Int.MAX_VALUE).toInt()
|
|
|
|
|
|
|
|
val uuid = UUID.randomUUID()
|
|
|
|
|
|
|
|
|
|
|
|
val spawnPacket = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY)
|
|
|
|
val spawnPacket = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY)
|
|
|
|
spawnPacket.integers.write(0, id)
|
|
|
|
spawnPacket.integers.write(0, id)
|
|
|
|
spawnPacket.uuiDs.write(0, uuid)
|
|
|
|
spawnPacket.uuiDs.write(0, uuid)
|
|
|
|
@ -250,6 +288,7 @@ private class HintMarker(
|
|
|
|
|
|
|
|
|
|
|
|
val watcher = WrappedDataWatcher()
|
|
|
|
val watcher = WrappedDataWatcher()
|
|
|
|
watcher.setObject(0, Registry.get(Byte::class.javaObjectType), options)
|
|
|
|
watcher.setObject(0, Registry.get(Byte::class.javaObjectType), options)
|
|
|
|
|
|
|
|
watcher.setObject(11, Registry.get(Vector3f::class.javaObjectType), offset)
|
|
|
|
watcher.setObject(12, Registry.get(Vector3f::class.javaObjectType), scale)
|
|
|
|
watcher.setObject(12, Registry.get(Vector3f::class.javaObjectType), scale)
|
|
|
|
watcher.setObject(23, Registry.getBlockDataSerializer(false), blockData)
|
|
|
|
watcher.setObject(23, Registry.getBlockDataSerializer(false), blockData)
|
|
|
|
|
|
|
|
|
|
|
|
@ -258,20 +297,22 @@ private class HintMarker(
|
|
|
|
|
|
|
|
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, spawnPacket)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, spawnPacket)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, dataPacket)
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, dataPacket)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Pair<Int, UUID>(id, uuid)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun updateColour() {
|
|
|
|
private fun updateColour() {
|
|
|
|
// marker
|
|
|
|
// base
|
|
|
|
val dataPacket = PacketContainer(PacketType.Play.Server.ENTITY_METADATA)
|
|
|
|
val dataPacket = PacketContainer(PacketType.Play.Server.ENTITY_METADATA)
|
|
|
|
dataPacket.integers.write(0,markerId);
|
|
|
|
dataPacket.integers.write(0, base.first);
|
|
|
|
|
|
|
|
|
|
|
|
val material = if (isValid) materialValid else materialInvalid
|
|
|
|
val material = if (isValid) Material.LIME_STAINED_GLASS else Material.RED_STAINED_GLASS
|
|
|
|
val blockData = BukkitConverters
|
|
|
|
val blockData = BukkitConverters
|
|
|
|
.getWrappedBlockDataConverter()
|
|
|
|
.getWrappedBlockDataConverter()
|
|
|
|
.getGeneric(WrappedBlockData.createData(material))
|
|
|
|
.getGeneric(WrappedBlockData.createData(material))
|
|
|
|
|
|
|
|
|
|
|
|
val metadata = listOf(
|
|
|
|
val metadata = listOf(
|
|
|
|
WrappedDataValue(23, WrappedDataWatcher.Registry.getBlockDataSerializer(false), blockData)
|
|
|
|
WrappedDataValue(23, Registry.getBlockDataSerializer(false), blockData)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
dataPacket.dataValueCollectionModifier.write(0, metadata)
|
|
|
|
dataPacket.dataValueCollectionModifier.write(0, metadata)
|
|
|
|
@ -281,7 +322,7 @@ private class HintMarker(
|
|
|
|
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
|
|
|
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
|
|
|
outlineTeamPacket.strings.write(0, "placeValid")
|
|
|
|
outlineTeamPacket.strings.write(0, "placeValid")
|
|
|
|
outlineTeamPacket.integers.write(0, 2)
|
|
|
|
outlineTeamPacket.integers.write(0, 2)
|
|
|
|
val params = WrappedTeamParameters.newBuilder(Utils.teamParams)
|
|
|
|
val params = WrappedTeamParameters.newBuilder(teamParamsTemplate)
|
|
|
|
.color(if (isValid) EnumWrappers.ChatFormatting.GREEN else EnumWrappers.ChatFormatting.RED)
|
|
|
|
.color(if (isValid) EnumWrappers.ChatFormatting.GREEN else EnumWrappers.ChatFormatting.RED)
|
|
|
|
.build()
|
|
|
|
.build()
|
|
|
|
|
|
|
|
|
|
|
|
@ -290,18 +331,4 @@ private class HintMarker(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
// endregion
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class Utils {
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
|
|
|
val teamParams: WrappedTeamParameters = WrappedTeamParameters.newBuilder()
|
|
|
|
|
|
|
|
.displayName(WrappedChatComponent.fromText(""))
|
|
|
|
|
|
|
|
.collisionRule("never")
|
|
|
|
|
|
|
|
.nametagVisibility("never")
|
|
|
|
|
|
|
|
.options(0)
|
|
|
|
|
|
|
|
.color(EnumWrappers.ChatFormatting.RED)
|
|
|
|
|
|
|
|
.prefix(WrappedChatComponent.fromText(""))
|
|
|
|
|
|
|
|
.suffix(WrappedChatComponent.fromText(""))
|
|
|
|
|
|
|
|
.build()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|