Skip to content

Commit

Permalink
Make the singleplayer F3 screen threadsafe by disallowing level access
Browse files Browse the repository at this point in the history
  • Loading branch information
2No2Name committed Jan 24, 2025
1 parent 4454d54 commit 3172931
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ confirming the issue without worldthreader.

## Fixes:

- Ticking time, weather and sleeping players order ensured by updating in overworld before updating in the other
dimension
- Using the server console accessed the overworld
- Non-world threads could incorrectly request exclusive world access during world tick
- Fix ticking time, weather and sleeping players order by updating them in the overworld before updating them in the
other dimension
- Fix non-world threads being able to request exclusive world access during world tick incorrectly
- Fix F3 debug screen unsafely accessing the server world in singleplayer by not showing that information
- Fix Server console unsafely accessing the overworld to get the spawn position by delaying the access

## Known issues:

Expand Down
7 changes: 6 additions & 1 deletion DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ needed.
- DimensionDataStorage is per-dimension in vanilla, but maps and some others are tied to overworld
- Crafter block scaling or locking a map in the nether or end takes exclusive world access
- Network connections have a non-threadsafe integer counter for tracking network statistics
- Currently still non-threadsafe in worldthreader, leading to possibly wrong packet counts being displayed
- Currently still non-threadsafe in worldthreader, leading to possibly wrong packet counts being displayed

## Vanilla issues fixed

- Fix F3 debug screen unsafely accessing the server world in singleplayer by not showing that information
- Fix Server console unsafely accessing the overworld to get the spawn position by delaying the access
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package no2.worldthreader.mixin.threading_compatibility;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import net.minecraft.client.server.IntegratedServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(DebugScreenOverlay.class)
public class DebugScreenOverlayMixin {

@Shadow
@Final
private Minecraft minecraft;

/**
* @author 2No2Name
* @reason That's not threadsafe. So don't do it.
*/
@Overwrite
@Nullable
private ServerLevel getServerLevel() {
return null;
}

/**
* @author 2No2Name
* @reason That's not threadsafe. So don't do it.
*/
@Overwrite
private Level getLevel() {
return this.minecraft.level;
}

@Redirect(
method = {"getGameInformation()Ljava/util/List;", "drawGameInformation(Lnet/minecraft/client/gui/GuiGraphics;)V"},
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/Minecraft;getSingleplayerServer()Lnet/minecraft/client/server/IntegratedServer;")
)
private IntegratedServer avoidOffthreadAccess(Minecraft instance) {
return null;
}
}
1 change: 1 addition & 0 deletions src/main/resources/worldthreader.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"threadsafe_scoreboard.teams.ServerScoreboardMixin"
],
"client": [
"threading_compatibility.DebugScreenOverlayMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down

0 comments on commit 3172931

Please sign in to comment.