From acd318c5f1ac90544a637c4782ad00f10a901f95 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 28 Apr 2024 02:38:52 +0200 Subject: [PATCH] feat!: added Gimble Server side check, reworked mode & modifier checks Signed-off-by: moonleay --- .../net/moonleay/gimble/client/ClientMain.kt | 6 +- .../gimble/client/editor/ClientEditor.kt | 118 +++++++++++++++--- .../client/keybindings/KeybindingRegistrar.kt | 23 ++-- .../editormode/EnableInsertModeShortcut.kt | 4 +- .../editormode/EnableReplaceModeShortcut.kt | 4 +- .../editormode/EnableVisualModeShortcut.kt | 4 +- .../gimble/editor/ServerEditorManager.kt | 23 ++-- .../gimble/editor/state/GimblePolicyType.kt | 7 ++ .../gimble/editor/state/mode/Capability.kt | 11 ++ .../moonleay/gimble/editor/state/mode/Mode.kt | 2 +- .../moonleay/gimble/editor/util/EditorUtil.kt | 44 +++++++ .../gimble/editor/util/GimblePolicy.kt | 9 ++ .../moonleay/gimble/mixin/BulldozerMixin.java | 6 +- .../gimble/mixin/BulldozerMixin2.java | 4 +- .../gimble/mixin/ForcePlaceMixin.java | 9 +- .../gimble/mixin/GimblePolicyCheckMixin.java | 18 +++ .../net/moonleay/gimble/mixin/HudMixin.java | 44 +------ .../gimble/mixin/NoBlockUpdatesMixin.java | 9 +- .../gimble/mixin/NoClipCameraFixMixin.java | 9 +- .../moonleay/gimble/mixin/NoClipMixin.java | 6 +- .../gimble/mixin/NormalModeMixin.java | 13 +- .../gimble/mixin/ReplaceModeMixin.java | 4 +- .../gimble/networking/GimbleClient.kt | 21 ++++ .../gimble/networking/GimbleServer.kt | 19 ++- .../moonleay/gimble/networking/PacketIDs.kt | 3 + src/main/resources/gimble.mixins.json | 1 + 26 files changed, 305 insertions(+), 116 deletions(-) create mode 100644 src/main/java/net/moonleay/gimble/editor/state/GimblePolicyType.kt create mode 100644 src/main/java/net/moonleay/gimble/editor/state/mode/Capability.kt create mode 100644 src/main/java/net/moonleay/gimble/editor/util/EditorUtil.kt create mode 100644 src/main/java/net/moonleay/gimble/editor/util/GimblePolicy.kt create mode 100644 src/main/java/net/moonleay/gimble/mixin/GimblePolicyCheckMixin.java diff --git a/src/main/java/net/moonleay/gimble/client/ClientMain.kt b/src/main/java/net/moonleay/gimble/client/ClientMain.kt index be650db..c520c08 100644 --- a/src/main/java/net/moonleay/gimble/client/ClientMain.kt +++ b/src/main/java/net/moonleay/gimble/client/ClientMain.kt @@ -1,10 +1,11 @@ package net.moonleay.gimble.client -import net.moonleay.gimble.build.BuildConstants import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents +import net.moonleay.gimble.build.BuildConstants import net.moonleay.gimble.client.keybindings.KeybindingManager import net.moonleay.gimble.client.keybindings.KeybindingRegistrar +import net.moonleay.gimble.networking.GimbleClient import org.apache.logging.log4j.LogManager internal object ClientMain : ClientModInitializer { @@ -15,6 +16,9 @@ internal object ClientMain : ClientModInitializer { LOGGER.info("Initializing Gimble on the client side...") KeybindingRegistrar.registerKeybindings() registerEvents() + LOGGER.info("Registering packets...") + GimbleClient.registerPacketHandlers() + LOGGER.info("Packets have been registered.") LOGGER.info("Gimble has been initialized on the client side.") } diff --git a/src/main/java/net/moonleay/gimble/client/editor/ClientEditor.kt b/src/main/java/net/moonleay/gimble/client/editor/ClientEditor.kt index fa35f58..f5155e6 100644 --- a/src/main/java/net/moonleay/gimble/client/editor/ClientEditor.kt +++ b/src/main/java/net/moonleay/gimble/client/editor/ClientEditor.kt @@ -1,29 +1,97 @@ package net.moonleay.gimble.client.editor import net.minecraft.client.MinecraftClient +import net.minecraft.text.Text import net.moonleay.gimble.client.util.ChatUtil import net.moonleay.gimble.editor.ServerEditorManager import net.moonleay.gimble.editor.state.EditorState +import net.moonleay.gimble.editor.state.GimblePolicyType +import net.moonleay.gimble.editor.state.mode.Capability import net.moonleay.gimble.editor.state.mode.Mode import net.moonleay.gimble.editor.state.mode.ModeModifier +import net.moonleay.gimble.editor.util.EditorUtil +import net.moonleay.gimble.editor.util.GimblePolicy import net.moonleay.gimble.networking.GimbleClient object ClientEditor { - var CURRENT_MODE = Mode.NORMAL - val CURRENT_MODE_MODIFIER = mutableListOf() + private var POLICY = GimblePolicyType.NOT_PRESENT + + private var CURRENT_MODE = Mode.NORMAL + private var TEMP_DISABLED_MODE = Mode.UNKNOWN + + private val CURRENT_MODE_MODIFIER = mutableListOf() private val TEMP_DISABLED_MODIFIERS = mutableListOf() + private val DISABLED_MODIFIERS_STORAGE = mutableListOf() + + + fun onConnectedToNewWorld() { + POLICY = GimblePolicyType.NOT_PRESENT + GimbleClient.checkIfServerHasGimble(EditorState(CURRENT_MODE, CURRENT_MODE_MODIFIER)) + if (TEMP_DISABLED_MODE == Mode.UNKNOWN) { + TEMP_DISABLED_MODE = CURRENT_MODE + } + CURRENT_MODE = Mode.INSERT + DISABLED_MODIFIERS_STORAGE.addAll(CURRENT_MODE_MODIFIER) + CURRENT_MODE_MODIFIER.clear() + } + + fun onAllowedCheck(data: GimblePolicy) { + POLICY = data.policy + if (data.policy == GimblePolicyType.ALLOWED) { + if (TEMP_DISABLED_MODE != Mode.UNKNOWN) { + CURRENT_MODE = TEMP_DISABLED_MODE + TEMP_DISABLED_MODE = Mode.UNKNOWN + } + CURRENT_MODE_MODIFIER.addAll(DISABLED_MODIFIERS_STORAGE) + DISABLED_MODIFIERS_STORAGE.clear() + this.onUpdated() + } + } + + fun isAllowed(): Boolean { + return POLICY == GimblePolicyType.ALLOWED + } + + fun shouldClient(capability: Capability): Boolean { + return EditorUtil.shouldPlayer(capability, EditorState(CURRENT_MODE, CURRENT_MODE_MODIFIER)) + } + + fun isInNonDefaultMode(): Boolean { + return CURRENT_MODE != Mode.NORMAL + } /* * Send an updated player state to the server * */ - fun updateServerState() { + private fun updateServerState() { val state = EditorState(CURRENT_MODE, CURRENT_MODE_MODIFIER) GimbleClient.sendEditorState(state) ServerEditorManager.updateEditorState(MinecraftClient.getInstance().player!!.uuid, state) } + + /* + * Set the current mode + * */ + fun setMode(mode: Mode) { + if (!isAllowed()) { + ChatUtil.showToastToSelf("Gimble is disabled", "You cannot change modes", MinecraftClient.getInstance()) + return + } + CURRENT_MODE = mode + + this.onUpdated() + } + + /* + * Toggle a mode modifier + * */ fun toggleModifier(mod: ModeModifier) { + if (!isAllowed()) { + ChatUtil.showToastToSelf("Gimble is disabled", "You cannot change modifiers", MinecraftClient.getInstance()) + return + } if (CURRENT_MODE.incompatibleModifiers.contains(mod)){ if (TEMP_DISABLED_MODIFIERS.contains(mod)) TEMP_DISABLED_MODIFIERS.remove(mod) @@ -37,18 +105,20 @@ object ClientEditor { CURRENT_MODE_MODIFIER.add(mod) } - onModifiersUpdated() + this.onUpdated() } - fun onModifiersUpdated() { - CURRENT_MODE_MODIFIER.sort() - checkForIncompatibleModeModifiers() + private fun onUpdated() { + CURRENT_MODE_MODIFIER.sortBy { + it.displayName + } + this.checkForIncompatibleModeModifiers() } /** * This runs on Mode updated */ - fun checkForIncompatibleModeModifiers() { + private fun checkForIncompatibleModeModifiers() { if (TEMP_DISABLED_MODIFIERS.size > 0) { CURRENT_MODE_MODIFIER.addAll( TEMP_DISABLED_MODIFIERS @@ -68,6 +138,10 @@ object ClientEditor { } } + CURRENT_MODE_MODIFIER.sortBy { + it.displayName + } + // Update State this.updateServerState() @@ -87,15 +161,27 @@ object ClientEditor { return sb.toString().dropLast(2) } - fun getCurrentMode(): Mode { - return CURRENT_MODE + /* + * Get the display text to display in the HUD + * */ + fun getModeDisplayText(): Text { + val displayText = StringBuilder(CURRENT_MODE.displayName) + if (CURRENT_MODE_MODIFIER.isNotEmpty() && this.isAllowed()) { + displayText.append(" [") + for (i in CURRENT_MODE_MODIFIER.indices) { + displayText.append(CURRENT_MODE_MODIFIER[i].displayName) + if (i != CURRENT_MODE_MODIFIER.size - 1) { + displayText.append(", ") + } + } + displayText.append("]") + } else if (!this.isAllowed()) { + displayText.append(" [DISABLED]") + } + return Text.of(displayText.toString()) } - fun getCurrentModifier(): List { - return CURRENT_MODE_MODIFIER - } - - fun containsModifier(mod: ModeModifier): Boolean { - return CURRENT_MODE_MODIFIER.contains(mod) + fun getCurrentColor(): Int { + return CURRENT_MODE.color } } diff --git a/src/main/java/net/moonleay/gimble/client/keybindings/KeybindingRegistrar.kt b/src/main/java/net/moonleay/gimble/client/keybindings/KeybindingRegistrar.kt index 0f38092..018e736 100644 --- a/src/main/java/net/moonleay/gimble/client/keybindings/KeybindingRegistrar.kt +++ b/src/main/java/net/moonleay/gimble/client/keybindings/KeybindingRegistrar.kt @@ -5,7 +5,6 @@ import net.minecraft.client.util.InputUtil import net.moonleay.gimble.build.BuildConstants import net.moonleay.gimble.client.keybindings.impl.editormode.EnableInsertModeShortcut import net.moonleay.gimble.client.keybindings.impl.editormode.EnableReplaceModeShortcut -import net.moonleay.gimble.client.keybindings.impl.editormode.EnableVisualModeShortcut import net.moonleay.gimble.client.keybindings.impl.editormodemodifier.ToggleBulldozerModifierShortcut import net.moonleay.gimble.client.keybindings.impl.editormodemodifier.ToggleForcePlaceModifierShortcut import net.moonleay.gimble.client.keybindings.impl.editormodemodifier.ToggleNoClipModifierShortcut @@ -32,25 +31,25 @@ object KeybindingRegistrar { val toggleBulldozerModifierShortcut = KeyBinding( "gimble.key.editor.modifier.bulldozer", InputUtil.Type.KEYSYM, - GLFW.GLFW_KEY_B, + GLFW.GLFW_KEY_UNKNOWN, "gimble.category.editormodifier" ) val toggleForcePlaceModifierShortcut = KeyBinding( "gimble.key.editor.modifier.forceplace", InputUtil.Type.KEYSYM, - GLFW.GLFW_KEY_F, + GLFW.GLFW_KEY_UNKNOWN, "gimble.category.editormodifier" ) val toggleNoUpdatesModifierShortcut = KeyBinding( "gimble.key.editor.modifier.noupdates", InputUtil.Type.KEYSYM, - GLFW.GLFW_KEY_N, + GLFW.GLFW_KEY_UNKNOWN, "gimble.category.editormodifier" ) val toggleNoClipModifierShortcut = KeyBinding( "gimble.key.editor.modifier.noclip", InputUtil.Type.KEYSYM, - GLFW.GLFW_KEY_C, + GLFW.GLFW_KEY_UNKNOWN, "gimble.category.editormodifier" ) @@ -73,15 +72,15 @@ object KeybindingRegistrar { GLFW.GLFW_KEY_R, "gimble.category.editormode" ) - val visualKeyBinding = KeyBinding( - "gimble.key.editor.mode.visual", - InputUtil.Type.KEYSYM, - GLFW.GLFW_KEY_V, - "gimble.category.editormode" - ) +// val visualKeyBinding = KeyBinding( +// "gimble.key.editor.mode.visual", +// InputUtil.Type.KEYSYM, +// GLFW.GLFW_KEY_V, +// "gimble.category.editormode" +// ) KeybindingManager.registerShortcut(EnableInsertModeShortcut(insertKeyBinding)) KeybindingManager.registerShortcut(EnableReplaceModeShortcut(replaceKeyBinding)) - KeybindingManager.registerShortcut(EnableVisualModeShortcut(visualKeyBinding)) +// KeybindingManager.registerShortcut(EnableVisualModeShortcut(visualKeyBinding)) } private fun registerSetGameModeKeybindings() { diff --git a/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt b/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt index 6ee759c..a77abdf 100644 --- a/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt +++ b/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt @@ -9,8 +9,6 @@ import net.moonleay.gimble.editor.state.mode.Mode class EnableInsertModeShortcut(key: KeyBinding): GimbleShortcut(key) { override fun onPressed(client: MinecraftClient) { - ClientEditor.CURRENT_MODE = Mode.INSERT - - ClientEditor.checkForIncompatibleModeModifiers() + ClientEditor.setMode(Mode.INSERT) } } diff --git a/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt b/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt index 2d6898a..dfa9316 100644 --- a/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt +++ b/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt @@ -9,8 +9,6 @@ import net.moonleay.gimble.editor.state.mode.Mode class EnableReplaceModeShortcut(key: KeyBinding): GimbleShortcut(key) { override fun onPressed(client: MinecraftClient) { - ClientEditor.CURRENT_MODE = Mode.REPLACE - - ClientEditor.checkForIncompatibleModeModifiers() + ClientEditor.setMode(Mode.REPLACE) } } diff --git a/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt b/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt index 9264561..36711aa 100644 --- a/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt +++ b/src/main/java/net/moonleay/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt @@ -9,8 +9,6 @@ import net.moonleay.gimble.editor.state.mode.Mode class EnableVisualModeShortcut(key: KeyBinding): GimbleShortcut(key) { override fun onPressed(client: MinecraftClient) { - ClientEditor.CURRENT_MODE = Mode.VISUAL - - ClientEditor.checkForIncompatibleModeModifiers() + ClientEditor.setMode(Mode.VISUAL) } } diff --git a/src/main/java/net/moonleay/gimble/editor/ServerEditorManager.kt b/src/main/java/net/moonleay/gimble/editor/ServerEditorManager.kt index 0b5e387..25a3513 100644 --- a/src/main/java/net/moonleay/gimble/editor/ServerEditorManager.kt +++ b/src/main/java/net/moonleay/gimble/editor/ServerEditorManager.kt @@ -2,9 +2,10 @@ package net.moonleay.gimble.editor import net.moonleay.gimble.build.BuildConstants import net.moonleay.gimble.editor.state.EditorState -import net.moonleay.gimble.editor.state.mode.ModeModifier +import net.moonleay.gimble.editor.state.mode.Capability +import net.moonleay.gimble.editor.util.EditorUtil import org.apache.logging.log4j.LogManager -import java.util.UUID +import java.util.* object ServerEditorManager { private val LOGGER = LogManager.getLogger(BuildConstants.modName) @@ -16,13 +17,21 @@ object ServerEditorManager { LOGGER.info("$playerUUID: ${editorState.editorMode} with ${editorState.editorModifier}") } - fun getEditorState(playerUUID: UUID): EditorState? { - return STATEMAP[playerUUID] - } - fun playerHasModifier(playerUUID: UUID, modifier: ModeModifier): Boolean { + /* + * Check if a player should be able to perform an action + * */ + fun shouldPlayer(playerUUID: UUID, capability: Capability): Boolean { if (!STATEMAP.containsKey(playerUUID)) return false - return STATEMAP[playerUUID]!!.editorModifier.contains(modifier) ?: false + val state = STATEMAP[playerUUID]!! + return EditorUtil.shouldPlayer(capability, state) } + + +// fun playerHasModifier(playerUUID: UUID, modifier: ModeModifier): Boolean { +// if (!STATEMAP.containsKey(playerUUID)) +// return false +// return STATEMAP[playerUUID]!!.editorModifier.contains(modifier) ?: false +// } } diff --git a/src/main/java/net/moonleay/gimble/editor/state/GimblePolicyType.kt b/src/main/java/net/moonleay/gimble/editor/state/GimblePolicyType.kt new file mode 100644 index 0000000..52cda45 --- /dev/null +++ b/src/main/java/net/moonleay/gimble/editor/state/GimblePolicyType.kt @@ -0,0 +1,7 @@ +package net.moonleay.gimble.editor.state + +enum class GimblePolicyType { + ALLOWED, + DENIED, + NOT_PRESENT +} diff --git a/src/main/java/net/moonleay/gimble/editor/state/mode/Capability.kt b/src/main/java/net/moonleay/gimble/editor/state/mode/Capability.kt new file mode 100644 index 0000000..14dd079 --- /dev/null +++ b/src/main/java/net/moonleay/gimble/editor/state/mode/Capability.kt @@ -0,0 +1,11 @@ +package net.moonleay.gimble.editor.state.mode + +enum class Capability { + INSERT, + REPLACE, + CAN_INTERACT, + NO_CLIP, + FORCE_PLACE, + NO_UPDATES, + BULLDOZER, +} diff --git a/src/main/java/net/moonleay/gimble/editor/state/mode/Mode.kt b/src/main/java/net/moonleay/gimble/editor/state/mode/Mode.kt index b468a14..95d7961 100644 --- a/src/main/java/net/moonleay/gimble/editor/state/mode/Mode.kt +++ b/src/main/java/net/moonleay/gimble/editor/state/mode/Mode.kt @@ -1,7 +1,7 @@ package net.moonleay.gimble.editor.state.mode enum class Mode(val displayName: String, val color: Int, val incompatibleModifiers: List){ -// UNKNOWN("UNKNOWN", 0x000000, listOf()), // Unknown mode. This mode cannot be entered + UNKNOWN("UNKNOWN", 0x000000, listOf()), // Unknown mode. This mode cannot be entered NORMAL("NORMAL", 0x90a959, listOf(ModeModifier.NO_UPDATES, ModeModifier.BULLDOZER, ModeModifier.FORCE_PLACE)), // Do nothing INSERT("INSERT", 0xf4bf75, listOf()), // Place and break blocks REPLACE("REPLACE", 0xac4242, listOf()), // Replace blocks diff --git a/src/main/java/net/moonleay/gimble/editor/util/EditorUtil.kt b/src/main/java/net/moonleay/gimble/editor/util/EditorUtil.kt new file mode 100644 index 0000000..6c37255 --- /dev/null +++ b/src/main/java/net/moonleay/gimble/editor/util/EditorUtil.kt @@ -0,0 +1,44 @@ +package net.moonleay.gimble.editor.util + +import net.moonleay.gimble.editor.state.EditorState +import net.moonleay.gimble.editor.state.mode.Capability +import net.moonleay.gimble.editor.state.mode.Mode +import net.moonleay.gimble.editor.state.mode.ModeModifier + +object EditorUtil { + + /* + * Check if a player should be able to perform an action + * */ + fun shouldPlayer(capability: Capability, state: EditorState): Boolean { + when (capability) { + Capability.INSERT -> { + return state.editorMode == Mode.INSERT + } + + Capability.REPLACE -> { + return state.editorMode == Mode.REPLACE + } + + Capability.CAN_INTERACT -> { + return state.editorMode != Mode.VISUAL && state.editorMode != Mode.NORMAL + } + + Capability.NO_CLIP -> { + return state.editorModifier.contains(ModeModifier.NO_CLIP) + } + + Capability.FORCE_PLACE -> { + return state.editorModifier.contains(ModeModifier.FORCE_PLACE) + } + + Capability.NO_UPDATES -> { + return state.editorModifier.contains(ModeModifier.NO_UPDATES) + } + + Capability.BULLDOZER -> { + return state.editorModifier.contains(ModeModifier.BULLDOZER) + } + } + } +} diff --git a/src/main/java/net/moonleay/gimble/editor/util/GimblePolicy.kt b/src/main/java/net/moonleay/gimble/editor/util/GimblePolicy.kt new file mode 100644 index 0000000..620e682 --- /dev/null +++ b/src/main/java/net/moonleay/gimble/editor/util/GimblePolicy.kt @@ -0,0 +1,9 @@ +package net.moonleay.gimble.editor.util + +import kotlinx.serialization.Serializable +import net.moonleay.gimble.editor.state.GimblePolicyType + +@Serializable +data class GimblePolicy( + val policy: GimblePolicyType, +) diff --git a/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin.java b/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin.java index 461437e..70995ad 100644 --- a/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin.java @@ -2,7 +2,7 @@ package net.moonleay.gimble.mixin; import net.minecraft.client.MinecraftClient; import net.moonleay.gimble.client.editor.ClientEditor; -import net.moonleay.gimble.editor.state.mode.ModeModifier; +import net.moonleay.gimble.editor.state.mode.Capability; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -17,7 +17,7 @@ public abstract class BulldozerMixin { @Inject(method = "doAttack", at = @At(value = "HEAD")) private void func(CallbackInfoReturnable cir) { - if (!ClientEditor.INSTANCE.containsModifier(ModeModifier.BULLDOZER)){ + if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER)) { return; } this.attackCooldown = 0; @@ -25,7 +25,7 @@ public abstract class BulldozerMixin { @Inject(method = "handleBlockBreaking", at = @At(value = "HEAD")) private void func2(boolean breaking, CallbackInfo ci) { - if (!ClientEditor.INSTANCE.containsModifier(ModeModifier.BULLDOZER) || !breaking){ + if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !breaking) { return; } this.attackCooldown = 0; diff --git a/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin2.java b/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin2.java index 9539155..f0bac3f 100644 --- a/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin2.java +++ b/src/main/java/net/moonleay/gimble/mixin/BulldozerMixin2.java @@ -4,7 +4,7 @@ import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.moonleay.gimble.client.editor.ClientEditor; -import net.moonleay.gimble.editor.state.mode.ModeModifier; +import net.moonleay.gimble.editor.state.mode.Capability; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -18,7 +18,7 @@ public class BulldozerMixin2 { @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD")) private void func(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - if (!ClientEditor.INSTANCE.containsModifier(ModeModifier.BULLDOZER)) { + if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER)) { return; } this.blockBreakingCooldown = 0; diff --git a/src/main/java/net/moonleay/gimble/mixin/ForcePlaceMixin.java b/src/main/java/net/moonleay/gimble/mixin/ForcePlaceMixin.java index 115e2b1..700403c 100644 --- a/src/main/java/net/moonleay/gimble/mixin/ForcePlaceMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/ForcePlaceMixin.java @@ -1,16 +1,17 @@ package net.moonleay.gimble.mixin; import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemPlacementContext; import net.moonleay.gimble.editor.ServerEditorManager; -import net.moonleay.gimble.editor.state.mode.ModeModifier; +import net.moonleay.gimble.editor.state.mode.Capability; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.UUID; + @Mixin(BlockItem.class) public class ForcePlaceMixin { @@ -19,9 +20,9 @@ public class ForcePlaceMixin { if (context.getPlayer() == null) { return; } - PlayerEntity player = context.getPlayer(); + UUID id = context.getPlayer().getGameProfile().getId(); - if (!ServerEditorManager.INSTANCE.playerHasModifier(player.getGameProfile().getId(), ModeModifier.FORCE_PLACE)) { + if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.FORCE_PLACE)) { return; } cir.setReturnValue(true); diff --git a/src/main/java/net/moonleay/gimble/mixin/GimblePolicyCheckMixin.java b/src/main/java/net/moonleay/gimble/mixin/GimblePolicyCheckMixin.java new file mode 100644 index 0000000..951c4aa --- /dev/null +++ b/src/main/java/net/moonleay/gimble/mixin/GimblePolicyCheckMixin.java @@ -0,0 +1,18 @@ +package net.moonleay.gimble.mixin; + +import net.minecraft.client.gui.screen.DownloadingTerrainScreen; +import net.moonleay.gimble.client.editor.ClientEditor; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(DownloadingTerrainScreen.class) +public class GimblePolicyCheckMixin { + + + @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/DownloadingTerrainScreen;close()V", ordinal = -1)) + private void func(CallbackInfo ci) { + ClientEditor.INSTANCE.onConnectedToNewWorld(); + } +} diff --git a/src/main/java/net/moonleay/gimble/mixin/HudMixin.java b/src/main/java/net/moonleay/gimble/mixin/HudMixin.java index eb3a060..dd16008 100644 --- a/src/main/java/net/moonleay/gimble/mixin/HudMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/HudMixin.java @@ -4,21 +4,14 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; import net.moonleay.gimble.client.editor.ClientEditor; -import net.moonleay.gimble.editor.state.mode.Mode; -import net.moonleay.gimble.editor.state.mode.ModeModifier; -import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.List; - @Mixin(InGameHud.class) public class HudMixin { @@ -26,41 +19,10 @@ public class HudMixin { @Inject(method = "renderStatusEffectOverlay", at = @At("HEAD")) private void render(MatrixStack matrices, CallbackInfo ci) { - Mode currentMode = ClientEditor.INSTANCE.getCurrentMode(); - StringBuilder displayText = getStringBuilder(currentMode); - - MinecraftClient mc = MinecraftClient.getInstance(); - TextRenderer tr = mc.textRenderer; -// int screenWidth = mc.getWindow().getWidth(); -// int screenHeight = mc.getWindow().getHeight(); -// int scale = (mc.options.getGuiScale().getValue() == 0 ? 1 : mc.options.getGuiScale().getValue()); -// int bottomY = screenHeight / scale - 4 - tr.fontHeight - 12; - + TextRenderer tr = this.client.textRenderer; tr.drawWithShadow(matrices, - Text.of(displayText.toString()), + ClientEditor.INSTANCE.getModeDisplayText(), 4, 4, - currentMode.getColor()); - } - - @Unique - private static @NotNull StringBuilder getStringBuilder(Mode currentMode) { - List currentModifier = ClientEditor.INSTANCE.getCurrentModifier(); - StringBuilder displayText = new StringBuilder(currentMode.getDisplayName()); - if (!currentModifier.isEmpty()) { - displayText.append(" ["); - for (int i = 0; i < currentModifier.size(); i++) { - displayText.append(currentModifier.get(i).getDisplayName()); - if (i != currentModifier.size() - 1) { - displayText.append(", "); - } - } - displayText.append("]"); - } - return displayText; - } - - @Unique - private int getXRight(String txt, int screenWidth) { - return screenWidth / (MinecraftClient.getInstance().options.getGuiScale().getValue() == 0 ? 1 : MinecraftClient.getInstance().options.getGuiScale().getValue()) - 4 - MinecraftClient.getInstance().textRenderer.getWidth(Text.of(txt)); + ClientEditor.INSTANCE.getCurrentColor()); } } diff --git a/src/main/java/net/moonleay/gimble/mixin/NoBlockUpdatesMixin.java b/src/main/java/net/moonleay/gimble/mixin/NoBlockUpdatesMixin.java index dab0588..f5aa1d8 100644 --- a/src/main/java/net/moonleay/gimble/mixin/NoBlockUpdatesMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/NoBlockUpdatesMixin.java @@ -2,16 +2,17 @@ package net.moonleay.gimble.mixin; import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemPlacementContext; import net.moonleay.gimble.editor.ServerEditorManager; -import net.moonleay.gimble.editor.state.mode.ModeModifier; +import net.moonleay.gimble.editor.state.mode.Capability; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.UUID; + @Mixin(BlockItem.class) public class NoBlockUpdatesMixin { @@ -20,9 +21,9 @@ public class NoBlockUpdatesMixin { if (context.getPlayer() == null) { return; } - PlayerEntity player = context.getPlayer(); + UUID id = context.getPlayer().getGameProfile().getId(); - if (!ServerEditorManager.INSTANCE.playerHasModifier(player.getGameProfile().getId(), ModeModifier.NO_UPDATES)) { + if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.NO_UPDATES)) { return; } diff --git a/src/main/java/net/moonleay/gimble/mixin/NoClipCameraFixMixin.java b/src/main/java/net/moonleay/gimble/mixin/NoClipCameraFixMixin.java index 3c06734..a58778d 100644 --- a/src/main/java/net/moonleay/gimble/mixin/NoClipCameraFixMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/NoClipCameraFixMixin.java @@ -2,7 +2,7 @@ package net.moonleay.gimble.mixin; import net.minecraft.client.render.Camera; import net.moonleay.gimble.client.editor.ClientEditor; -import net.moonleay.gimble.editor.state.mode.ModeModifier; +import net.moonleay.gimble.editor.state.mode.Capability; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -13,9 +13,10 @@ public class NoClipCameraFixMixin { @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) private void fixCameraInNoClip(double desiredCameraDistance, CallbackInfoReturnable cir) { - if (ClientEditor.INSTANCE.containsModifier(ModeModifier.NO_CLIP)){ - cir.setReturnValue(desiredCameraDistance); - cir.cancel(); + if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP)) { + return; } + cir.setReturnValue(desiredCameraDistance); + cir.cancel(); } } diff --git a/src/main/java/net/moonleay/gimble/mixin/NoClipMixin.java b/src/main/java/net/moonleay/gimble/mixin/NoClipMixin.java index b69b502..e84762c 100644 --- a/src/main/java/net/moonleay/gimble/mixin/NoClipMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/NoClipMixin.java @@ -8,7 +8,7 @@ import net.minecraft.entity.player.PlayerAbilities; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.world.World; import net.moonleay.gimble.editor.ServerEditorManager; -import net.moonleay.gimble.editor.state.mode.ModeModifier; +import net.moonleay.gimble.editor.state.mode.Capability; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -33,7 +33,7 @@ public abstract class NoClipMixin extends LivingEntity { ) private void enoClip(CallbackInfo ci) { UUID uuid = this.getGameProfile().getId(); - if (!ServerEditorManager.INSTANCE.playerHasModifier(uuid, ModeModifier.NO_CLIP)) { + if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) { return; // NoClip is not enabled } if (!this.getAbilities().flying) { @@ -47,7 +47,7 @@ public abstract class NoClipMixin extends LivingEntity { private void onUpdatePose(CallbackInfo ci) { UUID uuid = this.getGameProfile().getId(); - if (!ServerEditorManager.INSTANCE.playerHasModifier(uuid, ModeModifier.NO_CLIP)) + if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) return; // NoClip is not enabled if (!this.getAbilities().flying) return; diff --git a/src/main/java/net/moonleay/gimble/mixin/NormalModeMixin.java b/src/main/java/net/moonleay/gimble/mixin/NormalModeMixin.java index a59a026..c0e5bef 100644 --- a/src/main/java/net/moonleay/gimble/mixin/NormalModeMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/NormalModeMixin.java @@ -2,8 +2,9 @@ package net.moonleay.gimble.mixin; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.GameOptions; -import net.moonleay.gimble.editor.state.mode.Mode; import net.moonleay.gimble.client.editor.ClientEditor; +import net.moonleay.gimble.editor.state.mode.Capability; +import net.moonleay.gimble.editor.state.mode.Mode; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -20,17 +21,17 @@ public class NormalModeMixin { @Inject(method = "openPauseMenu", at = @At("HEAD"), cancellable = true) private void setNormalMode(boolean pause, CallbackInfo ci) { - if (ClientEditor.INSTANCE.getCURRENT_MODE() != Mode.NORMAL){ + if (ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) { // Set the editor mode to normal - ClientEditor.INSTANCE.setCURRENT_MODE(Mode.NORMAL); - ClientEditor.INSTANCE.checkForIncompatibleModeModifiers(); + ClientEditor.INSTANCE.setMode(Mode.NORMAL); ci.cancel(); } } @Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isUsingItem()Z"), cancellable = true) - private void blockWorldManipulation(CallbackInfo ci) { // This could be replaced by net.minecraft.world.GameMode#isBlockBreakingRestricted - if (ClientEditor.INSTANCE.getCURRENT_MODE() == Mode.NORMAL || ClientEditor.INSTANCE.getCURRENT_MODE() == Mode.VISUAL) { + private void blockWorldManipulation(CallbackInfo ci) { + // This could be replaced by net.minecraft.world.GameMode#isBlockBreakingRestricted + if (!ClientEditor.INSTANCE.shouldClient(Capability.CAN_INTERACT)) { while(this.options.attackKey.wasPressed()) { } diff --git a/src/main/java/net/moonleay/gimble/mixin/ReplaceModeMixin.java b/src/main/java/net/moonleay/gimble/mixin/ReplaceModeMixin.java index f75e219..947e6e7 100644 --- a/src/main/java/net/moonleay/gimble/mixin/ReplaceModeMixin.java +++ b/src/main/java/net/moonleay/gimble/mixin/ReplaceModeMixin.java @@ -12,7 +12,7 @@ import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.moonleay.gimble.client.editor.ClientEditor; -import net.moonleay.gimble.editor.state.mode.Mode; +import net.moonleay.gimble.editor.state.mode.Capability; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -38,7 +38,7 @@ public abstract class ReplaceModeMixin { @Inject(method = "doItemUse", at = @At("HEAD")) private void replaceBlock(CallbackInfo ci) { // Check if should run - if (!ClientEditor.INSTANCE.getCURRENT_MODE().equals(Mode.REPLACE)) + if (!ClientEditor.INSTANCE.shouldClient(Capability.REPLACE)) return; // Mode is not REPLACE, ignore MinecraftClient client = MinecraftClient.getInstance(); assert this.interactionManager != null; diff --git a/src/main/java/net/moonleay/gimble/networking/GimbleClient.kt b/src/main/java/net/moonleay/gimble/networking/GimbleClient.kt index 407b1cc..718c7c8 100644 --- a/src/main/java/net/moonleay/gimble/networking/GimbleClient.kt +++ b/src/main/java/net/moonleay/gimble/networking/GimbleClient.kt @@ -2,13 +2,28 @@ package net.moonleay.gimble.networking import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.cbor.Cbor +import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.encodeToByteArray import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking import net.fabricmc.fabric.api.networking.v1.PacketByteBufs +import net.minecraft.network.PacketByteBuf +import net.moonleay.gimble.client.editor.ClientEditor import net.moonleay.gimble.editor.state.EditorState +import net.moonleay.gimble.editor.util.GimblePolicy object GimbleClient { + fun registerPacketHandlers() { + ClientPlayNetworking.registerGlobalReceiver(PacketIDs.TRANSFER_GIMBLE_POLICY_ID) { _, _, buf, _ -> + onAllowedCheck(buf) + } + } + + private fun onAllowedCheck(buf: PacketByteBuf) { + val policy = Cbor.decodeFromByteArray(buf.readByteArray()) + ClientEditor.onAllowedCheck(policy) // Update the client's policy + } + /** * Sends the given [EditorState] to the server. */ @@ -18,4 +33,10 @@ object GimbleClient { buf.writeByteArray(Cbor.encodeToByteArray(state)) ClientPlayNetworking.send(PacketIDs.UPDATE_EDITOR_STATE_ID, buf) } + + fun checkIfServerHasGimble(state: EditorState) { + val buf = PacketByteBufs.create() + buf.writeByteArray(Cbor.encodeToByteArray(state)) + ClientPlayNetworking.send(PacketIDs.GIMBLE_PRERENCE_CHECK_ID, buf) + } } diff --git a/src/main/java/net/moonleay/gimble/networking/GimbleServer.kt b/src/main/java/net/moonleay/gimble/networking/GimbleServer.kt index c36848e..8b182b5 100644 --- a/src/main/java/net/moonleay/gimble/networking/GimbleServer.kt +++ b/src/main/java/net/moonleay/gimble/networking/GimbleServer.kt @@ -2,12 +2,15 @@ package net.moonleay.gimble.networking import kotlinx.serialization.cbor.Cbor import kotlinx.serialization.decodeFromByteArray +import kotlinx.serialization.encodeToByteArray +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking import net.minecraft.network.PacketByteBuf import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.text.Text import net.moonleay.gimble.editor.ServerEditorManager import net.moonleay.gimble.editor.state.EditorState +import net.moonleay.gimble.editor.state.GimblePolicyType +import net.moonleay.gimble.editor.util.GimblePolicy object GimbleServer { @@ -17,6 +20,11 @@ object GimbleServer { { server, player, handler, buf, responseSender -> handleStateUpdate(player, buf) } + ServerPlayNetworking + .registerGlobalReceiver(PacketIDs.GIMBLE_PRERENCE_CHECK_ID) + { server, player, handler, buf, responseSender -> + handlePresenceCheck(player, buf) + } } private fun handleStateUpdate(player: ServerPlayerEntity, buf: PacketByteBuf){ @@ -24,4 +32,13 @@ object GimbleServer { ServerEditorManager.updateEditorState(player.uuid, state) // player.sendMessage(Text.of("Mode: ${state.editorMode} with ${state.editorModifier}")) } + + private fun handlePresenceCheck(player: ServerPlayerEntity, buf: PacketByteBuf) { + val state = Cbor.decodeFromByteArray(buf.readByteArray()) + ServerEditorManager.updateEditorState(player.uuid, state) + + val buffer = PacketByteBufs.create() + buffer.writeByteArray(Cbor.encodeToByteArray(GimblePolicy(GimblePolicyType.ALLOWED))) + ServerPlayNetworking.send(player, PacketIDs.TRANSFER_GIMBLE_POLICY_ID, buffer) + } } diff --git a/src/main/java/net/moonleay/gimble/networking/PacketIDs.kt b/src/main/java/net/moonleay/gimble/networking/PacketIDs.kt index b50148a..4587ff8 100644 --- a/src/main/java/net/moonleay/gimble/networking/PacketIDs.kt +++ b/src/main/java/net/moonleay/gimble/networking/PacketIDs.kt @@ -5,4 +5,7 @@ import net.moonleay.gimble.build.BuildConstants object PacketIDs { val UPDATE_EDITOR_STATE_ID = Identifier(BuildConstants.modId, "update_editor_state") + val GIMBLE_PRERENCE_CHECK_ID = Identifier(BuildConstants.modId, "gimble_preference_check") + val TRANSFER_GIMBLE_POLICY_ID = Identifier(BuildConstants.modId, "gimble_is_present") + } diff --git a/src/main/resources/gimble.mixins.json b/src/main/resources/gimble.mixins.json index c555448..9ec9090 100644 --- a/src/main/resources/gimble.mixins.json +++ b/src/main/resources/gimble.mixins.json @@ -11,6 +11,7 @@ "client": [ "BulldozerMixin", "BulldozerMixin2", + "GimblePolicyCheckMixin", "HudMixin", "NoClipCameraFixMixin", "NormalModeMixin",