feat: added gamemode checks, Editor now only works in Creative mode

Signed-off-by: moonleay <contact@moonleay.net>
moonleay 2024-04-28 03:29:49 +02:00
parent acd318c5f1
commit 4abb372805
Signed by: moonleay
GPG key ID: 82667543CCD715FB
9 changed files with 65 additions and 20 deletions

@ -79,6 +79,8 @@ object ClientEditor {
ChatUtil.showToastToSelf("Gimble is disabled", "You cannot change modes", MinecraftClient.getInstance()) ChatUtil.showToastToSelf("Gimble is disabled", "You cannot change modes", MinecraftClient.getInstance())
return return
} }
if (!MinecraftClient.getInstance().player!!.isCreative)
return
CURRENT_MODE = mode CURRENT_MODE = mode
this.onUpdated() this.onUpdated()
@ -92,6 +94,9 @@ object ClientEditor {
ChatUtil.showToastToSelf("Gimble is disabled", "You cannot change modifiers", MinecraftClient.getInstance()) ChatUtil.showToastToSelf("Gimble is disabled", "You cannot change modifiers", MinecraftClient.getInstance())
return return
} }
if (!MinecraftClient.getInstance().player!!.isCreative)
return
if (CURRENT_MODE.incompatibleModifiers.contains(mod)){ if (CURRENT_MODE.incompatibleModifiers.contains(mod)){
if (TEMP_DISABLED_MODIFIERS.contains(mod)) if (TEMP_DISABLED_MODIFIERS.contains(mod))
TEMP_DISABLED_MODIFIERS.remove(mod) TEMP_DISABLED_MODIFIERS.remove(mod)
@ -166,7 +171,7 @@ object ClientEditor {
* */ * */
fun getModeDisplayText(): Text { fun getModeDisplayText(): Text {
val displayText = StringBuilder(CURRENT_MODE.displayName) val displayText = StringBuilder(CURRENT_MODE.displayName)
if (CURRENT_MODE_MODIFIER.isNotEmpty() && this.isAllowed()) { if (CURRENT_MODE_MODIFIER.isNotEmpty() && this.isAllowed() && MinecraftClient.getInstance().player?.isCreative == true) {
displayText.append(" [") displayText.append(" [")
for (i in CURRENT_MODE_MODIFIER.indices) { for (i in CURRENT_MODE_MODIFIER.indices) {
displayText.append(CURRENT_MODE_MODIFIER[i].displayName) displayText.append(CURRENT_MODE_MODIFIER[i].displayName)
@ -175,8 +180,9 @@ object ClientEditor {
} }
} }
displayText.append("]") displayText.append("]")
} else if (!this.isAllowed()) { } else if (!this.isAllowed() || !MinecraftClient.getInstance().player?.isCreative!!) {
displayText.append(" [DISABLED]") displayText.clear()
displayText.append("[GIMBLE DISABLED]")
} }
return Text.of(displayText.toString()) return Text.of(displayText.toString())
} }

@ -1,8 +1,10 @@
package net.moonleay.gimble.mixin; package net.moonleay.gimble.mixin;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.moonleay.gimble.client.editor.ClientEditor; import net.moonleay.gimble.client.editor.ClientEditor;
import net.moonleay.gimble.editor.state.mode.Capability; import net.moonleay.gimble.editor.state.mode.Capability;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -10,14 +12,20 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Objects;
@Mixin(MinecraftClient.class) @Mixin(MinecraftClient.class)
public abstract class BulldozerMixin { public abstract class BulldozerMixin {
@Shadow protected int attackCooldown; @Shadow protected int attackCooldown;
@Shadow
@Nullable
public ClientPlayerEntity player;
@Inject(method = "doAttack", at = @At(value = "HEAD")) @Inject(method = "doAttack", at = @At(value = "HEAD"))
private void func(CallbackInfoReturnable<Boolean> cir) { private void func(CallbackInfoReturnable<Boolean> cir) {
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER)) { if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.player).isCreative()) {
return; return;
} }
this.attackCooldown = 0; this.attackCooldown = 0;
@ -25,7 +33,7 @@ public abstract class BulldozerMixin {
@Inject(method = "handleBlockBreaking", at = @At(value = "HEAD")) @Inject(method = "handleBlockBreaking", at = @At(value = "HEAD"))
private void func2(boolean breaking, CallbackInfo ci) { private void func2(boolean breaking, CallbackInfo ci) {
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !breaking) { if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !breaking || !Objects.requireNonNull(this.player).isCreative()) {
return; return;
} }
this.attackCooldown = 0; this.attackCooldown = 0;

@ -1,24 +1,32 @@
package net.moonleay.gimble.mixin; package net.moonleay.gimble.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.moonleay.gimble.client.editor.ClientEditor; import net.moonleay.gimble.client.editor.ClientEditor;
import net.moonleay.gimble.editor.state.mode.Capability; import net.moonleay.gimble.editor.state.mode.Capability;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Objects;
@Mixin(ClientPlayerInteractionManager.class) @Mixin(ClientPlayerInteractionManager.class)
public class BulldozerMixin2 { public class BulldozerMixin2 {
@Shadow private int blockBreakingCooldown; @Shadow private int blockBreakingCooldown;
@Shadow
@Final
private MinecraftClient client;
@Inject(method = "updateBlockBreakingProgress", at = @At("HEAD")) @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD"))
private void func(BlockPos pos, Direction direction, CallbackInfoReturnable<Boolean> cir) { private void func(BlockPos pos, Direction direction, CallbackInfoReturnable<Boolean> cir) {
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER)) { if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.client.player).isCreative()) {
return; return;
} }
this.blockBreakingCooldown = 0; this.blockBreakingCooldown = 0;

@ -17,9 +17,11 @@ public class ForcePlaceMixin {
@Inject(method = "canPlace", at = @At("HEAD"), cancellable = true) @Inject(method = "canPlace", at = @At("HEAD"), cancellable = true)
private void func(ItemPlacementContext context, BlockState state, CallbackInfoReturnable<Boolean> cir) { private void func(ItemPlacementContext context, BlockState state, CallbackInfoReturnable<Boolean> cir) {
if (context.getPlayer() == null) { if (context.getPlayer() == null)
return; return;
} if (!context.getPlayer().isCreative())
return;
UUID id = context.getPlayer().getGameProfile().getId(); UUID id = context.getPlayer().getGameProfile().getId();
if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.FORCE_PLACE)) { if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.FORCE_PLACE)) {

@ -18,9 +18,10 @@ public class NoBlockUpdatesMixin {
@Inject(method = "place(Lnet/minecraft/item/ItemPlacementContext;Lnet/minecraft/block/BlockState;)Z", at = @At("HEAD"), cancellable = true) @Inject(method = "place(Lnet/minecraft/item/ItemPlacementContext;Lnet/minecraft/block/BlockState;)Z", at = @At("HEAD"), cancellable = true)
private void func(ItemPlacementContext context, BlockState state, CallbackInfoReturnable<Boolean> cir) { private void func(ItemPlacementContext context, BlockState state, CallbackInfoReturnable<Boolean> cir) {
if (context.getPlayer() == null) { if (context.getPlayer() == null)
return;
if (!context.getPlayer().isCreative())
return; return;
}
UUID id = context.getPlayer().getGameProfile().getId(); UUID id = context.getPlayer().getGameProfile().getId();
if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.NO_UPDATES)) { if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.NO_UPDATES)) {

@ -1,5 +1,6 @@
package net.moonleay.gimble.mixin; package net.moonleay.gimble.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera; import net.minecraft.client.render.Camera;
import net.moonleay.gimble.client.editor.ClientEditor; import net.moonleay.gimble.client.editor.ClientEditor;
import net.moonleay.gimble.editor.state.mode.Capability; import net.moonleay.gimble.editor.state.mode.Capability;
@ -13,7 +14,7 @@ public class NoClipCameraFixMixin {
@Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true)
private void fixCameraInNoClip(double desiredCameraDistance, CallbackInfoReturnable<Double> cir) { private void fixCameraInNoClip(double desiredCameraDistance, CallbackInfoReturnable<Double> cir) {
if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP)) { if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP) || (!(MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().player.isCreative()))) {
return; return;
} }
cir.setReturnValue(desiredCameraDistance); cir.setReturnValue(desiredCameraDistance);

@ -23,6 +23,9 @@ public abstract class NoClipMixin extends LivingEntity {
@Shadow public abstract PlayerAbilities getAbilities(); @Shadow public abstract PlayerAbilities getAbilities();
@Shadow
public abstract boolean isCreative();
protected NoClipMixin(EntityType<? extends LivingEntity> entityType, World world) { protected NoClipMixin(EntityType<? extends LivingEntity> entityType, World world) {
super(entityType, world); super(entityType, world);
} // Server side } // Server side
@ -31,6 +34,8 @@ public abstract class NoClipMixin extends LivingEntity {
@Inject(method = "tick", at = @At(value = "FIELD", @Inject(method = "tick", at = @At(value = "FIELD",
target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z", shift = At.Shift.AFTER) target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z", shift = At.Shift.AFTER)
) private void enoClip(CallbackInfo ci) { ) private void enoClip(CallbackInfo ci) {
if (!this.isCreative())
return;
UUID uuid = this.getGameProfile().getId(); UUID uuid = this.getGameProfile().getId();
if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) { if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) {

@ -1,6 +1,7 @@
package net.moonleay.gimble.mixin; package net.moonleay.gimble.mixin;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.GameOptions;
import net.moonleay.gimble.client.editor.ClientEditor; import net.moonleay.gimble.client.editor.ClientEditor;
import net.moonleay.gimble.editor.state.mode.Capability; import net.moonleay.gimble.editor.state.mode.Capability;
@ -19,28 +20,38 @@ public class NormalModeMixin {
@Nullable @Nullable
public GameOptions options; public GameOptions options;
@Shadow
@Nullable
public ClientPlayerEntity player;
@Inject(method = "openPauseMenu", at = @At("HEAD"), cancellable = true) @Inject(method = "openPauseMenu", at = @At("HEAD"), cancellable = true)
private void setNormalMode(boolean pause, CallbackInfo ci) { private void setNormalMode(boolean pause, CallbackInfo ci) {
if (ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) { if (ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) {
assert this.player != null;
if (this.player.isCreative()) {
// Set the editor mode to normal // Set the editor mode to normal
ClientEditor.INSTANCE.setMode(Mode.NORMAL); ClientEditor.INSTANCE.setMode(Mode.NORMAL);
ci.cancel(); ci.cancel();
} }
} }
}
@Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isUsingItem()Z"), cancellable = true) @Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isUsingItem()Z"), cancellable = true)
private void blockWorldManipulation(CallbackInfo ci) { private void blockWorldManipulation(CallbackInfo ci) {
// This could be replaced by net.minecraft.world.GameMode#isBlockBreakingRestricted // This could be replaced by net.minecraft.world.GameMode#isBlockBreakingRestricted
if (!ClientEditor.INSTANCE.shouldClient(Capability.CAN_INTERACT)) { if (!ClientEditor.INSTANCE.shouldClient(Capability.CAN_INTERACT)) {
while(this.options.attackKey.wasPressed()) { assert this.player != null;
if (this.player.isCreative()) {
while (this.options.attackKey.wasPressed()) {
} }
while(this.options.useKey.wasPressed()) { while (this.options.useKey.wasPressed()) {
} }
while(this.options.pickItemKey.wasPressed()) { while (this.options.pickItemKey.wasPressed()) {
} }
ci.cancel(); ci.cancel();
} }
} }
}
} }

@ -37,6 +37,9 @@ public abstract class ReplaceModeMixin {
@Inject(method = "doItemUse", at = @At("HEAD")) @Inject(method = "doItemUse", at = @At("HEAD"))
private void replaceBlock(CallbackInfo ci) { private void replaceBlock(CallbackInfo ci) {
assert this.player != null;
if (!this.player.isCreative())
return;
// Check if should run // Check if should run
if (!ClientEditor.INSTANCE.shouldClient(Capability.REPLACE)) if (!ClientEditor.INSTANCE.shouldClient(Capability.REPLACE))
return; // Mode is not REPLACE, ignore return; // Mode is not REPLACE, ignore