Skip to content

Commit 40f56ab

Browse files
committed
decouple fudge factor from double break to prevent desync when the difference between client and server ticks are close enough to cause a small but critical mismatch in breaking progress
1 parent f8371e3 commit 40f56ab

File tree

3 files changed

+30
-20
lines changed

3 files changed

+30
-20
lines changed

common/src/main/kotlin/com/lambda/config/groups/BreakSettings.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ class BreakSettings(
2828
priority: Priority = 0,
2929
vis: () -> Boolean = { true }
3030
) : BreakConfig(priority) {
31-
override val breakMode by c.setting("Break Mode", BreakMode.Packet) { vis() }
31+
override val breakMode by c.setting("Break Mode", BreakMode.Packet, visibility = vis)
3232
override val reBreak by c.setting("ReBreak", true, "Re-breaks blocks after they've been broken once", visibility = vis)
3333
override val unsafeCancels by c.setting("Unsafe Cancels", true, "Allows cancelling block breaking even if the server might continue breaking sever side, potentially causing unexpected state changes", visibility = vis)
34-
override val breakThreshold by c.setting("Break Threshold", 0.7f, 0.1f..1.0f, 0.02f, "The break amount at which the block is considered broken", visibility = vis)
34+
override val breakThreshold by c.setting("Break Threshold", 0.75f, 0.1f..1.0f, 0.01f, "The break amount at which the block is considered broken", visibility = vis)
3535
override val doubleBreak by c.setting("Double Break", true, "Allows breaking two blocks at once", visibility = vis)
36-
override val doubleBreakFudgeFactor by c.setting("Double Break Fudge Factor", 3, 0..3, 1, "The amount of ticks to give double, aka secondary breaks extra for the server to recognise the break") { doubleBreak && vis() }
36+
override val fudgeFactor by c.setting("Fudge Factor", 2, 0..5, 1, "The amount of ticks to give double, aka secondary breaks extra for the server to recognise the break", visibility = vis)
3737
override val breakDelay by c.setting("Break Delay", 0, 0..6, 1, "The delay between breaking blocks", " ticks", visibility = vis)
3838
override val breakStageMask by c.setting("Break Stage Mask", setOf(TickEvent.Pre, TickEvent.Input.Pre, TickEvent.Input.Post, TickEvent.Player.Post), "The sub-tick timing at which break actions can be performed", visibility = vis)
3939
override val swing by c.setting("Swing Mode", SwingMode.Constant, "The times at which to swing the players hand", visibility = vis)
@@ -48,7 +48,7 @@ class BreakSettings(
4848
override val breaksPerTick by c.setting("Breaks Per Tick", 5, 1..30, 1, "Maximum instant block breaks per tick", visibility = vis)
4949
override val suitableToolsOnly by c.setting("Suitable Tools Only", false, "Places a restriction to only use tools suitable for the given block", visibility = vis)
5050
override val avoidLiquids by c.setting("Avoid Liquids", true, "Avoids breaking blocks that would cause liquid to spill", visibility = vis)
51-
override val breakWeakBlocks by c.setting("Break Weak Blocks", false, "Break blocks that dont have structural integrity (e.g: grass)") { vis() }
51+
override val breakWeakBlocks by c.setting("Break Weak Blocks", false, "Break blocks that dont have structural integrity (e.g: grass)", visibility = vis)
5252
override val forceSilkTouch by c.setting("Force Silk Touch", false, "Force silk touch when breaking blocks", visibility = vis)
5353
override val forceFortunePickaxe by c.setting("Force Fortune Pickaxe", false, "Force fortune pickaxe when breaking blocks", visibility = vis)
5454
override val minFortuneLevel by c.setting("Min Fortune Level", 1, 1..3, 1, "The minimum fortune level to use") { vis() && forceFortunePickaxe }

common/src/main/kotlin/com/lambda/interaction/request/breaking/BreakConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ abstract class BreakConfig(
3131
abstract val unsafeCancels: Boolean
3232
abstract val breakThreshold: Float
3333
abstract val doubleBreak: Boolean
34-
abstract val doubleBreakFudgeFactor: Int
34+
abstract val fudgeFactor: Int
3535
abstract val breakDelay: Int
3636
abstract val breakStageMask: Set<Event>
3737
abstract val swing: SwingMode

common/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ import net.minecraft.entity.ItemEntity
5858
import net.minecraft.sound.SoundCategory
5959
import net.minecraft.util.Hand
6060
import net.minecraft.util.math.BlockPos
61+
import kotlin.math.ceil
62+
import kotlin.math.max
6163

6264
object BreakManager : RequestHandler<BreakRequest>(
6365
0,
@@ -494,6 +496,7 @@ object BreakManager : RequestHandler<BreakRequest>(
494496
* @see net.minecraft.client.network.ClientPlayerInteractionManager.updateBlockBreakingProgress
495497
*/
496498
private fun SafeContext.updateBreakProgress(info: BreakInfo): Boolean {
499+
val config = info.breakConfig
497500
info.updatedProgressThisTick = true
498501
val ctx = info.context
499502
val hitResult = ctx.result
@@ -503,13 +506,13 @@ object BreakManager : RequestHandler<BreakRequest>(
503506
onBlockBreak(info)
504507
return true
505508
}
506-
breakCooldown = info.breakConfig.breakDelay
509+
breakCooldown = config.breakDelay
507510
lastPosStarted = ctx.expectedPos
508511
onBlockBreak(info)
509512
info.startBreakPacket(world, interaction)
510-
val swing = info.breakConfig.swing
513+
val swing = config.swing
511514
if (swing.isEnabled()) {
512-
swingHand(info.breakConfig.swingType, Hand.MAIN_HAND)
515+
swingHand(config.swingType, Hand.MAIN_HAND)
513516
}
514517
return true
515518
}
@@ -541,9 +544,9 @@ object BreakManager : RequestHandler<BreakRequest>(
541544
info.internalOnCancel()
542545
return false
543546
}
544-
val swing = info.breakConfig.swing
547+
val swing = config.swing
545548
if (swing.isEnabled() && swing != BreakConfig.SwingMode.End) {
546-
swingHand(info.breakConfig.swingType, Hand.MAIN_HAND)
549+
swingHand(config.swingType, Hand.MAIN_HAND)
547550
}
548551
return true
549552
}
@@ -560,9 +563,16 @@ object BreakManager : RequestHandler<BreakRequest>(
560563
player,
561564
world,
562565
ctx.expectedPos
563-
) * if (info.isSecondary || info.isRedundant) {
564-
info.breakingTicks - info.breakConfig.doubleBreakFudgeFactor
565-
} else info.breakingTicks
566+
).let { breakDelta ->
567+
breakDelta * if (info.isSecondary || info.isRedundant) {
568+
info.breakingTicks - config.fudgeFactor
569+
} else {
570+
val serverBreakTicks = ceil(1.0 / breakDelta).toInt()
571+
val clientBreakTicks = ceil(config.breakThreshold / breakDelta).toInt()
572+
val diff = serverBreakTicks - clientBreakTicks
573+
info.breakingTicks - max(config.fudgeFactor - diff, 0)
574+
}
575+
}
566576

567577
val overBreakThreshold = progress >= info.getBreakThreshold()
568578

@@ -573,7 +583,7 @@ object BreakManager : RequestHandler<BreakRequest>(
573583
return true
574584
}
575585

576-
if (info.breakConfig.sounds) {
586+
if (config.sounds) {
577587
if (info.soundsCooldown % 4.0f == 0.0f) {
578588
val blockSoundGroup = blockState.soundGroup
579589
mc.soundManager.play(
@@ -590,26 +600,26 @@ object BreakManager : RequestHandler<BreakRequest>(
590600
info.soundsCooldown++
591601
}
592602

593-
if (info.breakConfig.particles) {
603+
if (config.particles) {
594604
mc.particleManager.addBlockBreakingParticles(ctx.expectedPos, hitResult.side)
595605
}
596606

597-
if (info.breakConfig.breakingTexture) {
607+
if (config.breakingTexture) {
598608
info.setBreakingTextureStage(player, world)
599609
}
600610

601-
val swing = info.breakConfig.swing
611+
val swing = config.swing
602612
if (overBreakThreshold) {
603613
if (info.isPrimary) {
604614
onBlockBreak(info)
605615
info.stopBreakPacket(world, interaction)
606616
} else {
607617
onBlockBreak(info)
608618
}
609-
if (swing.isEnabled() && swing != BreakConfig.SwingMode.Start) swingHand(info.breakConfig.swingType, Hand.MAIN_HAND)
610-
breakCooldown = info.breakConfig.breakDelay
619+
if (swing.isEnabled() && swing != BreakConfig.SwingMode.Start) swingHand(config.swingType, Hand.MAIN_HAND)
620+
breakCooldown = config.breakDelay
611621
} else {
612-
if (swing == BreakConfig.SwingMode.Constant) swingHand(info.breakConfig.swingType, Hand.MAIN_HAND)
622+
if (swing == BreakConfig.SwingMode.Constant) swingHand(config.swingType, Hand.MAIN_HAND)
613623
}
614624

615625
return true

0 commit comments

Comments
 (0)