mirror of
https://codeberg.org/moonleay/Gimbal.git
synced 2024-11-25 22:22:10 +00:00
feat!: added Gimble Server side check, reworked mode & modifier checks
Signed-off-by: moonleay <contact@moonleay.net>
This commit is contained in:
parent
724618a052
commit
acd318c5f1
26 changed files with 305 additions and 116 deletions
|
@ -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.")
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ModeModifier>()
|
||||
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<ModeModifier>()
|
||||
private val TEMP_DISABLED_MODIFIERS = mutableListOf<ModeModifier>()
|
||||
|
||||
private val DISABLED_MODIFIERS_STORAGE = mutableListOf<ModeModifier>()
|
||||
|
||||
|
||||
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<ModeModifier> {
|
||||
return CURRENT_MODE_MODIFIER
|
||||
}
|
||||
|
||||
fun containsModifier(mod: ModeModifier): Boolean {
|
||||
return CURRENT_MODE_MODIFIER.contains(mod)
|
||||
fun getCurrentColor(): Int {
|
||||
return CURRENT_MODE.color
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package net.moonleay.gimble.editor.state
|
||||
|
||||
enum class GimblePolicyType {
|
||||
ALLOWED,
|
||||
DENIED,
|
||||
NOT_PRESENT
|
||||
}
|
|
@ -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,
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package net.moonleay.gimble.editor.state.mode
|
||||
|
||||
enum class Mode(val displayName: String, val color: Int, val incompatibleModifiers: List<ModeModifier>){
|
||||
// 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
|
||||
|
|
44
src/main/java/net/moonleay/gimble/editor/util/EditorUtil.kt
Normal file
44
src/main/java/net/moonleay/gimble/editor/util/EditorUtil.kt
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
)
|
|
@ -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<Boolean> 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;
|
||||
|
|
|
@ -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<Boolean> cir) {
|
||||
if (!ClientEditor.INSTANCE.containsModifier(ModeModifier.BULLDOZER)) {
|
||||
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER)) {
|
||||
return;
|
||||
}
|
||||
this.blockBreakingCooldown = 0;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<ModeModifier> 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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Double> cir) {
|
||||
if (ClientEditor.INSTANCE.containsModifier(ModeModifier.NO_CLIP)){
|
||||
if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP)) {
|
||||
return;
|
||||
}
|
||||
cir.setReturnValue(desiredCameraDistance);
|
||||
cir.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<GimblePolicy>(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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<EditorState>(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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"client": [
|
||||
"BulldozerMixin",
|
||||
"BulldozerMixin2",
|
||||
"GimblePolicyCheckMixin",
|
||||
"HudMixin",
|
||||
"NoClipCameraFixMixin",
|
||||
"NormalModeMixin",
|
||||
|
|
Loading…
Reference in a new issue