Skip to content

Commit d46257d

Browse files
wagyourtailxppleEarthcomputer
authored
Add cfps command (#726)
* Add cfps command * what I'm thinking * dont actually need to change this part * unlimited first * simplify mixins * reverse order * cut off values * add getter, fix common refresh rate list * mojang sorts them anyway -_- * make translation keys same as xpple * Update src/main/java/net/earthcomputer/clientcommands/mixin/commands/fps/MinecraftMixin.java Co-authored-by: Joseph Burton <[email protected]> * fix import * Update src/main/java/net/earthcomputer/clientcommands/command/FramerateCommand.java Co-authored-by: Frederik van der Els <[email protected]> * 2 values of monitors I actually have * don't chop common refreshrates * fix translation keys * Update src/main/resources/assets/clientcommands/lang/en_us.json Co-authored-by: Frederik van der Els <[email protected]> --------- Co-authored-by: Frederik van der Els <[email protected]> Co-authored-by: Joseph Burton <[email protected]> Co-authored-by: Frederik van der Els <[email protected]>
1 parent bc4008c commit d46257d

File tree

7 files changed

+114
-0
lines changed

7 files changed

+114
-0
lines changed

src/main/java/net/earthcomputer/clientcommands/ClientCommands.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public static void registerCommands(CommandDispatcher<FabricClientCommandSource>
151151
FindItemCommand.register(dispatcher, context);
152152
FishCommand.register(dispatcher, context);
153153
FovCommand.register(dispatcher);
154+
FramerateCommand.register(dispatcher);
154155
GammaCommand.register(dispatcher);
155156
GetDataCommand.register(dispatcher);
156157
GhostBlockCommand.register(dispatcher, context);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package net.earthcomputer.clientcommands.command;
2+
3+
import com.mojang.brigadier.CommandDispatcher;
4+
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
5+
import net.minecraft.client.Minecraft;
6+
import net.minecraft.network.chat.Component;
7+
8+
import static com.mojang.brigadier.arguments.IntegerArgumentType.*;
9+
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*;
10+
11+
public class FramerateCommand {
12+
private static final int[] COMMON_REFRESH_RATES = new int[] {
13+
30, 45, 60, 75, 90, 100, 120, 144, 165, 180, 240, 300, 360, 420, 480, 540, 600
14+
};
15+
16+
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
17+
dispatcher.register(literal("cfps")
18+
.executes(ctx -> getMaxFps(ctx.getSource()))
19+
.then(literal("unlimited")
20+
.executes(ctx -> maxFps(ctx.getSource(), Integer.MAX_VALUE)))
21+
.then(argument("maxfps", integer())
22+
.suggests((context, builder) -> {
23+
int maxFps = getDisplayMaxFramerate();
24+
for (int refreshRate : COMMON_REFRESH_RATES) {
25+
if (refreshRate > maxFps) {
26+
break;
27+
}
28+
builder.suggest(refreshRate);
29+
}
30+
return builder.buildFuture();
31+
})
32+
.executes(ctx -> maxFps(ctx.getSource(), getInteger(ctx, "maxfps")))
33+
)
34+
);
35+
36+
}
37+
38+
private static int getMaxFps(FabricClientCommandSource source) {
39+
int framerateLimit = source.getClient().getFramerateLimitTracker().getFramerateLimit();
40+
if (framerateLimit < Integer.MAX_VALUE) {
41+
source.sendFeedback(Component.translatable("commands.cfps.getMaxFps", framerateLimit));
42+
} else {
43+
source.sendFeedback(Component.translatable("commands.cfps.getMaxFps.unlimited"));
44+
}
45+
return framerateLimit;
46+
}
47+
48+
private static int maxFps(FabricClientCommandSource source, int maxFps) {
49+
source.getClient().getFramerateLimitTracker().setFramerateLimit(maxFps);
50+
if (maxFps == Integer.MAX_VALUE) {
51+
source.sendFeedback(Component.translatable("commands.cfps.setMaxFps.unlimited"));
52+
} else {
53+
source.sendFeedback(Component.translatable("commands.cfps.setMaxFps", maxFps));
54+
}
55+
return maxFps;
56+
}
57+
58+
private static int getDisplayMaxFramerate() {
59+
return Minecraft.getInstance().virtualScreen.screenManager.monitors.values().stream()
60+
.mapToInt(monitor -> monitor.getCurrentMode().getRefreshRate())
61+
.max().orElseThrow();
62+
}
63+
64+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package net.earthcomputer.clientcommands.mixin.commands.fps;
2+
3+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4+
import net.minecraft.client.Minecraft;
5+
import net.minecraft.client.Options;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.injection.At;
8+
9+
@Mixin(Minecraft.class)
10+
public class MinecraftMixin {
11+
12+
@ModifyExpressionValue(method = "runTick", at = @At(value = "CONSTANT", args = "intValue=" + Options.UNLIMITED_FRAMERATE_CUTOFF))
13+
private int fixMaxFps(int fps) {
14+
return Integer.MAX_VALUE;
15+
}
16+
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.earthcomputer.clientcommands.mixin.commands.fps;
2+
3+
import net.minecraft.client.Options;
4+
import org.spongepowered.asm.mixin.Mixin;
5+
import org.spongepowered.asm.mixin.injection.At;
6+
import org.spongepowered.asm.mixin.injection.ModifyArg;
7+
8+
@Mixin(Options.class)
9+
public class OptionsMixin {
10+
11+
@ModifyArg(method = "lambda$new$8", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/FramerateLimitTracker;setFramerateLimit(I)V"))
12+
private static int fixMaxFpsSet(int maxFps) {
13+
if (maxFps == Options.UNLIMITED_FRAMERATE_CUTOFF) {
14+
return Integer.MAX_VALUE;
15+
}
16+
return maxFps;
17+
}
18+
19+
20+
}

src/main/resources/assets/clientcommands/lang/en_us.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@
129129

130130
"commands.cfov.success": "Set FOV to %s",
131131

132+
"commands.cfps.getMaxFps": "Max FPS is %s",
133+
"commands.cfps.getMaxFps.unlimited": "Max FPS is unlimited",
134+
"commands.cfps.setMaxFps": "Set max FPS to %s",
135+
"commands.cfps.setMaxFps.unlimited": "Set max FPS to unlimited",
136+
132137
"commands.cfunction.limitReached": "Command limit (%s) reached",
133138
"commands.cfunction.success": "Ran %s commands from function %s",
134139

src/main/resources/clientcommands.aw

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ accessible method net/minecraft/world/level/block/ShulkerBoxBlock canOpen (Lnet/
1717
# cfish
1818
accessible method net/minecraft/world/entity/projectile/FishingHook canHitEntity (Lnet/minecraft/world/entity/Entity;)Z
1919

20+
# cfps
21+
accessible field net/minecraft/client/Minecraft virtualScreen Lnet/minecraft/client/renderer/VirtualScreen;
22+
accessible field net/minecraft/client/renderer/VirtualScreen screenManager Lcom/mojang/blaze3d/platform/ScreenManager;
23+
accessible field com/mojang/blaze3d/platform/ScreenManager monitors Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;
24+
2025
# cgive
2126
accessible method net/minecraft/world/entity/player/Inventory addResource (ILnet/minecraft/world/item/ItemStack;)I
2227
accessible method net/minecraft/world/entity/player/Inventory hasRemainingSpaceForItem (Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Z

src/main/resources/mixins.clientcommands.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
"commands.alias.ClientSuggestionProviderMixin",
6969
"commands.enchant.MultiPlayerGameModeMixin",
7070
"commands.findblock.ClientLevelMixin",
71+
"commands.fps.MinecraftMixin",
72+
"commands.fps.OptionsMixin",
7173
"commands.generic.CommandSuggestionsMixin",
7274
"commands.glow.LivingEntityRenderStateMixin",
7375
"commands.reply.ClientPacketListenerMixin",

0 commit comments

Comments
 (0)