[refactor] Player Packet Manager (#1947)

This commit is contained in:
Xiaro 2021-03-12 22:14:35 -05:00 committed by GitHub
parent fc7fc34ec3
commit e79d65dc8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 488 additions and 306 deletions

View File

@ -5,18 +5,18 @@ import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraftforge.common.ForgeHooks;
import org.kamiblue.client.event.KamiEventBus;
import org.kamiblue.client.event.events.GuiEvent;
import org.kamiblue.client.event.events.RunGameLoopEvent;
import org.kamiblue.client.gui.mc.KamiGuiUpdateNotification;
import org.kamiblue.client.manager.managers.PlayerPacketManager;
import org.kamiblue.client.manager.managers.HotbarManager;
import org.kamiblue.client.mixin.client.accessor.player.AccessorEntityPlayerSP;
import org.kamiblue.client.mixin.client.accessor.player.AccessorPlayerControllerMP;
import org.kamiblue.client.module.modules.combat.CrystalAura;
@ -39,9 +39,6 @@ public abstract class MixinMinecraft {
@Shadow public GameSettings gameSettings;
@Shadow public PlayerControllerMP playerController;
@Shadow public RayTraceResult objectMouseOver;
@Shadow public EntityRenderer entityRenderer;
@Shadow protected abstract void clickMouse();
private boolean handActive = false;
@ -87,19 +84,26 @@ public abstract class MixinMinecraft {
// Fix random crystal placing when eating gapple in offhand
@Inject(method = "rightClickMouse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;getHeldItem(Lnet/minecraft/util/EnumHand;)Lnet/minecraft/item/ItemStack;"), cancellable = true)
public void rightClickMouseAtInvokeGetHeldItem(CallbackInfo ci) {
EntityPlayerSP player = Wrapper.getPlayer();
WorldClient world = Wrapper.getWorld();
PlayerControllerMP playerController = Wrapper.getMinecraft().playerController;
RayTraceResult objectMouseOver = Wrapper.getMinecraft().objectMouseOver;
if (player == null || world == null || playerController == null) return;
if (CrystalAura.INSTANCE.isDisabled() || CrystalAura.INSTANCE.getInactiveTicks() > 2) return;
if (player.getHeldItemOffhand().getItem() == Items.END_CRYSTAL) return;
if (PlayerPacketManager.INSTANCE.getHoldingItemStack().getItem() != Items.END_CRYSTAL) return;
if (HotbarManager.INSTANCE.getServerSideItem(player).getItem() != Items.END_CRYSTAL) return;
ci.cancel();
for (EnumHand enumhand : EnumHand.values()) {
ItemStack itemstack = this.player.getHeldItem(enumhand);
if (itemstack.isEmpty() && (this.objectMouseOver == null || this.objectMouseOver.typeOfHit == RayTraceResult.Type.MISS)) {
net.minecraftforge.common.ForgeHooks.onEmptyClick(this.player, enumhand);
ItemStack itemstack = player.getHeldItem(enumhand);
if (itemstack.isEmpty() && (objectMouseOver == null || objectMouseOver.typeOfHit == RayTraceResult.Type.MISS)) {
ForgeHooks.onEmptyClick(player, enumhand);
}
if (!itemstack.isEmpty() && this.playerController.processRightClick(this.player, this.world, enumhand) == EnumActionResult.SUCCESS) {
this.entityRenderer.itemRenderer.resetEquippedProgress(enumhand);
if (!itemstack.isEmpty() && playerController.processRightClick(player, world, enumhand) == EnumActionResult.SUCCESS) {
Wrapper.getMinecraft().entityRenderer.itemRenderer.resetEquippedProgress(enumhand);
}
}
}

View File

@ -18,6 +18,7 @@ import org.kamiblue.client.event.events.OnUpdateWalkingPlayerEvent;
import org.kamiblue.client.event.events.PlayerMoveEvent;
import org.kamiblue.client.gui.mc.KamiGuiBeacon;
import org.kamiblue.client.manager.managers.MessageManager;
import org.kamiblue.client.manager.managers.PlayerPacketManager;
import org.kamiblue.client.module.modules.chat.PortalChat;
import org.kamiblue.client.module.modules.misc.BeaconSelector;
import org.kamiblue.client.module.modules.movement.Sprint;
@ -121,18 +122,28 @@ public abstract class MixinEntityPlayerSP extends EntityPlayer {
MessageManager.INSTANCE.setLastPlayerMessage(message);
}
@Inject(method = "onUpdateWalkingPlayer", at = @At("HEAD"), cancellable = true)
private void onUpdateWalkingPlayerPre(CallbackInfo ci) {
// Setup flags
boolean moving = isMoving();
boolean rotating = isRotating();
boolean sprinting = this.isSprinting();
boolean sneaking = this.isSneaking();
boolean onGround = this.onGround;
Vec3d pos = new Vec3d(this.posX, this.getEntityBoundingBox().minY, this.posZ);
Vec2f rotation = new Vec2f(this);
@Inject(method = "onUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;onUpdateWalkingPlayer()V", shift = At.Shift.AFTER))
private void onUpdateInvokeOnUpdateWalkingPlayer(CallbackInfo ci) {
Vec3d serverSidePos = PlayerPacketManager.INSTANCE.getServerSidePosition();
Vec2f serverSideRotation = PlayerPacketManager.INSTANCE.getPrevServerSideRotation();
OnUpdateWalkingPlayerEvent event = new OnUpdateWalkingPlayerEvent(moving, rotating, sprinting, sneaking, onGround, pos, rotation);
this.lastReportedPosX = serverSidePos.x;
this.lastReportedPosY = serverSidePos.y;
this.lastReportedPosZ = serverSidePos.z;
this.lastReportedYaw = serverSideRotation.getX();
this.lastReportedPitch = serverSideRotation.getY();
}
@Inject(method = "onUpdateWalkingPlayer", at = @At("HEAD"), cancellable = true)
private void onUpdateWalkingPlayerHead(CallbackInfo ci) {
// Setup flags
Vec3d position = new Vec3d(this.posX, this.getEntityBoundingBox().minY, this.posZ);
Vec2f rotation = new Vec2f(this.rotationYaw, this.rotationPitch);
boolean moving = isMoving(position);
boolean rotating = isRotating(rotation);
OnUpdateWalkingPlayerEvent event = new OnUpdateWalkingPlayerEvent(moving, rotating, position, rotation);
KamiEventBus.INSTANCE.post(event);
event = event.nextPhase();
@ -141,86 +152,86 @@ public abstract class MixinEntityPlayerSP extends EntityPlayer {
if (event.getCancelled()) {
ci.cancel();
++this.positionUpdateTicks;
if (!event.getCancelAll()) {
// Copy flags from event
moving = event.isMoving();
rotating = event.isRotating();
position = event.getPosition();
rotation = event.getRotation();
// Copy flags from event
moving = event.getMoving();
rotating = event.getRotating();
sprinting = event.getSprinting();
sneaking = event.getSneaking();
onGround = event.getOnGround();
pos = event.getPos();
rotation = event.getRotation();
// Sprinting Packet
if (sprinting != this.serverSprintState) {
if (sprinting) {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.START_SPRINTING));
} else {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.STOP_SPRINTING));
}
this.serverSprintState = sprinting;
}
// Sneaking Packet
if (sneaking != this.serverSneakState) {
if (sneaking) {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.START_SNEAKING));
} else {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.STOP_SNEAKING));
}
this.serverSneakState = sneaking;
}
// Position & Rotation Packet
if (this.isCurrentViewEntity()) {
if (this.isRiding()) {
this.connection.sendPacket(new CPacketPlayer.PositionRotation(this.motionX, -999.0D, this.motionZ, rotation.getX(), rotation.getY(), onGround));
moving = false;
} else if (moving && rotating) {
this.connection.sendPacket(new CPacketPlayer.PositionRotation(pos.x, pos.y, pos.z, rotation.getX(), rotation.getY(), onGround));
} else if (moving) {
this.connection.sendPacket(new CPacketPlayer.Position(pos.x, pos.y, pos.z, onGround));
} else if (rotating) {
this.connection.sendPacket(new CPacketPlayer.Rotation(rotation.getX(), rotation.getY(), onGround));
} else if (this.prevOnGround != onGround) {
this.connection.sendPacket(new CPacketPlayer(onGround));
}
if (moving) {
this.lastReportedPosX = pos.x;
this.lastReportedPosY = pos.y;
this.lastReportedPosZ = pos.z;
this.positionUpdateTicks = 0;
}
if (rotating) {
this.lastReportedYaw = rotation.getX();
this.lastReportedPitch = rotation.getY();
}
sendSprintPacket();
sendSneakPacket();
sendPlayerPacket(moving, rotating, position, rotation);
this.prevOnGround = onGround;
this.autoJumpEnabled = this.mc.gameSettings.autoJump;
}
++this.positionUpdateTicks;
this.autoJumpEnabled = this.mc.gameSettings.autoJump;
}
event = event.nextPhase();
KamiEventBus.INSTANCE.post(event);
}
private boolean isMoving() {
double xDiff = this.posX - this.lastReportedPosX;
double yDiff = this.getEntityBoundingBox().minY - this.lastReportedPosY;
double zDiff = this.posZ - this.lastReportedPosZ;
private void sendSprintPacket() {
boolean sprinting = this.isSprinting();
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff > 9.0E-4D || this.positionUpdateTicks >= 20;
if (sprinting != this.serverSprintState) {
if (sprinting) {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.START_SPRINTING));
} else {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.STOP_SPRINTING));
}
this.serverSprintState = sprinting;
}
}
private boolean isRotating() {
double yawDiff = this.rotationYaw - this.lastReportedYaw;
double pitchDiff = this.rotationPitch - this.lastReportedPitch;
private void sendSneakPacket() {
boolean sneaking = this.isSneaking();
if (sneaking != this.serverSneakState) {
if (sneaking) {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.START_SNEAKING));
} else {
this.connection.sendPacket(new CPacketEntityAction(this, CPacketEntityAction.Action.STOP_SNEAKING));
}
this.serverSneakState = sneaking;
}
}
private void sendPlayerPacket(boolean moving, boolean rotating, Vec3d position, Vec2f rotation) {
if (!this.isCurrentViewEntity()) return;
if (this.isRiding()) {
this.connection.sendPacket(new CPacketPlayer.PositionRotation(this.motionX, -999.0D, this.motionZ, rotation.getX(), rotation.getY(), onGround));
moving = false;
} else if (moving && rotating) {
this.connection.sendPacket(new CPacketPlayer.PositionRotation(position.x, position.y, position.z, rotation.getX(), rotation.getY(), onGround));
} else if (moving) {
this.connection.sendPacket(new CPacketPlayer.Position(position.x, position.y, position.z, onGround));
} else if (rotating) {
this.connection.sendPacket(new CPacketPlayer.Rotation(rotation.getX(), rotation.getY(), onGround));
} else if (this.prevOnGround != onGround) {
this.connection.sendPacket(new CPacketPlayer(onGround));
}
if (moving) {
this.positionUpdateTicks = 0;
}
}
private boolean isMoving(Vec3d position) {
double xDiff = position.x - this.lastReportedPosX;
double yDiff = position.y - this.lastReportedPosY;
double zDiff = position.z - this.lastReportedPosZ;
return this.positionUpdateTicks >= 20 || xDiff * xDiff + yDiff * yDiff + zDiff * zDiff > 9.0E-4D;
}
private boolean isRotating(Vec2f rotation) {
double yawDiff = rotation.getX() - this.lastReportedYaw;
double pitchDiff = rotation.getY() - this.lastReportedPitch;
return yawDiff != 0.0D || pitchDiff != 0.0D;
}

View File

@ -5,25 +5,51 @@ import org.kamiblue.client.event.Cancellable
import org.kamiblue.client.event.Event
import org.kamiblue.client.event.IMultiPhase
import org.kamiblue.client.event.Phase
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.util.math.Vec2f
import org.kamiblue.commons.extension.next
class OnUpdateWalkingPlayerEvent private constructor(
var moving: Boolean,
var rotating: Boolean,
var sprinting: Boolean,
var sneaking: Boolean,
var onGround: Boolean,
var pos: Vec3d,
var rotation: Vec2f,
moving: Boolean,
rotating: Boolean,
position: Vec3d,
rotation: Vec2f,
override val phase: Phase
) : Event, IMultiPhase<OnUpdateWalkingPlayerEvent>, Cancellable() {
constructor(moving: Boolean, rotating: Boolean, sprinting: Boolean, sneaking: Boolean, onGround: Boolean, pos: Vec3d, rotation: Vec2f)
: this(moving, rotating, sprinting, sneaking, onGround, pos, rotation, Phase.PRE)
var position = position; private set
var rotation = rotation; private set
var moving = moving
@JvmName("isMoving") get
private set
var rotating = rotating
@JvmName("isRotating") get
private set
var cancelAll = false; private set
constructor(moving: Boolean, rotating: Boolean, position: Vec3d, rotation: Vec2f) : this(moving, rotating, position, rotation, Phase.PRE)
override fun nextPhase(): OnUpdateWalkingPlayerEvent {
return OnUpdateWalkingPlayerEvent(moving, rotating, sprinting, sneaking, onGround, pos, rotation, phase.next())
return OnUpdateWalkingPlayerEvent(moving, rotating, position, rotation, phase.next())
}
fun apply(packet: PlayerPacketManager.Packet) {
cancel()
packet.moving?.let { moving ->
if (moving) packet.position?.let { this.position = it }
this.moving = moving
}
packet.rotating?.let { rotating ->
if (rotating) packet.rotation?.let { this.rotation = it }
this.rotating = rotating
}
this.cancelAll = packet.cancelAll
}
}

View File

@ -0,0 +1,113 @@
package org.kamiblue.client.manager.managers
import net.minecraft.client.entity.EntityPlayerSP
import net.minecraft.item.ItemStack
import net.minecraft.network.play.client.CPacketHeldItemChange
import net.minecraftforge.fml.common.gameevent.TickEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.manager.Manager
import org.kamiblue.client.mixin.extension.*
import org.kamiblue.client.module.AbstractModule
import org.kamiblue.client.util.TickTimer
import org.kamiblue.client.util.TimeoutFlag
import org.kamiblue.client.util.items.HotbarSlot
import org.kamiblue.client.util.threads.runSafe
import org.kamiblue.commons.extension.firstEntryOrNull
import org.kamiblue.commons.extension.firstKeyOrNull
import org.kamiblue.commons.extension.firstValue
import org.kamiblue.commons.extension.synchronized
import org.kamiblue.event.listener.listener
import java.util.*
object HotbarManager : Manager {
// <Module, <Slot, <Reset Time>
private val spoofingModule = TreeMap<AbstractModule, TimeoutFlag<Int>>(compareByDescending { it.modulePriority }).synchronized()
private val timer = TickTimer()
var serverSideHotbar = 0; private set
var swapTime = 0L; private set
val EntityPlayerSP.serverSideItem: ItemStack
get() = inventory.mainInventory[serverSideHotbar]
init {
listener<PacketEvent.Send>(-69420) {
if (it.packet is CPacketHeldItemChange && spoofingModule.isNotEmpty() && it.packet.slotId != serverSideHotbar) {
it.cancel()
}
}
listener<PacketEvent.PostSend>(-420) {
if (it.cancelled || it.packet !is CPacketHeldItemChange) return@listener
if (it.packet.slotId != serverSideHotbar) {
serverSideHotbar = it.packet.slotId
swapTime = System.currentTimeMillis()
}
}
listener<TickEvent.ClientTickEvent> {
if (it.phase != TickEvent.Phase.START || !timer.tick(250)) return@listener
val prevFirstKey = spoofingModule.firstKeyOrNull()
trimMap()
val newEntry = spoofingModule.firstEntryOrNull()
if (spoofingModule.isEmpty()) {
resetHotbarPacket()
} else if (prevFirstKey != null && newEntry != null && prevFirstKey != newEntry.key) {
sendHotbarPacket(newEntry.value.value)
}
}
}
fun AbstractModule.spoofHotbar(slot: HotbarSlot, timeout: Long = 250L) {
spoofHotbar(slot.hotbarSlot, timeout)
}
fun AbstractModule.spoofHotbar(slot: Int, timeout: Long = 250L) {
if (slot in 0..8) {
spoofingModule[this] = TimeoutFlag.relative(slot, timeout)
if (spoofingModule.firstKeyOrNull() == this) {
sendHotbarPacket(slot)
}
}
}
fun AbstractModule.resetHotbar() {
val prevFirstKey = spoofingModule.firstKeyOrNull()
spoofingModule.remove(this)
if (spoofingModule.isEmpty()) {
resetHotbarPacket()
} else if (prevFirstKey != null && prevFirstKey == this) {
spoofingModule.firstEntryOrNull()?.let { (_, flag) ->
sendHotbarPacket(flag.value)
}
}
}
private fun trimMap() {
while (spoofingModule.isNotEmpty() && spoofingModule.firstValue().timeout()) {
spoofingModule.pollFirstEntry()
}
}
private fun sendHotbarPacket(slot: Int) {
if (serverSideHotbar != slot) {
runSafe {
serverSideHotbar = slot
swapTime = System.currentTimeMillis()
mc.connection?.sendPacket(CPacketHeldItemChange(slot))
}
}
}
private fun resetHotbarPacket() {
runSafe {
sendHotbarPacket(playerController.currentPlayerItem)
}
}
}

View File

@ -1,7 +1,5 @@
package org.kamiblue.client.manager.managers
import net.minecraft.item.ItemStack
import net.minecraft.network.play.client.CPacketHeldItemChange
import net.minecraft.network.play.client.CPacketPlayer
import net.minecraft.util.math.Vec3d
import net.minecraftforge.fml.common.gameevent.TickEvent
@ -15,8 +13,6 @@ import org.kamiblue.client.mixin.client.accessor.*
import org.kamiblue.client.mixin.client.accessor.network.*
import org.kamiblue.client.mixin.extension.*
import org.kamiblue.client.module.AbstractModule
import org.kamiblue.client.util.TickTimer
import org.kamiblue.client.util.TimeUnit
import org.kamiblue.client.util.Wrapper
import org.kamiblue.client.util.math.Vec2f
import org.kamiblue.client.util.threads.safeListener
@ -26,7 +22,7 @@ import java.util.*
object PlayerPacketManager : Manager {
/** TreeMap for all packets to be sent, sorted by their callers' priority */
private val packetList = TreeMap<AbstractModule, PlayerPacket>(compareByDescending { it.modulePriority })
private val packetMap = TreeMap<AbstractModule, Packet>(compareByDescending { it.modulePriority })
var serverSidePosition: Vec3d = Vec3d.ZERO; private set
var prevServerSidePosition: Vec3d = Vec3d.ZERO; private set
@ -34,48 +30,26 @@ object PlayerPacketManager : Manager {
var serverSideRotation = Vec2f.ZERO; private set
var prevServerSideRotation = Vec2f.ZERO; private set
var clientSidePitch = Vec2f.ZERO; private set
var serverSideHotbar = 0; private set
var lastSwapTime = 0L; private set
private var spoofingHotbar = false
private var hotbarResetTimer = TickTimer(TimeUnit.SECONDS)
private var clientSidePitch = Vec2f.ZERO
init {
listener<OnUpdateWalkingPlayerEvent> {
if (it.phase != Phase.PERI) return@listener
if (packetList.isNotEmpty()) {
packetList.values.first().apply(it) // Apply the packet from the module that has the highest priority
packetList.clear()
}
}
listener<OnUpdateWalkingPlayerEvent>(Int.MIN_VALUE) {
if (it.phase != Phase.PERI || packetMap.isEmpty()) return@listener
listener<PacketEvent.Send>(-69420) {
if (it.packet is CPacketHeldItemChange && spoofingHotbar && it.packet.slotId != serverSideHotbar) {
if (hotbarResetTimer.tick(2L)) {
spoofingHotbar = false
} else {
it.cancel()
}
}
it.apply(packetMap.values.first())
packetMap.clear()
}
listener<PacketEvent.PostSend>(-6969) {
if (it.cancelled) return@listener
if (it.packet is CPacketPlayer) {
if (it.packet.moving) {
serverSidePosition = Vec3d(it.packet.x, it.packet.y, it.packet.z)
}
if (it.packet.rotating) {
serverSideRotation = Vec2f(it.packet.yaw, it.packet.pitch)
Wrapper.player?.let { player -> player.rotationYawHead = it.packet.yaw }
}
if (it.cancelled || it.packet !is CPacketPlayer) return@listener
if (it.packet.moving) {
serverSidePosition = Vec3d(it.packet.x, it.packet.y, it.packet.z)
}
if (it.packet is CPacketHeldItemChange) {
serverSideHotbar = it.packet.slotId
lastSwapTime = System.currentTimeMillis()
if (it.packet.rotating) {
serverSideRotation = Vec2f(it.packet.yaw, it.packet.pitch)
Wrapper.player?.let { player -> player.rotationYawHead = it.packet.yaw }
}
}
@ -88,111 +62,85 @@ object PlayerPacketManager : Manager {
listener<RenderEntityEvent.All> {
if (it.entity != Wrapper.player || it.entity.isRiding) return@listener
if (it.phase == Phase.PRE) {
with(it.entity) {
clientSidePitch = Vec2f(prevRotationPitch, rotationPitch)
prevRotationPitch = prevServerSideRotation.y
rotationPitch = serverSideRotation.y
when (it.phase) {
Phase.PRE -> {
with(it.entity) {
clientSidePitch = Vec2f(prevRotationPitch, rotationPitch)
prevRotationPitch = prevServerSideRotation.y
rotationPitch = serverSideRotation.y
}
}
}
if (it.phase == Phase.POST) {
with(it.entity) {
prevRotationPitch = clientSidePitch.x
rotationPitch = clientSidePitch.y
Phase.POST -> {
with(it.entity) {
prevRotationPitch = clientSidePitch.x
rotationPitch = clientSidePitch.y
}
}
else -> {
// Ignored
}
}
}
}
/**
* Adds a packet to the packet list
*
* @param packet Packet to be added
*/
fun addPacket(caller: AbstractModule, packet: PlayerPacket) {
if (packet.isEmpty()) return
packetList[caller] = packet
}
fun getHoldingItemStack(): ItemStack =
Wrapper.player?.inventory?.mainInventory?.get(serverSideHotbar) ?: ItemStack.EMPTY
fun spoofHotbar(slot: Int) {
Wrapper.minecraft.connection?.let {
if (serverSideHotbar != slot) {
serverSideHotbar = slot
it.sendPacket(CPacketHeldItemChange(slot))
spoofingHotbar = true
}
hotbarResetTimer.reset()
inline fun AbstractModule.sendPlayerPacket(block: Packet.Builder.() -> Unit) {
Packet.Builder().apply(block).build()?.let {
sendPlayerPacket(it)
}
}
fun resetHotbar() {
if (!spoofingHotbar) return
spoofingHotbar = false
Wrapper.minecraft.connection?.sendPacket(CPacketHeldItemChange(Wrapper.minecraft.playerController?.currentPlayerItem
?: 0))
fun AbstractModule.sendPlayerPacket(packet: Packet) {
packetMap[this] = packet
}
/**
* Used for PlayerPacketManager. All constructor parameters are optional.
* They are null by default. null values would not be used for modifying
* the packet
*/
class PlayerPacket(
var moving: Boolean? = null,
var rotating: Boolean? = null,
var sprinting: Boolean? = null,
var sneaking: Boolean? = null,
var onGround: Boolean? = null,
pos: Vec3d? = null,
rotation: Vec2f? = null
class Packet private constructor(
val moving: Boolean?,
val rotating: Boolean?,
val position: Vec3d?,
val rotation: Vec2f?,
val cancelAll: Boolean
) {
var pos: Vec3d? = pos
set(value) {
moving = true
field = value
class Builder {
private var position: Vec3d? = null
private var moving: Boolean? = null
private var rotation: Vec2f? = null
private var rotating: Boolean? = null
private var cancelAll = false
private var empty = true
fun move(position: Vec3d) {
this.position = position
this.moving = true
this.empty = false
}
var rotation: Vec2f? = rotation
set(value) {
rotating = true
field = value
fun rotate(rotation: Vec2f) {
this.rotation = rotation
this.rotating = true
this.empty = false
}
/**
* Checks whether this packet contains values
*
* @return True if all values in this packet is null
*/
fun isEmpty(): Boolean {
return moving == null
&& rotating == null
&& sprinting == null
&& sneaking == null
&& onGround == null
&& pos == null
&& rotation == null
}
fun cancelAll() {
this.cancelAll = true
this.empty = false
}
/**
* Apply this packet on an [event]
*
* @param event Event to apply on
*/
fun apply(event: OnUpdateWalkingPlayerEvent) {
if (this.isEmpty()) return
event.cancel()
this.moving?.let { event.moving = it }
this.rotating?.let { event.rotating = it }
this.sprinting?.let { event.sprinting = it }
this.sneaking?.let { event.sneaking = it }
this.onGround?.let { event.onGround = it }
this.pos?.let { event.pos = it }
this.rotation?.let { event.rotation = it }
}
fun cancelMove() {
this.position = null
this.moving = false
this.empty = false
}
fun cancelRotate() {
this.rotation = null
this.rotating = false
this.empty = false
}
fun build() =
if (!empty) Packet(moving, rotating, position, rotation, cancelAll) else null
}
}
}

View File

@ -11,7 +11,7 @@ import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.event.events.GuiEvent
import org.kamiblue.client.manager.managers.FriendManager
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.PlayerPacket
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.util.EntityUtils.isFakeOrSelf
@ -103,8 +103,9 @@ internal object AutoMend : Module(
player.inventory.currentItem = xpSlot
}
if (autoThrow && player.heldItemMainhand.item === Items.EXPERIENCE_BOTTLE) {
val packet = PlayerPacket(rotating = true, rotation = Vec2f(player.rotationYaw, 90.0f))
PlayerPacketManager.addPacket(AutoMend, packet)
sendPlayerPacket {
rotate(Vec2f(player.rotationYaw, 90.0f))
}
if (validServerSideRotation() && throwDelayTimer.tick(throwDelay.value.toLong())) {
playerController.processRightClick(player, world, EnumHand.MAIN_HAND)
}

View File

@ -8,7 +8,10 @@ import net.minecraftforge.fml.common.gameevent.InputEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.HotbarManager.resetHotbar
import org.kamiblue.client.manager.managers.HotbarManager.spoofHotbar
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.module.modules.combat.Surround.setting
@ -50,7 +53,7 @@ internal object AutoTrap : Module(
init {
onDisable {
PlayerPacketManager.resetHotbar()
resetHotbar()
}
safeListener<TickEvent.ClientTickEvent> {
@ -58,11 +61,13 @@ internal object AutoTrap : Module(
if (job.isActiveOrFalse) {
getObby()?.let {
PlayerPacketManager.spoofHotbar(it.hotbarSlot)
spoofHotbar(it)
} ?: return@safeListener
PlayerPacketManager.addPacket(AutoTrap, PlayerPacketManager.PlayerPacket(rotating = false))
sendPlayerPacket {
cancelRotate()
}
} else if (CombatManager.isOnTopPriority(AutoTrap)) {
PlayerPacketManager.resetHotbar()
resetHotbar()
}
}

View File

@ -16,6 +16,7 @@ import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.util.*
@ -225,7 +226,9 @@ internal object BedAura : Module(
}
private fun sendRotation() {
PlayerPacketManager.addPacket(this, PlayerPacketManager.PlayerPacket(rotating = true, rotation = lastRotation))
sendPlayerPacket {
rotate(lastRotation)
}
}
private fun SafeClientEvent.resetRotation() {

View File

@ -1,5 +1,6 @@
package org.kamiblue.client.module.modules.combat
import net.minecraft.client.entity.EntityPlayerSP
import net.minecraft.entity.item.EntityEnderCrystal
import net.minecraft.init.Items
import net.minecraft.init.MobEffects
@ -26,7 +27,12 @@ import org.kamiblue.client.event.events.OnUpdateWalkingPlayerEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.event.events.RunGameLoopEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.HotbarManager
import org.kamiblue.client.manager.managers.HotbarManager.resetHotbar
import org.kamiblue.client.manager.managers.HotbarManager.serverSideItem
import org.kamiblue.client.manager.managers.HotbarManager.spoofHotbar
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.mixin.extension.id
import org.kamiblue.client.mixin.extension.packetAction
import org.kamiblue.client.module.Category
@ -177,7 +183,7 @@ internal object CrystalAura : Module(
synchronized(packetList) {
packetList.clear()
}
PlayerPacketManager.resetHotbar()
resetHotbar()
}
listener<InputEvent.KeyInputEvent> {
@ -231,8 +237,9 @@ internal object CrystalAura : Module(
if (!CombatManager.isOnTopPriority(CrystalAura) || CombatSetting.pause) return@safeListener
if (it.phase == Phase.PRE && inactiveTicks <= 20 && lastLookAt != Vec3d.ZERO) {
val packet = PlayerPacketManager.PlayerPacket(rotating = true, rotation = getLastRotation())
PlayerPacketManager.addPacket(CrystalAura, packet)
sendPlayerPacket {
rotate(getLastRotation())
}
}
if (it.phase == Phase.POST) {
@ -258,8 +265,13 @@ internal object CrystalAura : Module(
}
if (it.phase == TickEvent.Phase.END) {
if (inactiveTicks > 5 || getHand() == EnumHand.OFF_HAND) PlayerPacketManager.resetHotbar()
if (inactiveTicks > 20) resetRotation()
if (getHand() == EnumHand.OFF_HAND) {
resetHotbar()
}
if (inactiveTicks > 20) {
resetHotbar()
resetRotation()
}
}
}
}
@ -292,23 +304,16 @@ internal object CrystalAura : Module(
private fun SafeClientEvent.place() {
getPlacingPos()?.let { pos ->
swapToCrystal()
val hand = getHand()
if (hand == null) {
if (autoSwap) {
player.hotbarSlots.firstItem(Items.END_CRYSTAL)?.let {
if (spoofHotbar) PlayerPacketManager.spoofHotbar(it.hotbarSlot)
else swapToSlot(it)
}
}
return
}
placeTimerMs.reset()
placeTimerTicks = 0
inactiveTicks = 0
lastLookAt = pos.toVec3d(0.5, placeOffset.toDouble(), 0.5)
if (hand == null) return
placeTimerMs.reset()
placeTimerTicks = 0
sendOrQueuePacket(getPlacePacket(pos, hand))
if (extraPlacePacket) sendOrQueuePacket(getPlacePacket(pos, hand))
if (placeSwing) sendOrQueuePacket(CPacketAnimation(hand))
@ -318,6 +323,28 @@ internal object CrystalAura : Module(
}
}
private fun SafeClientEvent.swapToCrystal() {
if (autoSwap && player.heldItemOffhand.item != Items.END_CRYSTAL) {
if (spoofHotbar) {
val slot = if (player.serverSideItem.item == Items.END_CRYSTAL) HotbarManager.serverSideHotbar
else player.getCrystalSlot()?.hotbarSlot
if (slot != null) {
spoofHotbar(slot, 1000L)
}
} else {
if (player.serverSideItem.item != Items.END_CRYSTAL) {
player.getCrystalSlot()?.let {
swapToSlot(it)
}
}
}
}
}
private fun EntityPlayerSP.getCrystalSlot() =
this.hotbarSlots.firstItem(Items.END_CRYSTAL)
private fun SafeClientEvent.getPlacePacket(pos: BlockPos, hand: EnumHand): CPacketPlayerTryUseItemOnBlock {
val side = getClosestVisibleSide(pos) ?: EnumFacing.UP
return CPacketPlayerTryUseItemOnBlock(pos, side, hand, 0.5f, placeOffset, 0.5f)
@ -363,12 +390,12 @@ internal object CrystalAura : Module(
private fun SafeClientEvent.preExplode(): Boolean {
if (antiWeakness && player.isPotionActive(MobEffects.WEAKNESS) && !isHoldingTool()) {
equipBestWeapon(allowTool = true)
PlayerPacketManager.resetHotbar()
resetHotbar()
return false
}
// Anticheat doesn't allow you attack right after changing item
if (System.currentTimeMillis() - PlayerPacketManager.lastSwapTime < swapDelay * 50) {
if (System.currentTimeMillis() - HotbarManager.swapTime < swapDelay * 50L) {
return false
}
@ -492,12 +519,9 @@ internal object CrystalAura : Module(
/* General */
private fun SafeClientEvent.getHand(): EnumHand? {
val serverSideItem = if (spoofHotbar) player.inventory.getStackInSlot(PlayerPacketManager.serverSideHotbar).item else null
return when (Items.END_CRYSTAL) {
player.heldItemOffhand.item -> EnumHand.OFF_HAND
player.heldItemMainhand.item -> EnumHand.MAIN_HAND
serverSideItem -> EnumHand.MAIN_HAND
player.serverSideItem.item -> EnumHand.MAIN_HAND
else -> null
}
}

View File

@ -13,7 +13,11 @@ import net.minecraftforge.fml.common.gameevent.TickEvent
import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.event.events.RenderWorldEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.HotbarManager.resetHotbar
import org.kamiblue.client.manager.managers.HotbarManager.serverSideItem
import org.kamiblue.client.manager.managers.HotbarManager.spoofHotbar
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.util.*
@ -61,7 +65,7 @@ internal object CrystalBasePlace : Module(
onDisable {
inactiveTicks = 0
placePacket = null
PlayerPacketManager.resetHotbar()
resetHotbar()
}
listener<RenderWorldEvent> {
@ -87,10 +91,10 @@ internal object CrystalBasePlace : Module(
placePacket?.let { packet ->
if (inactiveTicks > 1) {
if (!isHoldingObby) PlayerPacketManager.spoofHotbar(slot.hotbarSlot)
if (!isHoldingObby) spoofHotbar(slot.hotbarSlot)
player.swingArm(EnumHand.MAIN_HAND)
connection.sendPacket(packet)
PlayerPacketManager.resetHotbar()
resetHotbar()
placePacket = null
}
}
@ -99,8 +103,9 @@ internal object CrystalBasePlace : Module(
if (isActive()) {
rotationTo?.let { hitVec ->
val rotation = getRotationTo(hitVec)
PlayerPacketManager.addPacket(CrystalBasePlace, PlayerPacketManager.PlayerPacket(rotating = true, rotation = rotation))
sendPlayerPacket {
rotate(getRotationTo(hitVec))
}
}
} else {
rotationTo = null
@ -110,7 +115,7 @@ internal object CrystalBasePlace : Module(
private val SafeClientEvent.isHoldingObby
get() = isObby(player.heldItemMainhand)
|| isObby(player.inventory.getStackInSlot(PlayerPacketManager.serverSideHotbar))
|| isObby(player.serverSideItem)
private fun isObby(itemStack: ItemStack) = itemStack.item.block == Blocks.OBSIDIAN

View File

@ -6,10 +6,12 @@ import net.minecraft.util.EnumHand
import net.minecraft.util.math.AxisAlignedBB
import net.minecraft.util.math.BlockPos
import net.minecraftforge.fml.common.gameevent.TickEvent
import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.event.events.RenderOverlayEvent
import org.kamiblue.client.event.events.RenderWorldEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.HotbarManager.serverSideItem
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
@ -80,10 +82,10 @@ internal object CrystalESP : Module(
}
}
private fun checkHeldItem(packet: CPacketPlayerTryUseItemOnBlock) = packet.hand == EnumHand.MAIN_HAND
&& mc.player.inventory.getStackInSlot(PlayerPacketManager.serverSideHotbar).item == Items.END_CRYSTAL
private fun SafeClientEvent.checkHeldItem(packet: CPacketPlayerTryUseItemOnBlock) = packet.hand == EnumHand.MAIN_HAND
&& player.serverSideItem.item == Items.END_CRYSTAL
|| packet.hand == EnumHand.OFF_HAND
&& mc.player.heldItemOffhand.item == Items.END_CRYSTAL
&& player.heldItemOffhand.item == Items.END_CRYSTAL
init {
safeListener<TickEvent.ClientTickEvent> { event ->
@ -173,7 +175,7 @@ internal object CrystalESP : Module(
listener<RenderOverlayEvent> {
if (!showDamage.value && !showSelfDamage.value) return@listener
GlStateUtils.rescale(mc.displayWidth.toDouble(), mc.displayHeight.toDouble())
GlStateUtils.rescaleActual()
for ((pos, quad) in renderCrystalMap) {
glPushMatrix()

View File

@ -11,6 +11,7 @@ import net.minecraftforge.fml.common.gameevent.TickEvent
import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.util.EntityUtils.prevPosVector
@ -99,8 +100,9 @@ internal object HoleMiner : Module(
val center = pos.toVec3dCenter()
val rotation = getRotationTo(center)
val packet = PlayerPacketManager.PlayerPacket(rotating = true, rotation = rotation)
PlayerPacketManager.addPacket(this@HoleMiner, packet)
sendPlayerPacket {
rotate(rotation)
}
val diff = player.getPositionEyes(1.0f).subtract(center)
val normalizedVec = diff.normalize()

View File

@ -6,7 +6,9 @@ import net.minecraft.util.EnumHand
import net.minecraftforge.fml.common.gameevent.TickEvent
import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.HotbarManager
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.util.TickTimer
@ -80,7 +82,7 @@ internal object KillAura : Module(
if (player.getDistance(target) >= range) return@safeListener
if (player.scaledHealth > minSwapHealth && autoWeapon) equipBestWeapon(prefer)
if (weaponOnly && !player.heldItemMainhand.item.isWeapon) return@safeListener
if (swapDelay > 0 && System.currentTimeMillis() - PlayerPacketManager.lastSwapTime < swapDelay * 50L) return@safeListener
if (swapDelay > 0 && System.currentTimeMillis() - HotbarManager.swapTime < swapDelay * 50L) return@safeListener
inactiveTicks = 0
rotate(target)
@ -91,8 +93,9 @@ internal object KillAura : Module(
private fun SafeClientEvent.rotate(target: EntityLivingBase) {
when (rotationMode) {
RotationMode.SPOOF -> {
val rotation = getRotationToEntityClosest(target)
PlayerPacketManager.addPacket(this@KillAura, PlayerPacketManager.PlayerPacket(rotating = true, rotation = rotation))
sendPlayerPacket {
rotate(getRotationToEntityClosest(target))
}
}
RotationMode.VIEW_LOCK -> {
faceEntityClosest(target)

View File

@ -7,7 +7,9 @@ import net.minecraft.util.math.BlockPos
import net.minecraftforge.fml.common.gameevent.TickEvent
import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.manager.managers.CombatManager
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.HotbarManager.resetHotbar
import org.kamiblue.client.manager.managers.HotbarManager.spoofHotbar
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.module.modules.movement.Strafe
@ -17,6 +19,7 @@ import org.kamiblue.client.util.MovementUtils.centerPlayer
import org.kamiblue.client.util.MovementUtils.speed
import org.kamiblue.client.util.combat.SurroundUtils
import org.kamiblue.client.util.combat.SurroundUtils.checkHole
import org.kamiblue.client.util.items.HotbarSlot
import org.kamiblue.client.util.items.firstBlock
import org.kamiblue.client.util.items.hotbarSlots
import org.kamiblue.client.util.math.VectorUtils.toBlockPos
@ -58,7 +61,7 @@ internal object Surround : Module(
init {
onDisable {
PlayerPacketManager.resetHotbar()
resetHotbar()
holePos = null
}
@ -105,10 +108,12 @@ internal object Surround : Module(
if (!job.isActiveOrFalse) {
job = runSurround()
} else if (job.isActiveOrFalse) {
spoofHotbar()
PlayerPacketManager.addPacket(Surround, PlayerPacketManager.PlayerPacket(rotating = false))
spoofObby()
sendPlayerPacket {
cancelAll()
}
} else if (isEnabled && CombatManager.isOnTopPriority(Surround)) {
PlayerPacketManager.resetHotbar()
resetHotbar()
}
}
}
@ -135,11 +140,11 @@ internal object Surround : Module(
}
}
private fun SafeClientEvent.spoofHotbar() {
getObby()?.let { PlayerPacketManager.spoofHotbar(it) }
private fun SafeClientEvent.spoofObby() {
getObby()?.let { spoofHotbar(it) }
}
private fun SafeClientEvent.getObby(): Int? {
private fun SafeClientEvent.getObby(): HotbarSlot? {
val slots = player.hotbarSlots.firstBlock(Blocks.OBSIDIAN)
if (slots == null) { // Obsidian check
@ -150,7 +155,7 @@ internal object Surround : Module(
return null
}
return slots.hotbarSlot
return slots
}
private fun SafeClientEvent.canRun(): Boolean {
@ -161,7 +166,7 @@ internal object Surround : Module(
}
private fun SafeClientEvent.runSurround() = defaultScope.launch {
spoofHotbar()
spoofObby()
buildStructure(
player.flooredPosition,

View File

@ -32,7 +32,7 @@ import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.event.events.BlockBreakEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.event.events.RenderWorldEvent
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.process.AutoObsidianProcess
@ -196,8 +196,9 @@ internal object AutoObsidian : Module(
when (rotationMode) {
RotationMode.SPOOF -> {
val packet = PlayerPacketManager.PlayerPacket(rotating = true, rotation = rotation)
PlayerPacketManager.addPacket(this@AutoObsidian, packet)
sendPlayerPacket {
rotate(rotation)
}
}
RotationMode.VIEW_LOCK -> {
player.rotationYaw = rotation.x

View File

@ -10,6 +10,7 @@ import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.event.events.PlayerTravelEvent
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.mixin.extension.rotationPitch
import org.kamiblue.client.mixin.extension.tickLength
import org.kamiblue.client.mixin.extension.timer
@ -472,7 +473,8 @@ internal object ElytraFlight : Module(
private fun SafeClientEvent.spoofRotation() {
if (player.isSpectator || !elytraIsEquipped || elytraDurability <= 1 || !isFlying) return
val packet = PlayerPacketManager.PlayerPacket(rotating = true)
var cancelRotation = false
var rotation = Vec2f(player)
if (autoLanding) {
@ -483,15 +485,17 @@ internal object ElytraFlight : Module(
if (!isStandingStill) rotation = Vec2f(rotation.x, packetPitch)
/* Cancels rotation packets if player is not moving and not clicking */
val cancelRotation = isStandingStill && ((!mc.gameSettings.keyBindUseItem.isKeyDown && !mc.gameSettings.keyBindAttack.isKeyDown && blockInteract) || !blockInteract)
if (cancelRotation) {
packet.rotating = false
}
cancelRotation = isStandingStill && ((!mc.gameSettings.keyBindUseItem.isKeyDown && !mc.gameSettings.keyBindAttack.isKeyDown && blockInteract) || !blockInteract)
}
}
packet.rotation = rotation
PlayerPacketManager.addPacket(this@ElytraFlight, packet)
sendPlayerPacket {
if (cancelRotation) {
cancelRotate()
} else {
rotate(rotation)
}
}
}
init {

View File

@ -7,6 +7,7 @@ import org.kamiblue.client.event.events.OnUpdateWalkingPlayerEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.event.events.PlayerTravelEvent
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.module.Category
import org.kamiblue.client.module.Module
import org.kamiblue.client.util.MovementUtils
@ -89,7 +90,9 @@ internal object Flight : Module(
listener<OnUpdateWalkingPlayerEvent> {
if (mode != FlightMode.PACKET || it.phase != Phase.PRE) return@listener
PlayerPacketManager.addPacket(this, PlayerPacketManager.PlayerPacket(moving = false, rotating = false))
sendPlayerPacket {
cancelAll()
}
}
listener<PacketEvent.Receive> {

View File

@ -14,7 +14,11 @@ import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.event.events.OnUpdateWalkingPlayerEvent
import org.kamiblue.client.event.events.PacketEvent
import org.kamiblue.client.event.events.PlayerTravelEvent
import org.kamiblue.client.manager.managers.HotbarManager.resetHotbar
import org.kamiblue.client.manager.managers.HotbarManager.serverSideItem
import org.kamiblue.client.manager.managers.HotbarManager.spoofHotbar
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import org.kamiblue.client.mixin.client.entity.MixinEntity
import org.kamiblue.client.mixin.extension.syncCurrentPlayItem
import org.kamiblue.client.module.Category
@ -56,7 +60,7 @@ internal object Scaffold : Module(
private val delay by setting("Delay", 2, 1..10, 1)
private val maxRange by setting("Max Range", 1, 0..3, 1)
private var lastRotation = Vec2f.ZERO
private var lastHitVec: Vec3d? = null
private var placeInfo: PlaceInfo? = null
private var inactiveTicks = 69
@ -88,8 +92,8 @@ internal object Scaffold : Module(
}
}
private val isHoldingBlock: Boolean
get() = PlayerPacketManager.getHoldingItemStack().item is ItemBlock
private val SafeClientEvent.isHoldingBlock: Boolean
get() = player.serverSideItem.item is ItemBlock
private val SafeClientEvent.shouldTower: Boolean
get() = !player.onGround
@ -106,15 +110,18 @@ internal object Scaffold : Module(
}
placeInfo?.let {
lastRotation = getRotationTo(it.hitVec)
lastHitVec = it.hitVec
swapAndPlace(it)
}
if (inactiveTicks > 5) {
PlayerPacketManager.resetHotbar()
resetHotbar()
} else if (isHoldingBlock) {
val packet = PlayerPacketManager.PlayerPacket(rotating = true, rotation = lastRotation)
PlayerPacketManager.addPacket(this@Scaffold, packet)
lastHitVec?.let {
sendPlayerPacket {
rotate(getRotationTo(it))
}
}
}
}
}
@ -147,7 +154,7 @@ internal object Scaffold : Module(
private fun SafeClientEvent.swapAndPlace(placeInfo: PlaceInfo) {
getBlockSlot()?.let { slot ->
if (spoofHotbar) PlayerPacketManager.spoofHotbar(slot.hotbarSlot)
if (spoofHotbar) spoofHotbar(slot)
else swapToSlot(slot)
inactiveTicks = 0

View File

@ -0,0 +1,17 @@
package org.kamiblue.client.util
class TimeoutFlag<T> private constructor(
val value: T,
private val timeoutTime: Long
) {
fun timeout() =
System.currentTimeMillis() > timeoutTime
companion object {
fun <T> relative(value: T, timeout: Long) =
TimeoutFlag(value, System.currentTimeMillis() + timeout)
fun <T> absolute(value: T, timeout: Long) =
TimeoutFlag(value, timeout)
}
}

View File

@ -25,9 +25,6 @@ object Wrapper {
if (!KamiMod.ready) return
ShutdownEvent.post()
println("Shutting down: saving KAMI configuration")
saveAll()
println("Configuration saved.")
}
}

View File

@ -11,6 +11,7 @@ import net.minecraft.util.SoundCategory
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import org.kamiblue.client.event.SafeClientEvent
import org.kamiblue.client.manager.managers.HotbarManager.serverSideItem
import org.kamiblue.client.manager.managers.PlayerPacketManager
import org.kamiblue.client.util.math.RotationUtils.getRotationTo
import org.kamiblue.client.util.math.VectorUtils.toVec3dCenter
@ -274,7 +275,7 @@ fun SafeClientEvent.placeBlock(
connection.sendPacket(placeInfo.toPlacePacket(hand))
player.swingArm(hand)
val itemStack = PlayerPacketManager.getHoldingItemStack()
val itemStack = player.serverSideItem
val block = (itemStack.item as? ItemBlock?)?.block ?: return
val metaData = itemStack.metadata
val blockState = block.getStateForPlacement(world, placeInfo.pos, placeInfo.side, placeInfo.hitVecOffset.x.toFloat(), placeInfo.hitVecOffset.y.toFloat(), placeInfo.hitVecOffset.z.toFloat(), metaData, player, EnumHand.MAIN_HAND)