Skip to content

Commit 8b41484

Browse files
committed
Implement debug environment range checks
1 parent 89bcac6 commit 8b41484

File tree

5 files changed

+49
-14
lines changed

5 files changed

+49
-14
lines changed

Common/src/main/kotlin/gay/object/hexdebug/adapter/DebugAdapter.kt

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
6161

6262
fun debugger(threadId: Int) = debuggers[threadId]
6363

64+
private fun inRangeDebugger(threadId: Int) =
65+
debugger(threadId)?.takeIf { it.debugEnv.isCasterInRange }
66+
6467
private fun packId(threadId: Int, reference: Int): Int =
6568
(threadId shl THREAD_ID_SHIFT) or (reference and REFERENCE_MASK)
6669

@@ -164,7 +167,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
164167
evaluate(threadId, env, SpellList.LList(listOf(iota)))
165168

166169
fun evaluate(threadId: Int, env: CastingEnvironment, list: SpellList) =
167-
debugger(threadId)?.let {
170+
inRangeDebugger(threadId)?.let {
168171
val result = it.evaluate(env, list) ?: return null
169172
if (result.startedEvaluating) {
170173
setEvaluatorState(threadId, EvaluatorItem.EvalState.MODIFIED)
@@ -174,7 +177,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
174177

175178
fun resetEvaluator(threadId: Int) {
176179
setEvaluatorState(threadId, EvaluatorItem.EvalState.DEFAULT)
177-
if (debugger(threadId)?.resetEvaluator() == true) {
180+
if (inRangeDebugger(threadId)?.resetEvaluator() == true) {
178181
sendStoppedEvent(threadId, StopReason.STEP)
179182
}
180183
}
@@ -262,9 +265,9 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
262265

263266
private fun resumeAllExcept(threadId: Int) {
264267
for (index in allThreadIds) {
265-
val debugger = debugger(index)
266-
if (debugger != null && index != threadId) {
267-
handleDebuggerStep(threadId, debugger.executeUntilStopped())
268+
if (index == threadId) continue
269+
inRangeDebugger(index)?.let {
270+
handleDebuggerStep(threadId, it.executeUntilStopped())
268271
}
269272
}
270273
}
@@ -348,7 +351,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
348351
// stepping
349352

350353
override fun next(args: NextArguments): CompletableFuture<Void> {
351-
debugger(args.threadId)?.let {
354+
inRangeDebugger(args.threadId)?.let {
352355
handleDebuggerStep(args.threadId, it.executeUntilStopped(RequestStepType.OVER))
353356
}
354357
// HACK: vscode doesn't support single-thread execution
@@ -362,7 +365,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
362365
}
363366

364367
override fun continue_(args: ContinueArguments): CompletableFuture<ContinueResponse> {
365-
debugger(args.threadId)?.let {
368+
inRangeDebugger(args.threadId)?.let {
366369
handleDebuggerStep(args.threadId, it.executeUntilStopped())
367370
}
368371
val continueAllThreads = args.singleThread == false
@@ -375,7 +378,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
375378
}
376379

377380
override fun stepIn(args: StepInArguments): CompletableFuture<Void> {
378-
debugger(args.threadId)?.let {
381+
inRangeDebugger(args.threadId)?.let {
379382
handleDebuggerStep(args.threadId, it.executeOnce())
380383
}
381384
if (args.singleThread == false) {
@@ -385,7 +388,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
385388
}
386389

387390
override fun stepOut(args: StepOutArguments): CompletableFuture<Void> {
388-
debugger(args.threadId)?.let {
391+
inRangeDebugger(args.threadId)?.let {
389392
handleDebuggerStep(args.threadId, it.executeUntilStopped(RequestStepType.OUT))
390393
}
391394
if (args.singleThread == false) {
@@ -395,7 +398,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
395398
}
396399

397400
override fun pause(args: PauseArguments): CompletableFuture<Void> {
398-
debugger(args.threadId)?.let {
401+
inRangeDebugger(args.threadId)?.let {
399402
if (it.state == DebuggerState.RUNNING) {
400403
it.debugEnv.pause()
401404
}
@@ -404,6 +407,13 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
404407
}
405408

406409
override fun restart(args: RestartArguments?): CompletableFuture<Void> {
410+
// hack
411+
for (debugger in debuggers.values) {
412+
if (!debugger.debugEnv.isCasterInRange) {
413+
return futureOf()
414+
}
415+
}
416+
407417
val envs = debuggers.map { (threadId, debugger) -> threadId to debugger.debugEnv }
408418

409419
debuggers.clear()
@@ -425,7 +435,10 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
425435
}
426436

427437
override fun terminateThreads(args: TerminateThreadsArguments): CompletableFuture<Void> {
428-
for (threadId in args.threadIds) {
438+
val toRemove = args.threadIds.filter { inRangeDebugger(it) != null }
439+
if (toRemove.isEmpty()) return futureOf()
440+
441+
for (threadId in toRemove) {
429442
remoteProxy.thread(ThreadEventArguments().also {
430443
it.reason = ThreadEventArgumentsReason.EXITED
431444
it.threadId = threadId
@@ -434,7 +447,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
434447
}
435448

436449
MsgDebuggerStateS2C(
437-
args.threadIds.associateWith {
450+
toRemove.associateWith {
438451
DebuggerItem.DebugState.NOT_DEBUGGING
439452
}
440453
).sendToPlayer(player)
@@ -448,7 +461,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
448461
}
449462
closeEvaluator(null)
450463
} else {
451-
for (threadId in args.threadIds) {
464+
for (threadId in toRemove) {
452465
closeEvaluator(threadId)
453466
}
454467
}

Common/src/main/kotlin/gay/object/hexdebug/items/DebuggerItem.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,14 @@ class DebuggerItem(
7575
val debugAdapter = DebugAdapterManager[player]
7676
?: return InteractionResultHolder.fail(stack)
7777

78-
if (debugAdapter.isDebugging(threadId)) {
78+
val debugger = debugAdapter.debugger(threadId)
79+
if (debugger != null) {
80+
if (!debugger.debugEnv.isCasterInRange) {
81+
return InteractionResultHolder.fail(stack)
82+
}
83+
84+
// TODO: implement pause?
85+
7986
// step the ongoing debug session
8087
debugAdapter.apply {
8188
when (getStepMode(stack)) {

Common/src/main/kotlin/gay/object/hexdebug/items/EvaluatorItem.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class EvaluatorItem(
4646
return InteractionResultHolder.fail(itemStack)
4747
}
4848

49+
if (!debugger.debugEnv.isCasterInRange) {
50+
return InteractionResultHolder.fail(itemStack)
51+
}
52+
4953
if (debugger.state != DebuggerState.PAUSED) {
5054
player.displayClientMessage("text.hexdebug.not_paused".asTranslatedComponent(threadId), true)
5155
return InteractionResultHolder.fail(itemStack)

Core/src/main/java/gay/object/hexdebug/core/api/debugging/DebugEnvironment.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ public abstract boolean resume(
5858
*/
5959
public abstract boolean restart(int threadId);
6060

61+
/**
62+
* For in-world debugees, returns whether the caster is close enough to the debuggee to allow
63+
* debug-related actions to be performed (eg. pause, step, restart).
64+
*/
65+
public abstract boolean isCasterInRange();
66+
6167
public void printDebugMessage(@NotNull Component message) {
6268
printDebugMessage(message, DebugOutputCategory.STDOUT, true);
6369
}

Core/src/main/java/gay/object/hexdebug/core/api/debugging/SynchronousDebugEnv.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public boolean restart(int threadId) {
5454
}
5555
}
5656

57+
@Override
58+
public boolean isCasterInRange() {
59+
return true;
60+
}
61+
5762
public void start(@Nullable Integer threadId)
5863
throws IllegalDebugSessionException, IllegalDebugThreadException
5964
{

0 commit comments

Comments
 (0)