Skip to content

Commit 4a6bd89

Browse files
committed
other breaking-related documentation
1 parent 9315d3f commit 4a6bd89

File tree

5 files changed

+71
-36
lines changed

5 files changed

+71
-36
lines changed

src/main/kotlin/com/lambda/interaction/request/breaking/BreakInfo.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ import net.minecraft.item.ItemStack
3737
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket
3838
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action
3939

40+
/**
41+
* A data class that holds all the information required to process and continue a break.
42+
*/
4043
data class BreakInfo(
4144
override var context: BreakContext,
4245
var type: BreakType,
@@ -140,16 +143,13 @@ data class BreakInfo(
140143
}
141144

142145
context(_: SafeContext)
143-
fun startBreakPacket() =
144-
breakPacket(Action.START_DESTROY_BLOCK)
146+
fun startBreakPacket() = breakPacket(Action.START_DESTROY_BLOCK)
145147

146148
context(_: SafeContext)
147-
fun stopBreakPacket() =
148-
breakPacket(Action.STOP_DESTROY_BLOCK)
149+
fun stopBreakPacket() = breakPacket(Action.STOP_DESTROY_BLOCK)
149150

150151
context(_: SafeContext)
151-
fun abortBreakPacket() =
152-
breakPacket(Action.ABORT_DESTROY_BLOCK)
152+
fun abortBreakPacket() = breakPacket(Action.ABORT_DESTROY_BLOCK)
153153

154154
context(safeContext: SafeContext)
155155
private fun breakPacket(action: Action) =

src/main/kotlin/com/lambda/interaction/request/breaking/BreakRequest.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,24 @@ import com.lambda.interaction.construction.context.BuildContext
2424
import com.lambda.interaction.request.LogContext
2525
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
2626
import com.lambda.interaction.request.Request
27+
import com.lambda.interaction.request.breaking.BreakRequest.Companion.breakRequest
2728
import com.lambda.threading.runSafe
2829
import com.lambda.util.BlockUtils.blockState
2930
import com.lambda.util.BlockUtils.isEmpty
3031
import net.minecraft.entity.ItemEntity
3132
import net.minecraft.util.math.BlockPos
3233

34+
/**
35+
* Contains the information necessary for initializing and continuing breaks within the [BreakManager].
36+
*
37+
* The callbacks can be used to keep track of the break progress.
38+
*
39+
* The class has a private constructor to force use of the cleaner [BreakRequestDsl] builder. This is
40+
* accessed through the [breakRequest] method.
41+
*
42+
* @param contexts A collection of [BreakContext]'s gathered from the [com.lambda.interaction.construction.simulation.BuildSimulator].
43+
* @param pendingInteractions A mutable, concurrent list to store the pending actions.
44+
*/
3345
data class BreakRequest private constructor(
3446
val contexts: Collection<BreakContext>,
3547
val pendingInteractions: MutableCollection<BuildContext>,

src/main/kotlin/com/lambda/interaction/request/breaking/BrokenBlockHandler.kt

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ import net.minecraft.entity.ItemEntity
4242
import net.minecraft.util.math.ChunkSectionPos
4343

4444
/**
45-
* This object is designed to handle blocks that have been broken client side, yet are awaiting
46-
* confirmation from the server, and / or an item drop.
45+
* Designed to handle blocks that are deemed broken, yet are awaiting
46+
* confirmation from the server, and/or an item drop.
4747
*
4848
* @see BreakManager
4949
*/
@@ -105,7 +105,7 @@ object BrokenBlockHandler : PostActionHandler<BreakInfo>() {
105105

106106
if (pending.breakConfig.breakConfirmation == BreakConfirmationMode.AwaitThenBreak
107107
|| (pending.type == BreakInfo.BreakType.Rebreak && !pending.breakConfig.rebreak)
108-
) {
108+
) {
109109
destroyBlock(pending)
110110
}
111111
pending.internalOnBreak()
@@ -121,52 +121,44 @@ object BrokenBlockHandler : PostActionHandler<BreakInfo>() {
121121

122122
listen<EntityEvent.Update>(priority = Int.MIN_VALUE) {
123123
if (it.entity !is ItemEntity) return@listen
124-
run {
124+
val pending =
125125
pendingActions.firstOrNull { info -> matchesBlockItem(info, it.entity) }
126126
?: rebreak?.let { info ->
127-
return@run if (matchesBlockItem(info, it.entity)) info
128-
else null
129-
}
130-
}?.let { pending ->
131-
pending.internalOnItemDrop(it.entity)
132-
if (pending.callbacksCompleted) {
133-
pending.stopPending()
134-
if (lastPosStarted == pending.context.blockPos) {
135-
RebreakHandler.offerRebreak(pending)
136-
}
127+
if (matchesBlockItem(info, it.entity)) info
128+
else return@listen
129+
} ?: return@listen
130+
131+
pending.internalOnItemDrop(it.entity)
132+
if (pending.callbacksCompleted) {
133+
pending.stopPending()
134+
if (lastPosStarted == pending.context.blockPos) {
135+
RebreakHandler.offerRebreak(pending)
137136
}
138-
return@listen
139137
}
140138
}
141139
}
142140

143141
/**
144-
* A modified version of the minecraft breakBlock method.
142+
* A modified version of the minecraft [net.minecraft.client.world.ClientWorld.breakBlock] method.
145143
*
146-
* Performs the actions required to display break particles, sounds, texture overlay, etc.
147-
* based on the users settings.
148-
*
149-
* @return if the blocks state was set or not.
150-
*
151-
* @see net.minecraft.client.world.ClientWorld.breakBlock
144+
* Performs the actions required to display breaking particles, sounds, texture overlay, etc.
145+
* based on the user's settings.
152146
*/
153-
fun SafeContext.destroyBlock(info: BreakInfo): Boolean {
147+
fun SafeContext.destroyBlock(info: BreakInfo) {
154148
val ctx = info.context
155149

156-
if (player.isBlockBreakingRestricted(world, ctx.blockPos, gamemode)) return false
157-
if (!player.mainHandStack.canMine(ctx.cachedState, world, ctx.blockPos, player)) return false
150+
if (player.isBlockBreakingRestricted(world, ctx.blockPos, gamemode)) return
151+
if (!player.mainHandStack.canMine(ctx.cachedState, world, ctx.blockPos, player)) return
158152

159153
val block = ctx.cachedState.block
160-
if (block is OperatorBlock && !player.isCreativeLevelTwoOp) return false
161-
if (ctx.cachedState.isEmpty) return false
154+
if (block is OperatorBlock && !player.isCreativeLevelTwoOp) return
155+
if (ctx.cachedState.isEmpty) return
162156

163157
block.onBreak(world, ctx.blockPos, ctx.cachedState, player)
164158
val fluidState = fluidState(ctx.blockPos)
165159
val setState = world.setBlockState(ctx.blockPos, fluidState.blockState, 11)
166160
if (setState) block.onBroken(world, ctx.blockPos, ctx.cachedState)
167161

168162
if (info.breakConfig.breakingTexture) info.setBreakingTextureStage(player, world, -1)
169-
170-
return setState
171163
}
172164
}

src/main/kotlin/com/lambda/interaction/request/breaking/RebreakHandler.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
2525
import com.lambda.interaction.construction.context.BreakContext
2626
import com.lambda.interaction.request.breaking.BreakManager.calcBreakDelta
2727
import com.lambda.interaction.request.breaking.BrokenBlockHandler.destroyBlock
28+
import com.lambda.interaction.request.breaking.RebreakHandler.rebreak
2829
import com.lambda.threading.runSafeAutomated
2930
import com.lambda.util.player.swingHand
3031
import net.minecraft.util.Hand
3132

33+
/**
34+
* Designed to track the latest primary-broken [BreakInfo] in order to exploit a flaw in Minecraft's code that allows
35+
* the user to break any block placed in said position using the progress from the previously broken block.
36+
*/
3237
object RebreakHandler {
3338
var rebreak: BreakInfo? = null
3439

@@ -47,6 +52,10 @@ object RebreakHandler {
4752
}
4853
}
4954

55+
/**
56+
* Tests to see if the [BreakInfo] can be accepted. If not, nothing happens. Otherwise,
57+
* the [rebreak] is set, and the [BreakRequest.onReBreakStart] callback is invoked.
58+
*/
5059
context(safeContext: SafeContext)
5160
fun offerRebreak(info: BreakInfo) {
5261
if (!info.rebreakable) return
@@ -63,6 +72,15 @@ object RebreakHandler {
6372
rebreak = null
6473
}
6574

75+
/**
76+
* [RebreakPotential.None] if it cannot be rebroken at all.
77+
*
78+
* [RebreakPotential.PartialProgress] if some progress would be added to the break.
79+
*
80+
* [RebreakPotential.Instant] if the block can be instantly rebroken.
81+
*
82+
* @return In what way this block can be rebroken.
83+
*/
6684
context(_: SafeContext)
6785
fun BreakInfo.getRebreakPotential() = request.runSafeAutomated {
6886
rebreak?.let { reBreak ->
@@ -81,6 +99,11 @@ object RebreakHandler {
8199
} ?: RebreakPotential.None
82100
}
83101

102+
/**
103+
* Updates the current [rebreak] with a fresh [BreakContext], and attempts to rebreak the block if possible.
104+
*
105+
* @return A [RebreakResult] to indicate how the update has been processed.
106+
*/
84107
context(_: SafeContext)
85108
fun handleUpdate(ctx: BreakContext, breakRequest: BreakRequest) = breakRequest.runSafeAutomated {
86109
val reBreak = this@RebreakHandler.rebreak ?: return@runSafeAutomated RebreakResult.Ignored

src/main/kotlin/com/lambda/interaction/request/breaking/SwapInfo.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import com.lambda.interaction.request.breaking.BreakInfo.BreakType.Secondary
2727
import com.lambda.interaction.request.breaking.BreakManager.calcBreakDelta
2828
import com.lambda.threading.runSafeAutomated
2929

30+
/**
31+
* A simple data class to store info about when the [BreakManager] should swap tool.
32+
*/
3033
data class SwapInfo(
3134
private val type: BreakInfo.BreakType,
3235
private val automated: Automated,
@@ -43,13 +46,18 @@ data class SwapInfo(
4346
companion object {
4447
val EMPTY = SwapInfo(Primary, AutomationConfig)
4548

49+
/**
50+
* Calculates the contents and returns a [SwapInfo].
51+
*
52+
*
53+
*/
4654
context(_: SafeContext)
4755
fun BreakInfo.getSwapInfo() = request.runSafeAutomated {
4856
val breakDelta = context.cachedState.calcBreakDelta(context.blockPos, swapStack)
4957

5058
val threshold = getBreakThreshold()
5159

52-
// Plus one as this is calculated before this ticks progress is calculated and the breakingTicks are incremented
60+
// Plus one as this is calculated before this ticks' progress is calculated and the breakingTicks are incremented
5361
val breakTicks = (if (rebreakPotential.isPossible()) RebreakHandler.rebreak?.breakingTicks
5462
?: throw IllegalStateException("Rebreak BreakInfo was null when rebreak was considered possible")
5563
else breakingTicks) + 1 - breakConfig.fudgeFactor

0 commit comments

Comments
 (0)