mirror of
https://codeberg.org/moonleay/Gimbal.git
synced 2025-04-11 08:54:15 +02:00
Compare commits
32 commits
Author | SHA1 | Date | |
---|---|---|---|
dc732cc39f | |||
d59cf8f9f0 | |||
5252d9abdf | |||
42737446b2 | |||
6a89e5683f | |||
4c8404d306 | |||
b4f46ee703 | |||
19f4b3649a | |||
7325798098 | |||
302f486f1c | |||
68e9eeceb6 | |||
![]() |
60e638a3d8 | ||
31bab51603 | |||
6002af93a5 | |||
e7355f9781 | |||
f10897bf5d | |||
d26f96ee04 | |||
89dee6841a | |||
5c77165d17 | |||
13cbbfa72f | |||
7cf65cffd2 | |||
b5d65623aa | |||
dca01b275f | |||
c321746b08 | |||
8bcbcc021b | |||
8b7e576d3d | |||
8203d74b90 | |||
cfbd5d721c | |||
be062885ed | |||
c14cdffeed | |||
1c7138bb58 | |||
499863cba9 |
110 changed files with 3491 additions and 1067 deletions
42
.forgejo/workflows/build-dev.yml
Normal file
42
.forgejo/workflows/build-dev.yml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- refs/tags/
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dev:
|
||||||
|
runs-on: nodebullshit
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
|
||||||
|
- name: Set short git commit reference
|
||||||
|
id: vars
|
||||||
|
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- uses: https://github.com/actions/setup-java@v4
|
||||||
|
name: Setup Java
|
||||||
|
with:
|
||||||
|
distribution: temurin
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- uses: https://github.com/gradle/actions/setup-gradle@v3
|
||||||
|
name: Setup Gradle
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
|
- run: ./gradlew runDatagen
|
||||||
|
name: Generate assets
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
|
- run: ./gradlew build
|
||||||
|
name: Build project
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
|
- run: ./gradlew publish
|
||||||
|
name: Upload
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
PACKAGE_REPO_KEY: ${{ secrets.PACKAGE_REPO_KEY }}
|
54
.forgejo/workflows/build-release.yml
Normal file
54
.forgejo/workflows/build-release.yml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- released
|
||||||
|
- prereleased
|
||||||
|
- created
|
||||||
|
- published
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: nodebullshit
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
|
||||||
|
- name: Fetch the full git repository
|
||||||
|
run: git fetch --prune --unshallow
|
||||||
|
|
||||||
|
- name: Set short git commit reference
|
||||||
|
id: vars
|
||||||
|
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- uses: https://github.com/actions/setup-java@v4
|
||||||
|
name: Setup Java
|
||||||
|
with:
|
||||||
|
distribution: temurin
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- uses: https://github.com/gradle/actions/setup-gradle@v3
|
||||||
|
name: Setup Gradle
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
|
- run: ./gradlew runDatagen
|
||||||
|
name: Generate assets
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
|
- run: ./gradlew build
|
||||||
|
name: Build project
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
|
- run: ./gradlew publish
|
||||||
|
name: Upload
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
PACKAGE_REPO_KEY: ${{ secrets.PACKAGE_REPO_KEY }}
|
||||||
|
|
||||||
|
- run: ./gradlew modrinth
|
||||||
|
name: Publish to Modrinth
|
||||||
|
env:
|
||||||
|
GIT_SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
|
||||||
|
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
4
LICENSE
4
LICENSE
|
@ -631,7 +631,7 @@ to attach them to the start of each source file to most effectively
|
||||||
state the exclusion of warranty; and each file should have at least
|
state the exclusion of warranty; and each file should have at least
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
Gimble
|
Gimbal
|
||||||
Copyright (C) 2024 moonleay
|
Copyright (C) 2024 moonleay
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||||
If the program does terminal interaction, make it output a short
|
If the program does terminal interaction, make it output a short
|
||||||
notice like this when it starts in an interactive mode:
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
Gimble Copyright (C) 2024 moonleay
|
Gimbal Copyright (C) 2024 moonleay
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
|
|
17
README.md
17
README.md
|
@ -1,6 +1,21 @@
|
||||||
# The Gimble project
|
# The Gimbal project
|
||||||
This project aims to improve the experience of creating structures in Minecraft.
|
This project aims to improve the experience of creating structures in Minecraft.
|
||||||
|
|
||||||
|
# Links
|
||||||
|
|
||||||
|
<a href="https://discord.gg/rQUVrsttzz" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/Join_the-Discord-5865F2" alt="Join the Discord" />
|
||||||
|
</a>
|
||||||
|
<a href="https://codeberg.org/moonleay/Gimbal/wiki/?action=_pages">
|
||||||
|
<img src="https://img.shields.io/badge/Read_the-wiki-ffffff" alt="Read the wiki" />
|
||||||
|
</a>
|
||||||
|
<a href="https://codeberg.org/moonleay/Gimbal">
|
||||||
|
<img src="https://img.shields.io/badge/Clone_the-source_code-green" alt="Clone the source code" />
|
||||||
|
</a>
|
||||||
|
<a href="https://codeberg.org/moonleay/Gimbal/issues">
|
||||||
|
<img src="https://img.shields.io/badge/Report_a-problem-red" alt="Report a problem"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- **Modes** Use different modes to edit structures. Think Vim for Minecraft. [x]
|
- **Modes** Use different modes to edit structures. Think Vim for Minecraft. [x]
|
||||||
- **Modifier** Use modifiers to change the behavior of the modes and your building experience. [x]
|
- **Modifier** Use modifiers to change the behavior of the modes and your building experience. [x]
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
import org.jetbrains.gradle.ext.ProjectSettings
|
import org.jetbrains.gradle.ext.ProjectSettings
|
||||||
import org.jetbrains.gradle.ext.TaskTriggersConfig
|
import org.jetbrains.gradle.ext.TaskTriggersConfig
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
@ -9,13 +27,23 @@ plugins {
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
eclipse
|
eclipse
|
||||||
id("org.jetbrains.gradle.plugin.idea-ext")
|
id("org.jetbrains.gradle.plugin.idea-ext")
|
||||||
|
id("com.modrinth.minotaur") version "2.+"
|
||||||
}
|
}
|
||||||
|
|
||||||
val mavenVersion = System.getenv("CI_COMMIT_TAG") ?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
|
val ver = if ((System.getenv("GITHUB_REF") ?: "local").startsWith("refs/tags/"))
|
||||||
?: "0.1.0-dev" //""0.0.0-SNAPSHOT"
|
System.getenv("GITHUB_REF_NAME") ?: "err" else System.getenv("GIT_SHA_SHORT") ?: "0.0.0"
|
||||||
|
|
||||||
|
val mavenVersion = ver
|
||||||
val modId: String by project
|
val modId: String by project
|
||||||
val modName: String by project
|
val modName: String by project
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gimbal version stuff
|
||||||
|
* */
|
||||||
|
|
||||||
|
val gimbalProtocolVersion = 3
|
||||||
|
|
||||||
|
|
||||||
val mavenGroup: String by project
|
val mavenGroup: String by project
|
||||||
val mavenArtifact: String by project
|
val mavenArtifact: String by project
|
||||||
|
|
||||||
|
@ -32,6 +60,9 @@ group = mavenGroup
|
||||||
project.base.archivesName.set(mavenArtifact)
|
project.base.archivesName.set(mavenArtifact)
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
maven { // Dependency api
|
||||||
|
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fabricApi {
|
fabricApi {
|
||||||
|
@ -48,6 +79,10 @@ dependencies {
|
||||||
modImplementation("net.fabricmc:fabric-language-kotlin:$fabricKotlinVersion")
|
modImplementation("net.fabricmc:fabric-language-kotlin:$fabricKotlinVersion")
|
||||||
|
|
||||||
modImplementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
|
modImplementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
|
||||||
|
modApi("me.lucko:fabric-permissions-api:0.2-SNAPSHOT")
|
||||||
|
{
|
||||||
|
exclude(group = "net.fabricmc")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetJavaVersion = 17
|
val targetJavaVersion = 17
|
||||||
|
@ -58,6 +93,7 @@ val templateProps = mapOf(
|
||||||
"modVersion" to project.version as String,
|
"modVersion" to project.version as String,
|
||||||
"modId" to modId,
|
"modId" to modId,
|
||||||
"modName" to modName,
|
"modName" to modName,
|
||||||
|
"protocolVersion" to gimbalProtocolVersion,
|
||||||
"minecraftVersion" to minecraftVersion,
|
"minecraftVersion" to minecraftVersion,
|
||||||
"fabricLoaderVersion" to fabricLoaderVersion,
|
"fabricLoaderVersion" to fabricLoaderVersion,
|
||||||
"fabricKotlinVersion" to fabricKotlinVersion,
|
"fabricKotlinVersion" to fabricKotlinVersion,
|
||||||
|
@ -151,17 +187,18 @@ publishing {
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
if (System.getenv("CI_JOB_TOKEN") != null) {
|
if (System.getenv("CI") != null) {
|
||||||
maven {
|
maven {
|
||||||
name = "GitLab"
|
name = "Codeberg"
|
||||||
val projectId = System.getenv("CI_PROJECT_ID")
|
val repoOwner = System.getenv("GITHUB_REPOSITORY_OWNER")
|
||||||
val apiV4 = System.getenv("CI_API_V4_URL")
|
val serverUrl = System.getenv("GITHUB_SERVER_URL")
|
||||||
url = uri("$apiV4/projects/$projectId/packages/maven")
|
val accessToken = System.getenv("PACKAGE_REPO_KEY")
|
||||||
|
url = uri("$serverUrl/api/packages/$repoOwner/maven")
|
||||||
authentication {
|
authentication {
|
||||||
create("token", HttpHeaderAuthentication::class.java) {
|
create("header", HttpHeaderAuthentication::class.java) {
|
||||||
credentials(HttpHeaderCredentials::class.java) {
|
credentials(HttpHeaderCredentials::class) {
|
||||||
name = "Job-Token"
|
name = "Authorization"
|
||||||
value = System.getenv("CI_JOB_TOKEN")
|
value = "token $accessToken"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,6 +207,33 @@ publishing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build.gradle.kts
|
||||||
|
modrinth {
|
||||||
|
token.set(System.getenv("MODRINTH_TOKEN")) // Remember to have the MODRINTH_TOKEN environment variable set or else this will fail - just make sure it stays private!
|
||||||
|
projectId.set(modId) // This can be the project ID or the slug. Either will work!
|
||||||
|
versionNumber.set(mavenVersion) // You don't need to set this manually. Will fail if Modrinth has this version already
|
||||||
|
versionName.set("$modName $mavenVersion for $minecraftVersion")
|
||||||
|
versionType.set("alpha") // This is the default -- can also be `beta` or `alpha`
|
||||||
|
uploadFile.set(tasks.remapJar) // With Loom, this MUST be set to `remapJar` instead of `jar`!
|
||||||
|
gameVersions.addAll(listOf(project.ext["minecraft.version"] as String)) // Must be an array, even with only one version
|
||||||
|
loaders.add("fabric") // Must also be an array - no need to specify this if you're using Loom or ForgeGradle
|
||||||
|
changelog.set(
|
||||||
|
"Changelog v$mavenVersion\n\nCheckout the changelog [on codeberg](${System.getenv("GITHUB_SERVER_URL") ?: ""}/${
|
||||||
|
System.getenv(
|
||||||
|
"GITHUB_REPOSITORY"
|
||||||
|
) ?: ""
|
||||||
|
}/releases/tag/${System.getenv("GITHUB_REF_NAME") ?: ""})"
|
||||||
|
)
|
||||||
|
dependencies { // A special DSL for creating dependencies
|
||||||
|
// scope.type
|
||||||
|
// The scope can be `required`, `optional`, `incompatible`, or `embedded`
|
||||||
|
// The type can either be `project` or `version`
|
||||||
|
required.project("fabric-api") // Creates a new required dependency on Fabric API
|
||||||
|
required.project("fabric-language-kotlin")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rootProject.idea.project {
|
rootProject.idea.project {
|
||||||
this as ExtensionAware
|
this as ExtensionAware
|
||||||
configure<ProjectSettings> {
|
configure<ProjectSettings> {
|
||||||
|
|
|
@ -1,18 +1,36 @@
|
||||||
|
#
|
||||||
|
# Gimbal
|
||||||
|
# Copyright (C) 2024 moonleay
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
#Generated by fabric-mod-template
|
#Generated by fabric-mod-template
|
||||||
#Sun Apr 21 19:29:15 CEST 2024
|
#Sun Apr 21 19:29:15 CEST 2024
|
||||||
fabric.loom.version=1.4.6
|
fabric.loom.version=1.6-SNAPSHOT
|
||||||
kotlin.version=1.9.22
|
kotlin.version=1.9.22
|
||||||
fabric.api.version=0.77.0+1.19.2
|
fabric.api.version=0.77.0+1.19.2
|
||||||
yarn.version=1.19.2+build.28
|
yarn.version=1.19.2+build.28
|
||||||
idea-ext.version=1.1.6
|
idea-ext.version=1.1.6
|
||||||
org.gradle.jvmargs=-Xmx2G
|
org.gradle.jvmargs=-Xmx2G
|
||||||
modId=gimble
|
modId=gimbal
|
||||||
kotlinx.serialization.version=1.6.2
|
kotlinx.serialization.version=1.6.2
|
||||||
fabric.kotlin.version=1.10.18+kotlin.1.9.22
|
fabric.kotlin.version=1.10.18+kotlin.1.9.22
|
||||||
mavenGroup=net.moonleay
|
mavenGroup=net.moonleay
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
minecraft.version=1.19.2
|
minecraft.version=1.19.2
|
||||||
modName=Gimble
|
modName=Gimbal
|
||||||
#fabric.loader.version=0.15.10
|
#fabric.loader.version=0.15.10
|
||||||
mavenArtifact=gimble
|
mavenArtifact=gimbal
|
||||||
fabric.loader.version=0.14.0
|
fabric.loader.version=0.14.0
|
||||||
|
|
20
gradle/wrapper/gradle-wrapper.properties
vendored
20
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,24 @@
|
||||||
|
#
|
||||||
|
# Gimbal
|
||||||
|
# Copyright (C) 2024 moonleay
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
22
gradlew
vendored
22
gradlew
vendored
|
@ -1,19 +1,21 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015-2021 the original authors.
|
# Gimbal
|
||||||
|
# Copyright (C) 2024 moonleay
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# you may not use this file except in compliance with the License.
|
# it under the terms of the GNU General Public License as published by
|
||||||
# You may obtain a copy of the License at
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# https://www.apache.org/licenses/LICENSE-2.0
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# You should have received a copy of the GNU General Public License
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
|
|
43
src/main/java/net/moonleay/gimbal/Main.kt
Normal file
43
src/main/java/net/moonleay/gimbal/Main.kt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal
|
||||||
|
|
||||||
|
import net.fabricmc.api.ModInitializer
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
import net.moonleay.gimbal.networking.GimbalServer
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
|
||||||
|
internal object Main : ModInitializer {
|
||||||
|
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
||||||
|
|
||||||
|
override fun onInitialize() {
|
||||||
|
LOGGER.info("Initializing Gimbal on the common side...")
|
||||||
|
LOGGER.info("Registering packets...")
|
||||||
|
GimbalServer.registerPacketHandler()
|
||||||
|
LOGGER.info("Packets have been registered.")
|
||||||
|
LOGGER.info("Registering events...")
|
||||||
|
ServerPlayConnectionEvents.INIT.register(ServerPlayConnectionEvents.Init { handler, server ->
|
||||||
|
GimbalServer.notifyPlayerOfPolicy(handler.player)
|
||||||
|
})
|
||||||
|
LOGGER.info("Events have been registered.")
|
||||||
|
LOGGER.info("Gimbal has been initialized on the common side.")
|
||||||
|
LOGGER.info("${BuildConstants.modName} (${BuildConstants.modId}) v.${BuildConstants.modVersion} by moonleay")
|
||||||
|
}
|
||||||
|
}
|
67
src/main/java/net/moonleay/gimbal/client/ClientMain.kt
Normal file
67
src/main/java/net/moonleay/gimbal/client/ClientMain.kt
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientLoginConnectionEvents
|
||||||
|
import net.fabricmc.loader.api.FabricLoader
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
import net.moonleay.gimbal.client.config.ClientConfigHolder
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.KeybindingManager
|
||||||
|
import net.moonleay.gimbal.client.keybindings.KeybindingRegistrar
|
||||||
|
import net.moonleay.gimbal.networking.GimbalClient
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
|
||||||
|
internal object ClientMain : ClientModInitializer {
|
||||||
|
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
||||||
|
lateinit var CONFIG: ClientConfigHolder
|
||||||
|
|
||||||
|
|
||||||
|
override fun onInitializeClient() {
|
||||||
|
LOGGER.info("Initializing Gimbal on the client side...")
|
||||||
|
KeybindingRegistrar.registerKeybindings()
|
||||||
|
this.registerEvents()
|
||||||
|
LOGGER.info("Registering packets...")
|
||||||
|
GimbalClient.registerPacketHandlers()
|
||||||
|
LOGGER.info("Packets have been registered.")
|
||||||
|
LOGGER.info("Loading client config.")
|
||||||
|
val gimbalConfigPath = FabricLoader.getInstance().configDir.resolve(BuildConstants.modId + "/client.json")
|
||||||
|
CONFIG = ClientConfigHolder(gimbalConfigPath)
|
||||||
|
LOGGER.info("Config has been loaded.")
|
||||||
|
LOGGER.info("Applying Config to client.")
|
||||||
|
ClientEditor.applyConfig(CONFIG.config)
|
||||||
|
LOGGER.info("Config has been applied.")
|
||||||
|
LOGGER.info("Gimbal has been initialized on the client side.")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerEvents() {
|
||||||
|
LOGGER.info("Registering client events...")
|
||||||
|
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { client ->
|
||||||
|
KeybindingManager.onClientTick(client)
|
||||||
|
})
|
||||||
|
|
||||||
|
ClientLoginConnectionEvents.INIT.register(ClientLoginConnectionEvents.Init { _, _ ->
|
||||||
|
ClientEditor.onConnectedToNewWorld() // Client is connecting to a new server, reset the editor
|
||||||
|
})
|
||||||
|
LOGGER.info("Client events have been registered.")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config
|
||||||
|
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.decodeFromStream
|
||||||
|
import kotlinx.serialization.json.encodeToStream
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.*
|
||||||
|
|
||||||
|
class ClientConfigHolder(private val path: Path) {
|
||||||
|
var config: GimbalClientConfig
|
||||||
|
private set
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.config = load()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateConfig(new: GimbalClientConfig) {
|
||||||
|
this.config = new
|
||||||
|
this.save(config)
|
||||||
|
ClientEditor.applyConfig(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
fun load(): GimbalClientConfig {
|
||||||
|
if (!path.isReadable())
|
||||||
|
save(GimbalClientConfig())
|
||||||
|
val iStream = path.inputStream()
|
||||||
|
val gimbalClientConfig: GimbalClientConfig = iStream.use {
|
||||||
|
Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
}.decodeFromStream<GimbalClientConfig>(it)
|
||||||
|
}
|
||||||
|
iStream.close()
|
||||||
|
return gimbalClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
fun save(conf: GimbalClientConfig) {
|
||||||
|
if (!path.parent.exists()) {
|
||||||
|
path.parent.createDirectory()
|
||||||
|
}
|
||||||
|
if (!path.parent.isWritable()) {
|
||||||
|
throw Exception("Parent of path ${path.parent.pathString} is not writable.")
|
||||||
|
}
|
||||||
|
if (!path.exists())
|
||||||
|
path.createFile()
|
||||||
|
if (!path.isWritable()) {
|
||||||
|
throw Exception("Path (${path.pathString}) exists, but is not writable.")
|
||||||
|
}
|
||||||
|
val oStream = path.outputStream()
|
||||||
|
oStream.use {
|
||||||
|
Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
}.encodeToStream<GimbalClientConfig>(conf, it)
|
||||||
|
}
|
||||||
|
oStream.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.moonleay.gimbal.client.config.enums.ToastSettings
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GimbalClientConfig(
|
||||||
|
val guiSettings: GimbalGuiSettings = GimbalGuiSettings(),
|
||||||
|
val toastSettings: ToastSettings = ToastSettings.ALL,
|
||||||
|
val playerFlySpeed: Int = 100,
|
||||||
|
val shouldEscResetMode: Boolean = true,
|
||||||
|
val defaultMode: Mode = Mode.NORMAL
|
||||||
|
)
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.moonleay.gimbal.client.config.enums.HorizontalAnchor
|
||||||
|
import net.moonleay.gimbal.client.config.enums.HudOptions
|
||||||
|
import net.moonleay.gimbal.client.config.enums.VerticalAnchor
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GimbalGuiSettings(
|
||||||
|
val showHud: Boolean = true,
|
||||||
|
val offset: ScaledRes = ScaledRes(4.0, 4.0),
|
||||||
|
val horizontalAnchor: HorizontalAnchor = HorizontalAnchor.LEFT,
|
||||||
|
val verticalAnchor: VerticalAnchor = VerticalAnchor.TOP,
|
||||||
|
val hudOptions: HudOptions = HudOptions.ALL,
|
||||||
|
)
|
27
src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt
Normal file
27
src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ScaledRes(
|
||||||
|
val scaledX: Double, // offsetX
|
||||||
|
val scaledY: Double, // offsetY
|
||||||
|
)
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config.enums
|
||||||
|
|
||||||
|
enum class Centerpoint {
|
||||||
|
TOP_LEFT,
|
||||||
|
TOP_RIGHT,
|
||||||
|
BOTTOM_RIGHT,
|
||||||
|
BOTTOM_LEFT,
|
||||||
|
CENTER
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config.enums
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
enum class HorizontalAnchor {
|
||||||
|
LEFT,
|
||||||
|
CENTER,
|
||||||
|
RIGHT,
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config.enums
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.moonleay.gimbal.constants.TranslationKeys
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
enum class HudOptions(val translatableText: Text) {
|
||||||
|
ALL(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_ALL)),
|
||||||
|
NUMBER(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_NUMBER)),
|
||||||
|
INITIAL(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_INITIALS)),
|
||||||
|
ONLY_MODE(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODE_ONLY)),
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config.enums
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.moonleay.gimbal.client.util.ToastType
|
||||||
|
import net.moonleay.gimbal.constants.TranslationKeys
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
enum class ToastSettings(val translatableText: Text, val allowedTypes: List<ToastType>) {
|
||||||
|
ALL(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_ALL), listOf(ToastType.SYSTEM, ToastType.TOGGLE)),
|
||||||
|
ONLY_TOGGLE(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_TOGGLE), listOf(ToastType.TOGGLE)),
|
||||||
|
ONLY_SYSTEM(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_SYSTEM), listOf(ToastType.SYSTEM)),
|
||||||
|
NONE(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_NONE), listOf())
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.config.enums
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
enum class VerticalAnchor {
|
||||||
|
TOP,
|
||||||
|
CENTER,
|
||||||
|
BOTTOM,
|
||||||
|
}
|
316
src/main/java/net/moonleay/gimbal/client/editor/ClientEditor.kt
Normal file
316
src/main/java/net/moonleay/gimbal/client/editor/ClientEditor.kt
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.editor
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
import net.moonleay.gimbal.client.ClientMain
|
||||||
|
import net.moonleay.gimbal.client.config.GimbalClientConfig
|
||||||
|
import net.moonleay.gimbal.client.config.enums.HudOptions
|
||||||
|
import net.moonleay.gimbal.client.util.ChatUtil
|
||||||
|
import net.moonleay.gimbal.client.util.ToastType
|
||||||
|
import net.moonleay.gimbal.editor.ServerEditorManager
|
||||||
|
import net.moonleay.gimbal.editor.state.EditorState
|
||||||
|
import net.moonleay.gimbal.editor.state.GimbalPolicyType
|
||||||
|
import net.moonleay.gimbal.editor.state.GimbalServerState
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Capability
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.ModeModifier
|
||||||
|
import net.moonleay.gimbal.editor.util.EditorUtil
|
||||||
|
import net.moonleay.gimbal.networking.GimbalClient
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
|
||||||
|
object ClientEditor {
|
||||||
|
private var POLICY = GimbalPolicyType.NOT_PRESENT
|
||||||
|
|
||||||
|
private lateinit var CURRENT_MODE: Mode
|
||||||
|
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>()
|
||||||
|
|
||||||
|
|
||||||
|
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
||||||
|
|
||||||
|
fun applyConfig(config: GimbalClientConfig, isBoot: Boolean = true) {
|
||||||
|
if (isBoot) {
|
||||||
|
this.CURRENT_MODE = config.defaultMode
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!config.shouldEscResetMode) return
|
||||||
|
this.CURRENT_MODE = config.defaultMode
|
||||||
|
onUpdated()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onConnectedToNewWorld() {
|
||||||
|
POLICY = GimbalPolicyType.NOT_PRESENT
|
||||||
|
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 onPolicyReceived(data: GimbalServerState, shouldUpdateServer: Boolean = true) {
|
||||||
|
POLICY = data.policyType
|
||||||
|
if (data.policyType == GimbalPolicyType.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()
|
||||||
|
onUpdated(shouldUpdateServer)
|
||||||
|
|
||||||
|
if (!shouldUpdateServer) {
|
||||||
|
val player = MinecraftClient.getInstance().player
|
||||||
|
if (player == null) {
|
||||||
|
LOGGER.warn("Player is null!") //FIXME: Fix player is null at world join!
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ServerEditorManager.updateEditorState(
|
||||||
|
MinecraftClient.getInstance().player!!.uuid,
|
||||||
|
this.getClientState()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAllowed(): Boolean {
|
||||||
|
return POLICY == GimbalPolicyType.ALLOWED
|
||||||
|
}
|
||||||
|
|
||||||
|
fun shouldClient(capability: Capability): Boolean {
|
||||||
|
return EditorUtil.shouldPlayer(
|
||||||
|
capability, EditorState(
|
||||||
|
CURRENT_MODE,
|
||||||
|
CURRENT_MODE_MODIFIER
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isInNonDefaultMode(): Boolean {
|
||||||
|
return CURRENT_MODE != ClientMain.CONFIG.config.defaultMode
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send an updated player state to the server
|
||||||
|
* */
|
||||||
|
private fun updateServerState() {
|
||||||
|
val state = this.getClientState()
|
||||||
|
GimbalClient.sendStatePacket(state)
|
||||||
|
ServerEditorManager.updateEditorState(MinecraftClient.getInstance().player!!.uuid, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the current mode
|
||||||
|
* */
|
||||||
|
fun setMode(mode: Mode) {
|
||||||
|
if (!isAllowed()) {
|
||||||
|
ChatUtil.showToastToSelf(
|
||||||
|
"Gimbal is disabled",
|
||||||
|
"You cannot change modes",
|
||||||
|
ToastType.SYSTEM,
|
||||||
|
ClientMain.CONFIG.config,
|
||||||
|
MinecraftClient.getInstance()
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!MinecraftClient.getInstance().player!!.isCreative)
|
||||||
|
return
|
||||||
|
CURRENT_MODE = mode
|
||||||
|
|
||||||
|
onUpdated()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Toggle a mode modifier
|
||||||
|
* */
|
||||||
|
fun toggleModifier(mod: ModeModifier) {
|
||||||
|
if (!isAllowed()) {
|
||||||
|
ChatUtil.showToastToSelf(
|
||||||
|
"Gimbal is disabled",
|
||||||
|
"You cannot change modifiers",
|
||||||
|
ToastType.SYSTEM,
|
||||||
|
ClientMain.CONFIG.config,
|
||||||
|
MinecraftClient.getInstance()
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!MinecraftClient.getInstance().player!!.isCreative)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (CURRENT_MODE.incompatibleModifiers.contains(mod)){
|
||||||
|
if (TEMP_DISABLED_MODIFIERS.contains(mod)) {
|
||||||
|
TEMP_DISABLED_MODIFIERS.remove(mod)
|
||||||
|
} else {
|
||||||
|
TEMP_DISABLED_MODIFIERS.add(mod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (CURRENT_MODE_MODIFIER.contains(mod)) {
|
||||||
|
CURRENT_MODE_MODIFIER.remove(mod)
|
||||||
|
ChatUtil.showToastToSelf(
|
||||||
|
"Disabled ${mod.displayName}",
|
||||||
|
"[${this.getDisplayNameListAsString(CURRENT_MODE_MODIFIER)}]",
|
||||||
|
ToastType.TOGGLE, ClientMain.CONFIG.config,
|
||||||
|
MinecraftClient.getInstance()
|
||||||
|
)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
CURRENT_MODE_MODIFIER.add(mod)
|
||||||
|
ChatUtil.showToastToSelf(
|
||||||
|
"Enabled ${mod.displayName}",
|
||||||
|
"[${this.getDisplayNameListAsString(CURRENT_MODE_MODIFIER)}]",
|
||||||
|
ToastType.TOGGLE, ClientMain.CONFIG.config,
|
||||||
|
MinecraftClient.getInstance()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdated()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onUpdated(shouldUpdateServer: Boolean = true) {
|
||||||
|
CURRENT_MODE_MODIFIER.sortBy {
|
||||||
|
it.displayName
|
||||||
|
}
|
||||||
|
checkForIncompatibleModeModifiers(shouldUpdateServer)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This runs on Mode updated
|
||||||
|
*/
|
||||||
|
private fun checkForIncompatibleModeModifiers(shouldUpdateServer: Boolean = true) {
|
||||||
|
if (TEMP_DISABLED_MODIFIERS.size > 0) {
|
||||||
|
CURRENT_MODE_MODIFIER.addAll(
|
||||||
|
TEMP_DISABLED_MODIFIERS
|
||||||
|
)
|
||||||
|
TEMP_DISABLED_MODIFIERS.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
val incompatibleModeModifiers = CURRENT_MODE.incompatibleModifiers
|
||||||
|
for (mod in CURRENT_MODE_MODIFIER) {
|
||||||
|
if (incompatibleModeModifiers.contains(mod)) {
|
||||||
|
TEMP_DISABLED_MODIFIERS.add(mod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (mod in TEMP_DISABLED_MODIFIERS) {
|
||||||
|
if (CURRENT_MODE_MODIFIER.contains(mod)) { // This check is probably useless.
|
||||||
|
CURRENT_MODE_MODIFIER.remove(mod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CURRENT_MODE_MODIFIER.sortBy {
|
||||||
|
it.displayName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update State
|
||||||
|
if (shouldUpdateServer)
|
||||||
|
updateServerState()
|
||||||
|
|
||||||
|
if(TEMP_DISABLED_MODIFIERS.isNotEmpty()) {
|
||||||
|
ChatUtil.showToastToSelf(
|
||||||
|
"${CURRENT_MODE.displayName} Mode disabled",
|
||||||
|
getDisplayNameListAsString(TEMP_DISABLED_MODIFIERS),
|
||||||
|
ToastType.SYSTEM,
|
||||||
|
ClientMain.CONFIG.config,
|
||||||
|
MinecraftClient.getInstance()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDisplayNameListAsString(list: List<ModeModifier>): String {
|
||||||
|
if(list.isEmpty())
|
||||||
|
return ""
|
||||||
|
val sb = StringBuilder()
|
||||||
|
for (mod in list) {
|
||||||
|
sb.append(mod.displayName)
|
||||||
|
sb.append(", ")
|
||||||
|
}
|
||||||
|
return sb.toString().dropLast(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getShortNameListAsString(list: List<ModeModifier>): String {
|
||||||
|
if (list.isEmpty())
|
||||||
|
return ""
|
||||||
|
val sb = StringBuilder()
|
||||||
|
for (mod in list) {
|
||||||
|
sb.append(mod.shortName)
|
||||||
|
sb.append(", ")
|
||||||
|
}
|
||||||
|
return sb.toString().dropLast(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the display text to display in the HUD
|
||||||
|
* */
|
||||||
|
fun getModeDisplayText(config: GimbalClientConfig): Text {
|
||||||
|
val displayText = StringBuilder(CURRENT_MODE.displayName)
|
||||||
|
if (isAllowed() && MinecraftClient.getInstance().player?.isCreative == true) {
|
||||||
|
when (config.guiSettings.hudOptions) {
|
||||||
|
HudOptions.ALL -> {
|
||||||
|
if (CURRENT_MODE_MODIFIER.size > 0) {
|
||||||
|
displayText.append(" [")
|
||||||
|
displayText.append(this.getDisplayNameListAsString(CURRENT_MODE_MODIFIER))
|
||||||
|
displayText.append("]")
|
||||||
|
}
|
||||||
|
return Text.of(displayText.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
HudOptions.NUMBER -> {
|
||||||
|
displayText.append(" (")
|
||||||
|
displayText.append(CURRENT_MODE_MODIFIER.size)
|
||||||
|
displayText.append(")")
|
||||||
|
return Text.of(displayText.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
HudOptions.INITIAL -> {
|
||||||
|
if (CURRENT_MODE_MODIFIER.size > 0) {
|
||||||
|
displayText.append(" [")
|
||||||
|
displayText.append(this.getShortNameListAsString(CURRENT_MODE_MODIFIER))
|
||||||
|
displayText.append("]")
|
||||||
|
}
|
||||||
|
return Text.of(displayText.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
HudOptions.ONLY_MODE -> return Text.of(displayText.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Text.of("[GIMBAL DISABLED]")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCurrentColor(): Int {
|
||||||
|
return CURRENT_MODE.color
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getClientState(): EditorState {
|
||||||
|
return EditorState(CURRENT_MODE, CURRENT_MODE_MODIFIER)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
|
||||||
|
object KeybindingManager {
|
||||||
|
|
||||||
|
private val shortcuts = mutableListOf<GimbalShortcut>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a shortcut. This will also register the keybinding.
|
||||||
|
* */
|
||||||
|
fun registerShortcut(shortcut: GimbalShortcut) {
|
||||||
|
shortcuts.add(shortcut)
|
||||||
|
KeyBindingRegistryImpl.registerKeyBinding(shortcut.keyBinding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onClientTick(client: MinecraftClient){
|
||||||
|
// Sadly, this cannot be done without iterating over all shortcuts :madge:
|
||||||
|
for (shortcut in shortcuts)
|
||||||
|
if (shortcut.keyBinding.wasPressed())
|
||||||
|
shortcut.onPressed(client)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,36 @@
|
||||||
package net.moonleay.gimble.client.keybindings
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings
|
||||||
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
import net.minecraft.client.option.KeyBinding
|
||||||
import net.minecraft.client.util.InputUtil
|
import net.minecraft.client.util.InputUtil
|
||||||
import net.moonleay.gimble.build.BuildConstants
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
import net.moonleay.gimble.client.keybindings.impl.editormode.EnableInsertModeShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.editormode.EnableInsertModeShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.editormode.EnableReplaceModeShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.editormode.EnableReplaceModeShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.editormodemodifier.ToggleBulldozerModifierShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.editormodemodifier.ToggleBulldozerModifierShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.editormodemodifier.ToggleForcePlaceModifierShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.editormodemodifier.ToggleForcePlaceModifierShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.editormodemodifier.ToggleNoClipModifierShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.editormodemodifier.ToggleNoClipModifierShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.editormodemodifier.ToggleNoUpdatesModifierShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.editormodemodifier.ToggleNoUpdatesModifierShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.gamemode.CreativeModeShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.gamemode.CreativeModeShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.gamemode.SpectatorModeShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.gamemode.SpectatorModeShortcut
|
||||||
import net.moonleay.gimble.client.keybindings.impl.gamemode.SurvivalModeShortcut
|
import net.moonleay.gimbal.client.keybindings.impl.gamemode.SurvivalModeShortcut
|
||||||
|
import net.moonleay.gimbal.constants.TranslationKeys
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import org.lwjgl.glfw.GLFW
|
import org.lwjgl.glfw.GLFW
|
||||||
|
|
||||||
|
@ -29,28 +48,28 @@ object KeybindingRegistrar {
|
||||||
|
|
||||||
private fun registerSetEditorModeModifierKeybindings() {
|
private fun registerSetEditorModeModifierKeybindings() {
|
||||||
val toggleBulldozerModifierShortcut = KeyBinding(
|
val toggleBulldozerModifierShortcut = KeyBinding(
|
||||||
"gimble.key.editor.modifier.bulldozer",
|
TranslationKeys.Keybindings.Binding.Editor.Modifier.BULLDOZER,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_UNKNOWN,
|
GLFW.GLFW_KEY_UNKNOWN,
|
||||||
"gimble.category.editormodifier"
|
TranslationKeys.Keybindings.Category.Editor.MODIFIER
|
||||||
)
|
)
|
||||||
val toggleForcePlaceModifierShortcut = KeyBinding(
|
val toggleForcePlaceModifierShortcut = KeyBinding(
|
||||||
"gimble.key.editor.modifier.forceplace",
|
TranslationKeys.Keybindings.Binding.Editor.Modifier.FORCE_PLACE,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_UNKNOWN,
|
GLFW.GLFW_KEY_UNKNOWN,
|
||||||
"gimble.category.editormodifier"
|
TranslationKeys.Keybindings.Category.Editor.MODIFIER
|
||||||
)
|
)
|
||||||
val toggleNoUpdatesModifierShortcut = KeyBinding(
|
val toggleNoUpdatesModifierShortcut = KeyBinding(
|
||||||
"gimble.key.editor.modifier.noupdates",
|
TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_UPDATES,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_UNKNOWN,
|
GLFW.GLFW_KEY_UNKNOWN,
|
||||||
"gimble.category.editormodifier"
|
TranslationKeys.Keybindings.Category.Editor.MODIFIER
|
||||||
)
|
)
|
||||||
val toggleNoClipModifierShortcut = KeyBinding(
|
val toggleNoClipModifierShortcut = KeyBinding(
|
||||||
"gimble.key.editor.modifier.noclip",
|
TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_CLIP,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_UNKNOWN,
|
GLFW.GLFW_KEY_UNKNOWN,
|
||||||
"gimble.category.editormodifier"
|
TranslationKeys.Keybindings.Category.Editor.MODIFIER
|
||||||
)
|
)
|
||||||
|
|
||||||
KeybindingManager.registerShortcut(ToggleBulldozerModifierShortcut(toggleBulldozerModifierShortcut))
|
KeybindingManager.registerShortcut(ToggleBulldozerModifierShortcut(toggleBulldozerModifierShortcut))
|
||||||
|
@ -61,22 +80,22 @@ object KeybindingRegistrar {
|
||||||
|
|
||||||
private fun registerSetEditorModeKeybindings() {
|
private fun registerSetEditorModeKeybindings() {
|
||||||
val insertKeyBinding = KeyBinding(
|
val insertKeyBinding = KeyBinding(
|
||||||
"gimble.key.editor.mode.insert",
|
TranslationKeys.Keybindings.Binding.Editor.Mode.INSERT,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_I,
|
GLFW.GLFW_KEY_I,
|
||||||
"gimble.category.editormode"
|
TranslationKeys.Keybindings.Category.Editor.MODE
|
||||||
)
|
)
|
||||||
val replaceKeyBinding = KeyBinding(
|
val replaceKeyBinding = KeyBinding(
|
||||||
"gimble.key.editor.mode.replace",
|
TranslationKeys.Keybindings.Binding.Editor.Mode.REPLACE,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_R,
|
GLFW.GLFW_KEY_R,
|
||||||
"gimble.category.editormode"
|
TranslationKeys.Keybindings.Category.Editor.MODE
|
||||||
)
|
)
|
||||||
// val visualKeyBinding = KeyBinding(
|
// val visualKeyBinding = KeyBinding(
|
||||||
// "gimble.key.editor.mode.visual",
|
// "gimbal.key.editor.mode.visual",
|
||||||
// InputUtil.Type.KEYSYM,
|
// InputUtil.Type.KEYSYM,
|
||||||
// GLFW.GLFW_KEY_V,
|
// GLFW.GLFW_KEY_V,
|
||||||
// "gimble.category.editormode"
|
// "gimbal.category.editormode"
|
||||||
// )
|
// )
|
||||||
KeybindingManager.registerShortcut(EnableInsertModeShortcut(insertKeyBinding))
|
KeybindingManager.registerShortcut(EnableInsertModeShortcut(insertKeyBinding))
|
||||||
KeybindingManager.registerShortcut(EnableReplaceModeShortcut(replaceKeyBinding))
|
KeybindingManager.registerShortcut(EnableReplaceModeShortcut(replaceKeyBinding))
|
||||||
|
@ -85,22 +104,22 @@ object KeybindingRegistrar {
|
||||||
|
|
||||||
private fun registerSetGameModeKeybindings() {
|
private fun registerSetGameModeKeybindings() {
|
||||||
val survivalKeyBinding = KeyBinding(
|
val survivalKeyBinding = KeyBinding(
|
||||||
"gimble.key.game.mode.survival",
|
TranslationKeys.Keybindings.Binding.Game.Mode.SURVIVAL,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_UNKNOWN,
|
GLFW.GLFW_KEY_UNKNOWN,
|
||||||
"gimble.category.gamemode"
|
TranslationKeys.Keybindings.Category.Game.GAMEMODE
|
||||||
)
|
)
|
||||||
val creativeKeyBinding = KeyBinding(
|
val creativeKeyBinding = KeyBinding(
|
||||||
"gimble.key.game.mode.creative",
|
TranslationKeys.Keybindings.Binding.Game.Mode.CREATIVE,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_UNKNOWN,
|
GLFW.GLFW_KEY_UNKNOWN,
|
||||||
"gimble.category.gamemode"
|
TranslationKeys.Keybindings.Category.Game.GAMEMODE
|
||||||
)
|
)
|
||||||
val spectatorKeyBinding = KeyBinding(
|
val spectatorKeyBinding = KeyBinding(
|
||||||
"gimble.key.game.mode.spectator",
|
TranslationKeys.Keybindings.Binding.Game.Mode.SPECTATOR,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
GLFW.GLFW_KEY_UNKNOWN,
|
GLFW.GLFW_KEY_UNKNOWN,
|
||||||
"gimble.category.gamemode"
|
TranslationKeys.Keybindings.Category.Game.GAMEMODE
|
||||||
)
|
)
|
||||||
KeybindingManager.registerShortcut(SurvivalModeShortcut(survivalKeyBinding))
|
KeybindingManager.registerShortcut(SurvivalModeShortcut(survivalKeyBinding))
|
||||||
KeybindingManager.registerShortcut(CreativeModeShortcut(creativeKeyBinding))
|
KeybindingManager.registerShortcut(CreativeModeShortcut(creativeKeyBinding))
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
|
||||||
|
abstract class GimbalShortcut(val keyBinding: KeyBinding) {
|
||||||
|
|
||||||
|
abstract fun onPressed(client: MinecraftClient)
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.editormode
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
|
||||||
|
|
||||||
|
class EnableInsertModeShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ClientEditor.setMode(Mode.INSERT)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.editormode
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
|
||||||
|
|
||||||
|
class EnableReplaceModeShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ClientEditor.setMode(Mode.REPLACE)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.editormode
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
|
||||||
|
|
||||||
|
class EnableVisualModeShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ClientEditor.setMode(Mode.VISUAL)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.editormodemodifier
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.ModeModifier
|
||||||
|
|
||||||
|
class ToggleBulldozerModifierShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ClientEditor.toggleModifier(ModeModifier.BULLDOZER)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.editormodemodifier
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.ModeModifier
|
||||||
|
|
||||||
|
class ToggleForcePlaceModifierShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ClientEditor.toggleModifier(ModeModifier.FORCE_PLACE)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.editormodemodifier
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.ModeModifier
|
||||||
|
|
||||||
|
class ToggleNoClipModifierShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ClientEditor.toggleModifier(ModeModifier.NO_CLIP)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.editormodemodifier
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.ModeModifier
|
||||||
|
|
||||||
|
class ToggleNoUpdatesModifierShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ClientEditor.toggleModifier(ModeModifier.NO_UPDATES)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.gamemode
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.client.util.ChatUtil
|
||||||
|
|
||||||
|
class CreativeModeShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ChatUtil.sendCommand("/gamemode creative", client, false)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.gamemode
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.client.util.ChatUtil
|
||||||
|
|
||||||
|
class SpectatorModeShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ChatUtil.sendCommand("/gamemode spectator", client, false)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.keybindings.impl.gamemode
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.option.KeyBinding
|
||||||
|
import net.moonleay.gimbal.client.keybindings.impl.GimbalShortcut
|
||||||
|
import net.moonleay.gimbal.client.util.ChatUtil
|
||||||
|
|
||||||
|
|
||||||
|
class SurvivalModeShortcut(key: KeyBinding) : GimbalShortcut(key) {
|
||||||
|
|
||||||
|
override fun onPressed(client: MinecraftClient) {
|
||||||
|
ChatUtil.sendCommand("/gamemode survival", client, false)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.screen
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screen.Screen
|
||||||
|
import net.minecraft.client.gui.widget.ButtonWidget
|
||||||
|
import net.minecraft.client.util.math.MatrixStack
|
||||||
|
import net.minecraft.screen.ScreenTexts
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
import net.moonleay.gimbal.client.config.ClientConfigHolder
|
||||||
|
import net.moonleay.gimbal.client.config.GimbalClientConfig
|
||||||
|
import net.moonleay.gimbal.client.config.GimbalGuiSettings
|
||||||
|
import net.moonleay.gimbal.client.config.ScaledRes
|
||||||
|
import net.moonleay.gimbal.client.util.screen.ScreenUtil
|
||||||
|
import net.moonleay.gimbal.constants.TranslationKeys
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
|
||||||
|
class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfigHolder) :
|
||||||
|
Screen(Text.translatable(TranslationKeys.Gui.Config.Hud.EDIT_HUD)) {
|
||||||
|
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
||||||
|
|
||||||
|
private var tempXOffset = 4.0
|
||||||
|
private var tempYOffset = 4.0
|
||||||
|
private var shouldFollow = false
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.tempXOffset = cfg.config.guiSettings.offset.scaledX
|
||||||
|
this.tempYOffset = cfg.config.guiSettings.offset.scaledY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
super.init()
|
||||||
|
this.addDrawableChild(ButtonWidget(
|
||||||
|
this.width / 2 + 10, this.height - 27, 90, 20, Text.translatable(TranslationKeys.Gui.Config.Hud.RESET_HUD)
|
||||||
|
) { _: ButtonWidget? ->
|
||||||
|
tempXOffset = 4.0
|
||||||
|
tempYOffset = 4.0
|
||||||
|
shouldFollow = false
|
||||||
|
})
|
||||||
|
|
||||||
|
this.addDrawableChild(ButtonWidget(
|
||||||
|
this.width / 2 - 100, this.height - 27, 90, 20, ScreenTexts.DONE
|
||||||
|
) { _: ButtonWidget? ->
|
||||||
|
this.save()
|
||||||
|
this.client!!.setScreen(
|
||||||
|
this.parent
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun save() {
|
||||||
|
val oldConf = cfg.config
|
||||||
|
if (ScreenUtil.isPositionOutOfBounds(this.tempXOffset, this.tempYOffset)) {
|
||||||
|
LOGGER.info("Text is not in bounds. This will not be saved in order to keep the user from making the hud inaccessible.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
LOGGER.info("Saving Pos...")
|
||||||
|
|
||||||
|
val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset)
|
||||||
|
|
||||||
|
val newConf = GimbalClientConfig(
|
||||||
|
guiSettings = GimbalGuiSettings(
|
||||||
|
showHud = oldConf.guiSettings.showHud,
|
||||||
|
offset = ScaledRes(
|
||||||
|
scaledX = this.tempXOffset,
|
||||||
|
scaledY = this.tempYOffset,
|
||||||
|
),
|
||||||
|
horizontalAnchor = anchor.first,
|
||||||
|
verticalAnchor = anchor.second,
|
||||||
|
hudOptions = oldConf.guiSettings.hudOptions
|
||||||
|
),
|
||||||
|
toastSettings = oldConf.toastSettings,
|
||||||
|
playerFlySpeed = oldConf.playerFlySpeed,
|
||||||
|
shouldEscResetMode = oldConf.shouldEscResetMode,
|
||||||
|
defaultMode = oldConf.defaultMode
|
||||||
|
)
|
||||||
|
|
||||||
|
cfg.updateConfig(newConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
this.save()
|
||||||
|
this.client!!.setScreen(this.parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
super.tick()
|
||||||
|
if (this.shouldFollow) {
|
||||||
|
val mouse = this.client?.mouse!!
|
||||||
|
val wantedX = ScreenUtil.getScaled(this.client!!.window.width, mouse.x.toFloat())
|
||||||
|
val wantedY = ScreenUtil.getScaled(this.client!!.window.height, mouse.y.toFloat())
|
||||||
|
if (!ScreenUtil.isPositionOutOfBounds(wantedX, wantedY)) {
|
||||||
|
this.tempXOffset = wantedX
|
||||||
|
this.tempYOffset = wantedY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||||
|
this.shouldFollow = true
|
||||||
|
return super.mouseClicked(mouseX, mouseY, button)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||||
|
this.shouldFollow = false
|
||||||
|
return super.mouseReleased(mouseX, mouseY, button)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
|
||||||
|
this.renderBackground(matrices)
|
||||||
|
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215)
|
||||||
|
val scaleFactor = this.client!!.window.calculateScaleFactor(
|
||||||
|
this.client!!.options.guiScale.value,
|
||||||
|
this.client!!.forcesUnicodeFont()
|
||||||
|
)
|
||||||
|
val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset)
|
||||||
|
this.textRenderer.drawWithShadow(
|
||||||
|
matrices,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.Hud.EXAMPLE_HUD_TEXT),
|
||||||
|
ScreenUtil.getXForAnchor(
|
||||||
|
ScreenUtil.getReal(this.client!!.window.width, this.tempXOffset) / scaleFactor,
|
||||||
|
anchor.first,
|
||||||
|
this.textRenderer.getWidth(Text.translatable(TranslationKeys.Gui.Config.Hud.EXAMPLE_HUD_TEXT))
|
||||||
|
),
|
||||||
|
ScreenUtil.getYForAnchor(
|
||||||
|
ScreenUtil.getReal(this.client!!.window.height, this.tempYOffset) / scaleFactor,
|
||||||
|
anchor.second,
|
||||||
|
this.textRenderer.fontHeight
|
||||||
|
),
|
||||||
|
0xFFFFFF
|
||||||
|
)
|
||||||
|
super.render(matrices, mouseX, mouseY, delta)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,290 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.screen
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screen.Screen
|
||||||
|
import net.minecraft.client.gui.widget.ButtonWidget
|
||||||
|
import net.minecraft.client.gui.widget.CyclingButtonWidget
|
||||||
|
import net.minecraft.client.util.math.MatrixStack
|
||||||
|
import net.minecraft.screen.ScreenTexts
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.moonleay.gimbal.client.config.ClientConfigHolder
|
||||||
|
import net.moonleay.gimbal.client.config.GimbalClientConfig
|
||||||
|
import net.moonleay.gimbal.client.config.GimbalGuiSettings
|
||||||
|
import net.moonleay.gimbal.client.config.enums.HudOptions
|
||||||
|
import net.moonleay.gimbal.client.config.enums.ToastSettings
|
||||||
|
import net.moonleay.gimbal.client.screen.widgets.GimbalSliderWidget
|
||||||
|
import net.moonleay.gimbal.client.util.NumberUtil
|
||||||
|
import net.moonleay.gimbal.constants.TranslationKeys
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
|
||||||
|
class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfigHolder) :
|
||||||
|
Screen(Text.translatable(TranslationKeys.Gui.Config.SCREEN_NAME)) {
|
||||||
|
|
||||||
|
private var hudOptions: HudOptions
|
||||||
|
private var toastSettings: ToastSettings
|
||||||
|
private var playerFlySpeed: Int
|
||||||
|
private var defaultMode: Mode
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.hudOptions = cfg.config.guiSettings.hudOptions
|
||||||
|
this.toastSettings = cfg.config.toastSettings
|
||||||
|
this.playerFlySpeed = cfg.config.playerFlySpeed
|
||||||
|
this.defaultMode = cfg.config.defaultMode
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
this.addDrawableChild(CyclingButtonWidget.onOffBuilder(
|
||||||
|
// Text.translatable("gimbal.gui.enabled"),
|
||||||
|
// Text.translatable("gimbal.gui.disabled")
|
||||||
|
)
|
||||||
|
.initially(cfg.config.guiSettings.showHud)
|
||||||
|
.build(
|
||||||
|
this.width / 2 - 155,
|
||||||
|
this.height / 6 + 24 * 0,
|
||||||
|
150,
|
||||||
|
20,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.Hud.SHOW_HUD)
|
||||||
|
) { _: CyclingButtonWidget<Boolean?>?, isEnabled: Boolean? ->
|
||||||
|
val oldGui = cfg.config.guiSettings
|
||||||
|
val newGui = GimbalGuiSettings(
|
||||||
|
showHud = isEnabled ?: true,
|
||||||
|
offset = oldGui.offset,
|
||||||
|
horizontalAnchor = oldGui.horizontalAnchor,
|
||||||
|
verticalAnchor = oldGui.verticalAnchor,
|
||||||
|
hudOptions = oldGui.hudOptions
|
||||||
|
)
|
||||||
|
val newConf = GimbalClientConfig(
|
||||||
|
guiSettings = newGui,
|
||||||
|
toastSettings = cfg.config.toastSettings,
|
||||||
|
playerFlySpeed = cfg.config.playerFlySpeed,
|
||||||
|
shouldEscResetMode = cfg.config.shouldEscResetMode,
|
||||||
|
defaultMode = cfg.config.defaultMode
|
||||||
|
)
|
||||||
|
cfg.updateConfig(newConf)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.addDrawableChild(ButtonWidget(
|
||||||
|
this.width / 2 - 155 + 160,
|
||||||
|
this.height / 6 + 24 * 0,
|
||||||
|
150,
|
||||||
|
20,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.Hud.EDIT_HUD)
|
||||||
|
) { _: ButtonWidget? ->
|
||||||
|
this.client!!.setScreen(GimbalEditHudGui(this, cfg))
|
||||||
|
})
|
||||||
|
|
||||||
|
this.addDrawableChild<CyclingButtonWidget<HudOptions>>(
|
||||||
|
CyclingButtonWidget.builder<HudOptions> { value: HudOptions? ->
|
||||||
|
when (value) {
|
||||||
|
HudOptions.ALL -> {
|
||||||
|
return@builder HudOptions.ALL.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
HudOptions.NUMBER -> {
|
||||||
|
return@builder HudOptions.NUMBER.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
HudOptions.INITIAL -> {
|
||||||
|
return@builder HudOptions.INITIAL.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
HudOptions.ONLY_MODE -> {
|
||||||
|
return@builder HudOptions.ONLY_MODE.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> return@builder Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.values(HudOptions.entries)
|
||||||
|
.initially(this.hudOptions)
|
||||||
|
.build(
|
||||||
|
this.width / 2 - 155,
|
||||||
|
this.height / 6 + 24 * 1,
|
||||||
|
150,
|
||||||
|
20,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODIFIERS)
|
||||||
|
) { _: CyclingButtonWidget<HudOptions>?, hudDO: HudOptions ->
|
||||||
|
this.hudOptions = hudDO
|
||||||
|
|
||||||
|
val oldConfig = cfg.config
|
||||||
|
val oldGuiConfig = oldConfig.guiSettings
|
||||||
|
val newConfig = GimbalClientConfig(
|
||||||
|
guiSettings = GimbalGuiSettings(
|
||||||
|
horizontalAnchor = oldGuiConfig.horizontalAnchor,
|
||||||
|
verticalAnchor = oldGuiConfig.verticalAnchor,
|
||||||
|
showHud = oldGuiConfig.showHud,
|
||||||
|
offset = oldGuiConfig.offset,
|
||||||
|
hudOptions = this.hudOptions
|
||||||
|
),
|
||||||
|
toastSettings = oldConfig.toastSettings,
|
||||||
|
playerFlySpeed = oldConfig.playerFlySpeed,
|
||||||
|
shouldEscResetMode = oldConfig.shouldEscResetMode,
|
||||||
|
defaultMode = oldConfig.defaultMode
|
||||||
|
)
|
||||||
|
cfg.updateConfig(newConfig)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
this.addDrawableChild<CyclingButtonWidget<ToastSettings>>(
|
||||||
|
CyclingButtonWidget.builder<ToastSettings> { value: ToastSettings? ->
|
||||||
|
when (value) {
|
||||||
|
ToastSettings.ALL -> {
|
||||||
|
return@builder ToastSettings.ALL.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
ToastSettings.ONLY_TOGGLE -> {
|
||||||
|
return@builder ToastSettings.ONLY_TOGGLE.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
ToastSettings.ONLY_SYSTEM -> {
|
||||||
|
return@builder ToastSettings.ONLY_SYSTEM.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
ToastSettings.NONE -> {
|
||||||
|
return@builder ToastSettings.NONE.translatableText
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> return@builder Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.values(ToastSettings.entries)
|
||||||
|
.initially(this.toastSettings)
|
||||||
|
.build(
|
||||||
|
this.width / 2 - 155 + 160,
|
||||||
|
this.height / 6 + 24 * 1,
|
||||||
|
150,
|
||||||
|
20,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_TOASTS)
|
||||||
|
) { _: CyclingButtonWidget<ToastSettings>?, toastStng: ToastSettings ->
|
||||||
|
this.toastSettings = toastStng
|
||||||
|
|
||||||
|
val oldConfig = cfg.config
|
||||||
|
val newConfig = GimbalClientConfig(
|
||||||
|
guiSettings = oldConfig.guiSettings,
|
||||||
|
toastSettings = this.toastSettings,
|
||||||
|
playerFlySpeed = oldConfig.playerFlySpeed,
|
||||||
|
shouldEscResetMode = oldConfig.shouldEscResetMode,
|
||||||
|
defaultMode = oldConfig.defaultMode
|
||||||
|
)
|
||||||
|
cfg.updateConfig(newConfig)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addDrawableChild(GimbalSliderWidget(
|
||||||
|
this.width / 2 - 155,
|
||||||
|
this.height / 6 + 24 * 2,
|
||||||
|
150,
|
||||||
|
20,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.PLAYER_FLY_SPEED),
|
||||||
|
NumberUtil.linearInterpolate(this.playerFlySpeed.toDouble(), 100.0, 1000.0, 0.0, 1.0),
|
||||||
|
100.0,
|
||||||
|
1000.0,
|
||||||
|
) { value ->
|
||||||
|
this.playerFlySpeed = NumberUtil.linearInterpolate(value, 0.0, 1.0, 100.0, 1000.0).toInt()
|
||||||
|
|
||||||
|
if (client!!.player != null && client!!.player!!.isCreative) {
|
||||||
|
client!!.player!!.abilities.flySpeed = (this.playerFlySpeed / 100) * 0.05f
|
||||||
|
}
|
||||||
|
|
||||||
|
val oldConfig = cfg.config
|
||||||
|
val newConfig = GimbalClientConfig(
|
||||||
|
guiSettings = oldConfig.guiSettings,
|
||||||
|
toastSettings = this.toastSettings,
|
||||||
|
playerFlySpeed = this.playerFlySpeed,
|
||||||
|
shouldEscResetMode = oldConfig.shouldEscResetMode,
|
||||||
|
defaultMode = oldConfig.defaultMode
|
||||||
|
)
|
||||||
|
cfg.updateConfig(newConfig)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.addDrawableChild(CyclingButtonWidget.onOffBuilder()
|
||||||
|
.initially(cfg.config.shouldEscResetMode)
|
||||||
|
.build(
|
||||||
|
this.width / 2 - 155,
|
||||||
|
this.height / 6 + 24 * 3,
|
||||||
|
150,
|
||||||
|
20,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.SHOULD_ESC_RESET_MODE)
|
||||||
|
) { _: CyclingButtonWidget<Boolean?>?, isEnabled: Boolean? ->
|
||||||
|
val newConf = GimbalClientConfig(
|
||||||
|
guiSettings = cfg.config.guiSettings,
|
||||||
|
toastSettings = cfg.config.toastSettings,
|
||||||
|
playerFlySpeed = cfg.config.playerFlySpeed,
|
||||||
|
shouldEscResetMode = isEnabled?: true,
|
||||||
|
defaultMode = cfg.config.defaultMode
|
||||||
|
)
|
||||||
|
cfg.updateConfig(newConf)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.addDrawableChild<CyclingButtonWidget<Mode>>(
|
||||||
|
CyclingButtonWidget.builder<Mode> { value: Mode? ->
|
||||||
|
if (value == null) {
|
||||||
|
return@builder Text.literal(Mode.UNKNOWN.displayName)
|
||||||
|
}
|
||||||
|
return@builder Text.literal(value.displayName)
|
||||||
|
}
|
||||||
|
.values(Mode.entries)
|
||||||
|
.initially(this.defaultMode)
|
||||||
|
.build(
|
||||||
|
this.width / 2 - 155 + 160,
|
||||||
|
this.height / 6 + 24 * 3,
|
||||||
|
150,
|
||||||
|
20,
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.DEFAULT_MODE)
|
||||||
|
) { b: CyclingButtonWidget<Mode>?, requestedMode: Mode ->
|
||||||
|
if (requestedMode.hidden){
|
||||||
|
b!!.value = Mode.NORMAL
|
||||||
|
this.defaultMode = Mode.NORMAL
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.defaultMode = requestedMode
|
||||||
|
}
|
||||||
|
|
||||||
|
val oldConfig = cfg.config
|
||||||
|
val newConfig = GimbalClientConfig(
|
||||||
|
guiSettings = oldConfig.guiSettings,
|
||||||
|
toastSettings = oldConfig.toastSettings,
|
||||||
|
playerFlySpeed = oldConfig.playerFlySpeed,
|
||||||
|
shouldEscResetMode = oldConfig.shouldEscResetMode,
|
||||||
|
defaultMode = this.defaultMode
|
||||||
|
)
|
||||||
|
cfg.updateConfig(newConfig)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Done button
|
||||||
|
this.addDrawableChild(ButtonWidget(
|
||||||
|
this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE
|
||||||
|
) { _: ButtonWidget? ->
|
||||||
|
this.client!!.setScreen(
|
||||||
|
this.parent
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
|
||||||
|
this.renderBackground(matrices)
|
||||||
|
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215)
|
||||||
|
super.render(matrices, mouseX, mouseY, delta)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.screen.widgets
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.widget.SliderWidget
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.moonleay.gimbal.client.util.NumberUtil
|
||||||
|
|
||||||
|
class GimbalSliderWidget(
|
||||||
|
x: Int,
|
||||||
|
y: Int,
|
||||||
|
width: Int,
|
||||||
|
height: Int,
|
||||||
|
private val text: Text,
|
||||||
|
value: Double,
|
||||||
|
private val lowerEnd: Double,
|
||||||
|
private val upperEnd: Double,
|
||||||
|
private val setValue: (Double) -> Unit,
|
||||||
|
) :
|
||||||
|
SliderWidget(x, y, width, height, text, value) {
|
||||||
|
init {
|
||||||
|
this.message = this.text.copy()
|
||||||
|
.append(": " + (NumberUtil.linearInterpolate(this.value, 0.0, 1.0, this.lowerEnd, this.upperEnd).toInt()))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateMessage() {
|
||||||
|
this.message = this.text.copy()
|
||||||
|
.append(": " + (NumberUtil.linearInterpolate(this.value, 0.0, 1.0, this.lowerEnd, this.upperEnd).toInt()))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun applyValue() {
|
||||||
|
this.setValue(this.value)
|
||||||
|
}
|
||||||
|
}
|
54
src/main/java/net/moonleay/gimbal/client/util/ChatUtil.kt
Normal file
54
src/main/java/net/moonleay/gimbal/client/util/ChatUtil.kt
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.util
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.toast.SystemToast
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.moonleay.gimbal.client.config.GimbalClientConfig
|
||||||
|
|
||||||
|
object ChatUtil {
|
||||||
|
/**
|
||||||
|
* Note: command arg should contain "/" at the beginning.
|
||||||
|
* */
|
||||||
|
fun sendCommand(command: String, client: MinecraftClient, addToHistory: Boolean = true): Boolean {
|
||||||
|
if (addToHistory) {
|
||||||
|
client.inGameHud.chatHud.addToMessageHistory(command)
|
||||||
|
}
|
||||||
|
return client.player?.sendCommand(command.substring(1))?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addToChatHistory(message: String, client: MinecraftClient) {
|
||||||
|
client.inGameHud.chatHud.addMessage(Text.of(message))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showToastToSelf(
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
type: ToastType,
|
||||||
|
config: GimbalClientConfig,
|
||||||
|
client: MinecraftClient,
|
||||||
|
) {
|
||||||
|
if (!config.toastSettings.allowedTypes.contains(type))
|
||||||
|
return
|
||||||
|
|
||||||
|
val toast = SystemToast(SystemToast.Type.PERIODIC_NOTIFICATION, Text.of(title), Text.of(description))
|
||||||
|
client.toastManager.add(toast)
|
||||||
|
}
|
||||||
|
}
|
44
src/main/java/net/moonleay/gimbal/client/util/NumberUtil.kt
Normal file
44
src/main/java/net/moonleay/gimbal/client/util/NumberUtil.kt
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.util
|
||||||
|
|
||||||
|
object NumberUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpolate a number between two numbers in a linear way
|
||||||
|
*/
|
||||||
|
fun linearInterpolate(number: Double, min: Double, max: Double, lowerEnd: Double, upperEnd: Double): Double {
|
||||||
|
val subtractFromNr = (0 - min) * -1
|
||||||
|
val minMaxDiff = max - min
|
||||||
|
val onePercent = minMaxDiff / 100.0
|
||||||
|
val percentOfNumber = (number - subtractFromNr) / onePercent
|
||||||
|
|
||||||
|
val toAddToLowerEnd = (0 - lowerEnd) * -1
|
||||||
|
val upperLowerDiff = upperEnd - lowerEnd
|
||||||
|
val onePercentOfEnd = upperLowerDiff / 100.0
|
||||||
|
return (percentOfNumber * onePercentOfEnd) + toAddToLowerEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpolate a number between two numbers in a logarithmic way
|
||||||
|
*/
|
||||||
|
fun logarithmicInterpolate(number: Double, min: Double, max: Double, lowerEnd: Double, upperEnd: Double): Double {
|
||||||
|
TODO("Not impl.")
|
||||||
|
}
|
||||||
|
}
|
24
src/main/java/net/moonleay/gimbal/client/util/ToastType.kt
Normal file
24
src/main/java/net/moonleay/gimbal/client/util/ToastType.kt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.util
|
||||||
|
|
||||||
|
enum class ToastType {
|
||||||
|
TOGGLE,
|
||||||
|
SYSTEM,
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.client.util.screen
|
||||||
|
|
||||||
|
import net.moonleay.gimbal.client.config.enums.HorizontalAnchor
|
||||||
|
import net.moonleay.gimbal.client.config.enums.VerticalAnchor
|
||||||
|
|
||||||
|
object ScreenUtil {
|
||||||
|
|
||||||
|
fun getAnchor(x: Double, y: Double): Pair<HorizontalAnchor, VerticalAnchor> {
|
||||||
|
return when (x) {
|
||||||
|
in 0.0..<34.0 -> HorizontalAnchor.LEFT
|
||||||
|
in 34.0..<67.0 -> HorizontalAnchor.CENTER
|
||||||
|
else -> HorizontalAnchor.RIGHT
|
||||||
|
} to when (y) {
|
||||||
|
in 0.0..<34.0 -> VerticalAnchor.TOP
|
||||||
|
in 34.0..<67.0 -> VerticalAnchor.CENTER
|
||||||
|
else -> VerticalAnchor.BOTTOM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getXForAnchor(x: Float, anchor: HorizontalAnchor, textWidth: Int): Float {
|
||||||
|
return when (anchor) {
|
||||||
|
HorizontalAnchor.LEFT -> x
|
||||||
|
HorizontalAnchor.CENTER -> x - (textWidth / 2)
|
||||||
|
HorizontalAnchor.RIGHT -> x - textWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getYForAnchor(y: Float, anchor: VerticalAnchor, textHeight: Int): Float {
|
||||||
|
return when (anchor) {
|
||||||
|
VerticalAnchor.TOP -> y
|
||||||
|
VerticalAnchor.CENTER -> y - (textHeight / 2)
|
||||||
|
VerticalAnchor.BOTTOM -> y - textHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getScaled(length: Int, real: Float): Double {
|
||||||
|
val scale = length / 100.0
|
||||||
|
return real / scale
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getReal(length: Int, scaled: Double): Float {
|
||||||
|
val scale = length / 100.0
|
||||||
|
return (scaled * scale).toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isPositionOutOfBounds(x: Double, y: Double): Boolean {
|
||||||
|
val tooBig = 100 < x || 100 < y
|
||||||
|
val tooSmall = 0 > x || 0 > y
|
||||||
|
return tooBig || tooSmall
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
28
src/main/java/net/moonleay/gimbal/constants/PacketIDs.kt
Normal file
28
src/main/java/net/moonleay/gimbal/constants/PacketIDs.kt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.constants
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
|
||||||
|
object PacketIDs {
|
||||||
|
val UPDATE_EDITOR_STATE_ID = Identifier(BuildConstants.modId, "update_editor_state")
|
||||||
|
val GIMBAL_POLICY_PACKET_ID = Identifier(BuildConstants.modId, "gimbal_policy")
|
||||||
|
|
||||||
|
}
|
23
src/main/java/net/moonleay/gimbal/constants/PermissionIDs.kt
Normal file
23
src/main/java/net/moonleay/gimbal/constants/PermissionIDs.kt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.constants
|
||||||
|
|
||||||
|
object PermissionIDs {
|
||||||
|
const val GIMBAL_USAGE_PERMISSION = "gimbal.use"
|
||||||
|
}
|
127
src/main/java/net/moonleay/gimbal/constants/TranslationKeys.kt
Normal file
127
src/main/java/net/moonleay/gimbal/constants/TranslationKeys.kt
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.constants
|
||||||
|
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
|
||||||
|
object TranslationKeys {
|
||||||
|
object Gui {
|
||||||
|
const val BASE = "gui.${BuildConstants.modId}."
|
||||||
|
|
||||||
|
object Config {
|
||||||
|
const val BASE = "${TranslationKeys.Gui.BASE}conf."
|
||||||
|
|
||||||
|
const val SCREEN_NAME = "${BASE}settings"
|
||||||
|
const val GENERIC_ENABLED = "${BASE}enabled"
|
||||||
|
const val GENERIC_DISABLED = "${BASE}disabled"
|
||||||
|
|
||||||
|
const val PLAYER_FLY_SPEED = "${BASE}flySpeed"
|
||||||
|
const val SHOULD_ESC_RESET_MODE = "${BASE}shouldESCResetMode"
|
||||||
|
const val DEFAULT_MODE = "${BASE}defaultMode"
|
||||||
|
|
||||||
|
object Hud {
|
||||||
|
const val BASE = "${TranslationKeys.Gui.Config.BASE}hud."
|
||||||
|
|
||||||
|
const val SHOW_HUD = "${BASE}show"
|
||||||
|
const val EDIT_HUD = "${BASE}edit"
|
||||||
|
const val RESET_HUD = "${BASE}reset"
|
||||||
|
const val EXAMPLE_HUD_TEXT = "${BASE}example"
|
||||||
|
|
||||||
|
object Modifiers {
|
||||||
|
const val BASE = "${TranslationKeys.Gui.Config.Hud.BASE}modifiers."
|
||||||
|
|
||||||
|
const val SHOW_MODIFIERS = "${BASE}show"
|
||||||
|
const val SHOW_ALL = "${BASE}all"
|
||||||
|
const val SHOW_NUMBER = "${BASE}number"
|
||||||
|
const val SHOW_INITIALS = "${BASE}initials"
|
||||||
|
const val SHOW_MODE_ONLY = "${BASE}modeOnly"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Toasts {
|
||||||
|
const val BASE = "${TranslationKeys.Gui.Config.BASE}toasts."
|
||||||
|
|
||||||
|
const val SHOW_TOASTS = "${BASE}show"
|
||||||
|
const val SHOW_ALL = "${BASE}all"
|
||||||
|
const val SHOW_TOGGLE = "${BASE}toggle"
|
||||||
|
const val SHOW_SYSTEM = "${BASE}system"
|
||||||
|
const val SHOW_NONE = "${BASE}none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Keybindings {
|
||||||
|
// No base here, Categories and Bindings have separate BASEs
|
||||||
|
object Category {
|
||||||
|
const val BASE = "category.${BuildConstants.modId}."
|
||||||
|
|
||||||
|
object Editor {
|
||||||
|
const val BASE = "${TranslationKeys.Keybindings.Category.BASE}editor."
|
||||||
|
|
||||||
|
const val MODE = "${BASE}mode"
|
||||||
|
const val MODIFIER = "${BASE}modifier"
|
||||||
|
}
|
||||||
|
|
||||||
|
object Game {
|
||||||
|
const val BASE = "${TranslationKeys.Keybindings.Category.BASE}game."
|
||||||
|
|
||||||
|
const val GAMEMODE = "${BASE}mode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Binding {
|
||||||
|
const val BASE = "key.${BuildConstants.modId}."
|
||||||
|
|
||||||
|
object Editor {
|
||||||
|
const val BASE = "${TranslationKeys.Keybindings.Binding.BASE}editor."
|
||||||
|
|
||||||
|
object Mode {
|
||||||
|
const val BASE = "${TranslationKeys.Keybindings.Binding.Editor.BASE}mode."
|
||||||
|
|
||||||
|
const val INSERT = "${BASE}insert"
|
||||||
|
const val REPLACE = "${BASE}replace"
|
||||||
|
const val VISUAL = "${BASE}visual"
|
||||||
|
}
|
||||||
|
|
||||||
|
object Modifier {
|
||||||
|
const val BASE = "${TranslationKeys.Keybindings.Binding.Editor.BASE}modifier."
|
||||||
|
|
||||||
|
const val BULLDOZER = "${BASE}autoClicker"
|
||||||
|
const val FORCE_PLACE = "${BASE}forcePlace"
|
||||||
|
const val NO_UPDATES = "${BASE}noUpdates"
|
||||||
|
const val NO_CLIP = "${BASE}noClip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Game {
|
||||||
|
const val BASE = "${TranslationKeys.Keybindings.Binding.BASE}game."
|
||||||
|
|
||||||
|
object Mode {
|
||||||
|
const val BASE = "${TranslationKeys.Keybindings.Binding.Game.BASE}mode."
|
||||||
|
|
||||||
|
const val SURVIVAL = "${BASE}survival"
|
||||||
|
const val CREATIVE = "${BASE}creative"
|
||||||
|
const val SPECTATOR = "${BASE}spectator"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
33
src/main/java/net/moonleay/gimbal/datagen/DataGenerator.kt
Normal file
33
src/main/java/net/moonleay/gimbal/datagen/DataGenerator.kt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.datagen
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
|
||||||
|
internal class DataGenerator : DataGeneratorEntrypoint {
|
||||||
|
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
||||||
|
|
||||||
|
override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) {
|
||||||
|
LOGGER.info("Starting Data Generation")
|
||||||
|
fabricDataGenerator.addProvider(EnUsLanguageProvider(fabricDataGenerator))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.datagen
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider
|
||||||
|
import net.moonleay.gimbal.constants.TranslationKeys
|
||||||
|
|
||||||
|
class EnUsLanguageProvider(dataGenerator: FabricDataGenerator?) :
|
||||||
|
FabricLanguageProvider(dataGenerator, "en_us") {
|
||||||
|
|
||||||
|
override fun generateTranslations(translationBuilder: TranslationBuilder?) {
|
||||||
|
if (translationBuilder == null) return
|
||||||
|
/// Screens
|
||||||
|
// Gimbal settings screen
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.SCREEN_NAME, "Gimbal Settings")
|
||||||
|
|
||||||
|
// Hud
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.SHOW_HUD, "Show HUD")
|
||||||
|
|
||||||
|
|
||||||
|
//Gimbal HUD pos edit
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.EDIT_HUD, "Edit HUD Layout...")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.RESET_HUD, "Reset Layout")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.EXAMPLE_HUD_TEXT, "EXAMPLE [No Clip, Force]")
|
||||||
|
|
||||||
|
//Gimbal HUD Content
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODIFIERS, "Show Modifiers")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_ALL, "All")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_NUMBER, "Number")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_INITIALS, "Short")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODE_ONLY, "None")
|
||||||
|
|
||||||
|
//Gimbal Toasts
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_TOASTS, "Show Toasts")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_ALL, "All")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_TOGGLE, "Only Toggle")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_SYSTEM, "Only System")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_NONE, "None")
|
||||||
|
|
||||||
|
// Gimbal Generic Settings
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.PLAYER_FLY_SPEED, "Fly Speed")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.SHOULD_ESC_RESET_MODE, "ESC Resets Mode")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.DEFAULT_MODE, "Default Mode")
|
||||||
|
|
||||||
|
// Gimbal Generic Gui
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.GENERIC_ENABLED, "Enabled")
|
||||||
|
translationBuilder.add(TranslationKeys.Gui.Config.GENERIC_DISABLED, "Disabled")
|
||||||
|
|
||||||
|
/// Options
|
||||||
|
// Editor modes
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Category.Editor.MODE, "Editor Modes")
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Mode.INSERT, "Enter Insert Mode")
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Mode.REPLACE, "Enter Replace Mode")
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Mode.VISUAL, "Enter Visual Mode")
|
||||||
|
|
||||||
|
// Editor mode modifiers
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Category.Editor.MODIFIER, "Editor Mode Modifiers")
|
||||||
|
translationBuilder.add(
|
||||||
|
TranslationKeys.Keybindings.Binding.Editor.Modifier.BULLDOZER,
|
||||||
|
"Toggle Bulldozer Modifier"
|
||||||
|
)
|
||||||
|
translationBuilder.add(
|
||||||
|
TranslationKeys.Keybindings.Binding.Editor.Modifier.FORCE_PLACE,
|
||||||
|
"Toggle Force Place Modifier"
|
||||||
|
)
|
||||||
|
translationBuilder.add(
|
||||||
|
TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_UPDATES,
|
||||||
|
"Toggle No Updates Modifier"
|
||||||
|
)
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_CLIP, "Toggle No Clip Modifier")
|
||||||
|
|
||||||
|
// Game mode
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Category.Game.GAMEMODE, "Game Mode")
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Binding.Game.Mode.SURVIVAL, "Enable Survival Mode")
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Binding.Game.Mode.CREATIVE, "Enable Creative Mode")
|
||||||
|
translationBuilder.add(TranslationKeys.Keybindings.Binding.Game.Mode.SPECTATOR, "Enable Spectator Mode")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor
|
||||||
|
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants
|
||||||
|
import net.moonleay.gimbal.editor.state.EditorState
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Capability
|
||||||
|
import net.moonleay.gimbal.editor.util.EditorUtil
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object ServerEditorManager {
|
||||||
|
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
||||||
|
|
||||||
|
private val STATEMAP = mutableMapOf<UUID, EditorState>()
|
||||||
|
|
||||||
|
fun updateEditorState(playerUUID: UUID, editorState: EditorState) {
|
||||||
|
STATEMAP[playerUUID] = editorState
|
||||||
|
LOGGER.debug("{}: {} with {}", playerUUID, editorState.editorMode, editorState.editorModifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if a player should be able to perform an action
|
||||||
|
* */
|
||||||
|
fun shouldPlayer(playerUUID: UUID, capability: Capability): Boolean {
|
||||||
|
if (!STATEMAP.containsKey(playerUUID))
|
||||||
|
return 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,29 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.state
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.ModeModifier
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class EditorState(
|
||||||
|
var editorMode: Mode,
|
||||||
|
var editorModifier: MutableList<ModeModifier>,
|
||||||
|
)
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.state
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
enum class GimbalPolicyType {
|
||||||
|
ALLOWED,
|
||||||
|
DENIED,
|
||||||
|
NOT_PRESENT,
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.state
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GimbalServerState(
|
||||||
|
val protocolVersion: Int,
|
||||||
|
val policyType: GimbalPolicyType,
|
||||||
|
)
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.state.mode
|
||||||
|
|
||||||
|
enum class Capability {
|
||||||
|
INSERT,
|
||||||
|
REPLACE,
|
||||||
|
CAN_INTERACT,
|
||||||
|
NO_CLIP,
|
||||||
|
FORCE_PLACE,
|
||||||
|
NO_UPDATES,
|
||||||
|
BULLDOZER,
|
||||||
|
}
|
28
src/main/java/net/moonleay/gimbal/editor/state/mode/Mode.kt
Normal file
28
src/main/java/net/moonleay/gimbal/editor/state/mode/Mode.kt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.state.mode
|
||||||
|
|
||||||
|
enum class Mode(val displayName: String, val color: Int, val hidden: Boolean, val incompatibleModifiers: List<ModeModifier>){
|
||||||
|
UNKNOWN("UNKNOWN", 0x000000, true, listOf()), // Unknown mode. This mode cannot be entered
|
||||||
|
NORMAL("NORMAL", 0x90a959, false, listOf(ModeModifier.NO_UPDATES, ModeModifier.BULLDOZER, ModeModifier.FORCE_PLACE)), // Do nothing
|
||||||
|
INSERT("INSERT", 0xf4bf75, false, listOf()), // Place and break blocks
|
||||||
|
REPLACE("REPLACE", 0xac4242, false, listOf(ModeModifier.NO_UPDATES)), // Replace blocks
|
||||||
|
// Add hidden modes after this comment
|
||||||
|
VISUAL("VISUAL", 0x6a9fb5, true, listOf(ModeModifier.BULLDOZER)), // Do fancy stuff with WE
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.state.mode
|
||||||
|
|
||||||
|
enum class ModeModifier(val displayName: String, val shortName: String) {
|
||||||
|
// NONE("None"), // No Modifiers - default behavior
|
||||||
|
NO_UPDATES("NO UPDATES", "NU"), // Do not update blocks when placing
|
||||||
|
BULLDOZER("BULLDOZER", "BLR"), // Break blocks fast
|
||||||
|
FORCE_PLACE("FORCE", "FP"), // Ignore block placement restrictions
|
||||||
|
NO_CLIP("NO CLIP", "NC"), // Do not collide with blocks
|
||||||
|
}
|
|
@ -1,9 +1,28 @@
|
||||||
package net.moonleay.gimble.editor.util
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.util
|
||||||
|
|
||||||
|
import net.moonleay.gimbal.editor.state.EditorState
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Capability
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Mode
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.ModeModifier
|
||||||
|
|
||||||
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 {
|
object EditorUtil {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.editor.util
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.moonleay.gimbal.editor.state.GimbalPolicyType
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GimbalPolicy(
|
||||||
|
val policy: GimbalPolicyType,
|
||||||
|
)
|
84
src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin.java
Normal file
84
src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin.java
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.network.ClientPlayerInteractionManager;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor;
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Capability;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public abstract class BulldozerMixin {
|
||||||
|
|
||||||
|
@Mixin(MinecraftClient.class)
|
||||||
|
public static abstract class MinecraftClientMixin {
|
||||||
|
@Shadow
|
||||||
|
@Nullable
|
||||||
|
public ClientPlayerEntity player;
|
||||||
|
@Shadow
|
||||||
|
protected int attackCooldown;
|
||||||
|
|
||||||
|
@Inject(method = "doAttack", at = @At(value = "HEAD"))
|
||||||
|
private void func(CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.player).isCreative()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.attackCooldown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "handleBlockBreaking", at = @At(value = "HEAD"))
|
||||||
|
private void func2(boolean breaking, CallbackInfo ci) {
|
||||||
|
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !breaking || !Objects.requireNonNull(this.player).isCreative()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.attackCooldown = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mixin(ClientPlayerInteractionManager.class)
|
||||||
|
public static abstract class ClientPlayerInteractionManagerMixin {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private int blockBreakingCooldown;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private MinecraftClient client;
|
||||||
|
|
||||||
|
@Inject(method = "updateBlockBreakingProgress", at = @At("HEAD"))
|
||||||
|
private void func(BlockPos pos, Direction direction, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.client.player).isCreative()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.blockBreakingCooldown = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,28 @@
|
||||||
package net.moonleay.gimble.mixin;
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
import net.moonleay.gimble.editor.ServerEditorManager;
|
import net.moonleay.gimbal.editor.ServerEditorManager;
|
||||||
import net.moonleay.gimble.editor.state.mode.Capability;
|
import net.moonleay.gimbal.editor.state.mode.Capability;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
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;
|
74
src/main/java/net/moonleay/gimbal/mixin/HudMixin.java
Normal file
74
src/main/java/net/moonleay/gimbal/mixin/HudMixin.java
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
|
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.gimbal.client.ClientMain;
|
||||||
|
import net.moonleay.gimbal.client.config.GimbalGuiSettings;
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor;
|
||||||
|
import net.moonleay.gimbal.client.util.screen.ScreenUtil;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(InGameHud.class)
|
||||||
|
public abstract class HudMixin {
|
||||||
|
|
||||||
|
@Shadow @Final private MinecraftClient client;
|
||||||
|
|
||||||
|
@Inject(method = "renderStatusEffectOverlay", at = @At("HEAD"))
|
||||||
|
private void render(MatrixStack matrices, CallbackInfo ci) {
|
||||||
|
TextRenderer tr = this.client.textRenderer;
|
||||||
|
GimbalGuiSettings conf = ClientMain.CONFIG.getConfig().getGuiSettings();
|
||||||
|
if (!conf.getShowHud())
|
||||||
|
return;
|
||||||
|
int scaleFactor = this.client.getWindow()
|
||||||
|
.calculateScaleFactor(
|
||||||
|
this.client.options.getGuiScale().getValue(),
|
||||||
|
this.client.forcesUnicodeFont()
|
||||||
|
);
|
||||||
|
Text displayText = ClientEditor.INSTANCE.getModeDisplayText(ClientMain.CONFIG.getConfig());
|
||||||
|
tr.drawWithShadow(
|
||||||
|
matrices,
|
||||||
|
displayText,
|
||||||
|
ScreenUtil.INSTANCE.getXForAnchor(
|
||||||
|
ScreenUtil.INSTANCE.getReal(
|
||||||
|
this.client.getWindow().getWidth(),
|
||||||
|
conf.getOffset().getScaledX() / scaleFactor),
|
||||||
|
conf.getHorizontalAnchor(),
|
||||||
|
this.client.textRenderer.getWidth(displayText)
|
||||||
|
),
|
||||||
|
ScreenUtil.INSTANCE.getYForAnchor(
|
||||||
|
ScreenUtil.INSTANCE.getReal(
|
||||||
|
this.client.getWindow().getHeight(),
|
||||||
|
conf.getOffset().getScaledY() / scaleFactor),
|
||||||
|
conf.getVerticalAnchor(),
|
||||||
|
this.client.textRenderer.fontHeight
|
||||||
|
),
|
||||||
|
ClientEditor.INSTANCE.getCurrentColor()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,29 @@
|
||||||
package net.moonleay.gimble.mixin;
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
import net.moonleay.gimble.editor.ServerEditorManager;
|
import net.moonleay.gimbal.editor.ServerEditorManager;
|
||||||
import net.moonleay.gimble.editor.state.mode.Capability;
|
import net.moonleay.gimbal.editor.state.mode.Capability;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
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;
|
106
src/main/java/net/moonleay/gimbal/mixin/NoClipMixin.java
Normal file
106
src/main/java/net/moonleay/gimbal/mixin/NoClipMixin.java
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.render.Camera;
|
||||||
|
import net.minecraft.entity.EntityPose;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerAbilities;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor;
|
||||||
|
import net.moonleay.gimbal.editor.ServerEditorManager;
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Capability;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class NoClipMixin {
|
||||||
|
|
||||||
|
@Mixin(PlayerEntity.class) // Serverside, allows clipping
|
||||||
|
public static abstract class PlayerEntityMixin extends LivingEntity {
|
||||||
|
protected PlayerEntityMixin(EntityType<? extends LivingEntity> entityType, World world) {
|
||||||
|
super(entityType, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract GameProfile getGameProfile();
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract PlayerAbilities getAbilities();
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract boolean isCreative();
|
||||||
|
|
||||||
|
@Inject(method = "tick", at = @At(value = "FIELD",
|
||||||
|
target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z", shift = At.Shift.AFTER)
|
||||||
|
)
|
||||||
|
private void enoClip(CallbackInfo ci) {
|
||||||
|
if (!this.isCreative())
|
||||||
|
return;
|
||||||
|
UUID uuid = this.getGameProfile().getId();
|
||||||
|
|
||||||
|
if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) {
|
||||||
|
return; // NoClip is not enabled
|
||||||
|
}
|
||||||
|
if (!this.getAbilities().flying) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Enable NoClip
|
||||||
|
this.noClip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "updatePose", at = @At("HEAD"))
|
||||||
|
private void onUpdatePose(CallbackInfo ci) {
|
||||||
|
UUID uuid = this.getGameProfile().getId();
|
||||||
|
|
||||||
|
if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP))
|
||||||
|
return; // NoClip is not enabled
|
||||||
|
if (!this.getAbilities().flying)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Force standing pose in NoClip mode
|
||||||
|
|
||||||
|
this.setPose(EntityPose.STANDING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(Camera.class) // Clientside, fixes camera
|
||||||
|
public static abstract class CameraMixin {
|
||||||
|
|
||||||
|
@Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void fixCameraInNoClip(double desiredCameraDistance, CallbackInfoReturnable<Double> cir) {
|
||||||
|
if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP) || (!(MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().player.isCreative()))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cir.setReturnValue(desiredCameraDistance);
|
||||||
|
cir.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,29 @@
|
||||||
package net.moonleay.gimble.mixin;
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
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.gimbal.client.ClientMain;
|
||||||
import net.moonleay.gimble.editor.state.mode.Capability;
|
import net.moonleay.gimbal.client.editor.ClientEditor;
|
||||||
import net.moonleay.gimble.editor.state.mode.Mode;
|
import net.moonleay.gimbal.editor.state.mode.Capability;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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;
|
||||||
|
@ -25,12 +43,12 @@ public class NormalModeMixin {
|
||||||
public ClientPlayerEntity player;
|
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 setDefaultMode(boolean pause, CallbackInfo ci) {
|
||||||
if (ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) {
|
if (ClientMain.CONFIG.getConfig().getShouldEscResetMode() && ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) {
|
||||||
assert this.player != null;
|
assert this.player != null;
|
||||||
if (this.player.isCreative()) {
|
if (this.player.isCreative()) {
|
||||||
// Set the editor mode to normal
|
// Set the editor mode to normal
|
||||||
ClientEditor.INSTANCE.setMode(Mode.NORMAL);
|
ClientEditor.INSTANCE.setMode(ClientMain.CONFIG.getConfig().getDefaultMode());
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
|
import net.minecraft.network.packet.s2c.play.PlayerAbilitiesS2CPacket;
|
||||||
|
import net.moonleay.gimbal.client.ClientMain;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(ClientPlayNetworkHandler.class)
|
||||||
|
public abstract class PlayerFlySpeedMixin {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private MinecraftClient client;
|
||||||
|
|
||||||
|
@Inject(method = "onPlayerAbilities", at = @At(value = "RETURN"))
|
||||||
|
private void func(PlayerAbilitiesS2CPacket packet, CallbackInfo ci) {
|
||||||
|
this.client.player.getAbilities().setFlySpeed((ClientMain.CONFIG.getConfig().getPlayerFlySpeed() / 100) * 0.05f);
|
||||||
|
//client!!.player!!.abilities.flySpeed = (this.playerFlySpeed / 100) * 0.05f
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
104
src/main/java/net/moonleay/gimbal/mixin/ReplaceModeMixin.java
Normal file
104
src/main/java/net/moonleay/gimbal/mixin/ReplaceModeMixin.java
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.*;
|
||||||
|
import net.minecraft.state.property.Property;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.moonleay.gimbal.editor.ServerEditorManager;
|
||||||
|
import net.moonleay.gimbal.editor.state.mode.Capability;
|
||||||
|
import org.spongepowered.asm.mixin.*;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class ReplaceModeMixin {
|
||||||
|
|
||||||
|
@Mixin(ItemPlacementContext.class)
|
||||||
|
public static abstract class ItemPlacementContextMixin extends ItemUsageContext {
|
||||||
|
@Shadow
|
||||||
|
protected boolean canReplaceExisting;
|
||||||
|
|
||||||
|
@Mutable
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private BlockPos placementPos;
|
||||||
|
|
||||||
|
public ItemPlacementContextMixin(PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||||
|
super(player, hand, hit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/Hand;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/hit/BlockHitResult;)V", at = @At(value = "RETURN"))
|
||||||
|
private void func(World world, PlayerEntity playerEntity, Hand hand, ItemStack itemStack, BlockHitResult blockHitResult, CallbackInfo ci) {
|
||||||
|
if (playerEntity == null)
|
||||||
|
return;
|
||||||
|
UUID id = playerEntity.getGameProfile().getId();
|
||||||
|
if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.REPLACE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.canReplaceExisting = true;
|
||||||
|
this.placementPos = blockHitResult.getBlockPos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mixin(BlockItem.class)
|
||||||
|
public static abstract class BlockItemMixin extends Item {
|
||||||
|
|
||||||
|
public BlockItemMixin(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected abstract boolean place(ItemPlacementContext context, BlockState state);
|
||||||
|
|
||||||
|
@Redirect(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;place(Lnet/minecraft/item/ItemPlacementContext;Lnet/minecraft/block/BlockState;)Z"))
|
||||||
|
private boolean func(BlockItem instance, ItemPlacementContext context, BlockState state) {
|
||||||
|
if (context.getPlayer() == null)
|
||||||
|
return this.place(context, state);
|
||||||
|
UUID id = context.getPlayer().getGameProfile().getId();
|
||||||
|
if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.REPLACE))
|
||||||
|
return this.place(context, state);
|
||||||
|
BlockState oldState = context.getWorld().getBlockState(context.getBlockPos());
|
||||||
|
return this.place(context, getTargetBlockState(oldState, instance.getBlock().getDefaultState()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
public BlockState getTargetBlockState(BlockState oldState, BlockState newBlock) {
|
||||||
|
var oldManager = oldState.getBlock().getStateManager();
|
||||||
|
var newManager = newBlock.getBlock().getStateManager();
|
||||||
|
for (var prop : oldManager.getProperties()) {
|
||||||
|
var matchingProp = newManager.getProperty(prop.getName());
|
||||||
|
if (matchingProp != null) {
|
||||||
|
//noinspection rawtypes,unchecked
|
||||||
|
newBlock = newBlock.with((Property) matchingProp, oldState.get(matchingProp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screen.GameMenuScreen;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.client.gui.screen.TitleScreen;
|
||||||
|
import net.minecraft.client.gui.widget.TexturedButtonWidget;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.moonleay.gimbal.build.BuildConstants;
|
||||||
|
import net.moonleay.gimbal.client.ClientMain;
|
||||||
|
import net.moonleay.gimbal.client.screen.GimbalSettingsGui;
|
||||||
|
import net.moonleay.gimbal.constants.TranslationKeys;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
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;
|
||||||
|
|
||||||
|
// What is my purpose?
|
||||||
|
public class YouInjectButtonMixin {
|
||||||
|
// Go my god.
|
||||||
|
|
||||||
|
@Mixin(TitleScreen.class)
|
||||||
|
public static abstract class TitleScreenMixin extends Screen {
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static final Identifier GIMBAL_TEXTURE = new Identifier(BuildConstants.modId, "textures/gimbal_options_texture_button.png");
|
||||||
|
|
||||||
|
protected TitleScreenMixin(Text title) {
|
||||||
|
super(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "init", at = @At(value = "RETURN"))
|
||||||
|
private void func(CallbackInfo ci) {
|
||||||
|
int l = this.height / 4 + 48;
|
||||||
|
this.addDrawableChild(
|
||||||
|
new TexturedButtonWidget(
|
||||||
|
this.width / 2 - 124 - 24,
|
||||||
|
l + 72 + 12,
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
20,
|
||||||
|
GIMBAL_TEXTURE,
|
||||||
|
20,
|
||||||
|
40,
|
||||||
|
button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)),
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.SCREEN_NAME)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(GameMenuScreen.class)
|
||||||
|
public static abstract class GameMenuScreenMixin extends Screen {
|
||||||
|
@Unique
|
||||||
|
private static final Identifier GIMBAL_TEXTURE = new Identifier(BuildConstants.modId, "textures/gimbal_options_texture_button.png");
|
||||||
|
|
||||||
|
protected GameMenuScreenMixin(Text title) {
|
||||||
|
super(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "initWidgets", at = @At(value = "RETURN"))
|
||||||
|
private void func(CallbackInfo ci) {
|
||||||
|
this.addDrawableChild(
|
||||||
|
new TexturedButtonWidget(
|
||||||
|
this.width / 2 - 124,
|
||||||
|
this.height / 4 + 96 + -16,
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
20,
|
||||||
|
GIMBAL_TEXTURE,
|
||||||
|
20,
|
||||||
|
40,
|
||||||
|
button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)),
|
||||||
|
Text.translatable(TranslationKeys.Gui.Config.SCREEN_NAME)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
70
src/main/java/net/moonleay/gimbal/networking/GimbalClient.kt
Normal file
70
src/main/java/net/moonleay/gimbal/networking/GimbalClient.kt
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.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.gimbal.build.BuildConstants
|
||||||
|
import net.moonleay.gimbal.client.editor.ClientEditor
|
||||||
|
import net.moonleay.gimbal.constants.PacketIDs
|
||||||
|
import net.moonleay.gimbal.editor.state.EditorState
|
||||||
|
import net.moonleay.gimbal.editor.state.GimbalPolicyType
|
||||||
|
import net.moonleay.gimbal.editor.state.GimbalServerState
|
||||||
|
|
||||||
|
object GimbalClient {
|
||||||
|
|
||||||
|
fun registerPacketHandlers() {
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(PacketIDs.GIMBAL_POLICY_PACKET_ID) { _, _, buf, handler ->
|
||||||
|
val state = this.getServerState(buf)
|
||||||
|
val isUsable = this.isGimbalUsable(state)
|
||||||
|
if (isUsable) {
|
||||||
|
val buf = PacketByteBufs.create()
|
||||||
|
buf.writeByteArray(Cbor.encodeToByteArray(ClientEditor.getClientState()))
|
||||||
|
handler.sendPacket(PacketIDs.UPDATE_EDITOR_STATE_ID, buf)
|
||||||
|
}
|
||||||
|
ClientEditor.onPolicyReceived(state, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
private fun getServerState(buf: PacketByteBuf): GimbalServerState {
|
||||||
|
val serverState = Cbor.decodeFromByteArray<GimbalServerState>(buf.readByteArray())
|
||||||
|
return serverState
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isGimbalUsable(state: GimbalServerState): Boolean {
|
||||||
|
return state.policyType == GimbalPolicyType.ALLOWED && state.protocolVersion.toString() == BuildConstants.protocolVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
private fun createStatePacket(state: EditorState): PacketByteBuf {
|
||||||
|
val buf = PacketByteBufs.create()
|
||||||
|
buf.writeByteArray(Cbor.encodeToByteArray(state))
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendStatePacket(state: EditorState) {
|
||||||
|
ClientPlayNetworking.send(PacketIDs.UPDATE_EDITOR_STATE_ID, createStatePacket(state))
|
||||||
|
}
|
||||||
|
}
|
74
src/main/java/net/moonleay/gimbal/networking/GimbalServer.kt
Normal file
74
src/main/java/net/moonleay/gimbal/networking/GimbalServer.kt
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Gimbal
|
||||||
|
* Copyright (C) 2024 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.gimbal.networking
|
||||||
|
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import kotlinx.serialization.cbor.Cbor
|
||||||
|
import kotlinx.serialization.decodeFromByteArray
|
||||||
|
import kotlinx.serialization.encodeToByteArray
|
||||||
|
import me.lucko.fabric.api.permissions.v0.Permissions
|
||||||
|
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.moonleay.gimbal.build.BuildConstants
|
||||||
|
import net.moonleay.gimbal.constants.PacketIDs
|
||||||
|
import net.moonleay.gimbal.constants.PermissionIDs
|
||||||
|
import net.moonleay.gimbal.editor.ServerEditorManager
|
||||||
|
import net.moonleay.gimbal.editor.state.EditorState
|
||||||
|
import net.moonleay.gimbal.editor.state.GimbalPolicyType
|
||||||
|
import net.moonleay.gimbal.editor.state.GimbalServerState
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
|
||||||
|
object GimbalServer {
|
||||||
|
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
||||||
|
|
||||||
|
fun registerPacketHandler() {
|
||||||
|
ServerPlayNetworking
|
||||||
|
.registerGlobalReceiver(PacketIDs.UPDATE_EDITOR_STATE_ID)
|
||||||
|
{ _, player, _, buf, _ ->
|
||||||
|
handleStateUpdate(player, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
fun notifyPlayerOfPolicy(player: ServerPlayerEntity) {
|
||||||
|
LOGGER.info("Sending policy to " + player.name.string)
|
||||||
|
val buf = PacketByteBufs.create()
|
||||||
|
buf.writeByteArray(
|
||||||
|
Cbor.encodeToByteArray(
|
||||||
|
GimbalServerState(
|
||||||
|
BuildConstants.protocolVersion.toInt(),
|
||||||
|
if (this.isPlayerAllowedToUseGimbal(player)) GimbalPolicyType.ALLOWED else GimbalPolicyType.DENIED
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ServerPlayNetworking.send(player, PacketIDs.GIMBAL_POLICY_PACKET_ID, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleStateUpdate(player: ServerPlayerEntity, buf: PacketByteBuf){
|
||||||
|
val state = Cbor.decodeFromByteArray<EditorState>(buf.readByteArray())
|
||||||
|
ServerEditorManager.updateEditorState(player.uuid, state)
|
||||||
|
// player.sendMessage(Text.of("Mode: ${state.editorMode} with ${state.editorModifier}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isPlayerAllowedToUseGimbal(player: ServerPlayerEntity): Boolean {
|
||||||
|
return player.hasPermissionLevel(2) || Permissions.check(player, PermissionIDs.GIMBAL_USAGE_PERMISSION)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
package net.moonleay.gimble
|
|
||||||
|
|
||||||
import net.moonleay.gimble.build.BuildConstants
|
|
||||||
import net.fabricmc.api.ModInitializer
|
|
||||||
import net.moonleay.gimble.networking.GimbleServer
|
|
||||||
import org.apache.logging.log4j.LogManager
|
|
||||||
|
|
||||||
internal object Main : ModInitializer {
|
|
||||||
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
|
||||||
|
|
||||||
override fun onInitialize() {
|
|
||||||
LOGGER.info("Initializing Gimble on the common side...")
|
|
||||||
LOGGER.info("Registering packets...")
|
|
||||||
GimbleServer.registerPacketHandler()
|
|
||||||
LOGGER.info("Packets have been registered.")
|
|
||||||
LOGGER.info("Gimble has been initialized on the common side.")
|
|
||||||
LOGGER.info("${BuildConstants.modName} (${BuildConstants.modId}) v.${BuildConstants.modVersion} by moonleay")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package net.moonleay.gimble.client
|
|
||||||
|
|
||||||
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 {
|
|
||||||
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
|
||||||
|
|
||||||
|
|
||||||
override fun onInitializeClient() {
|
|
||||||
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.")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerEvents() {
|
|
||||||
LOGGER.info("Registering client events...")
|
|
||||||
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { client ->
|
|
||||||
KeybindingManager.onClientTick(client)
|
|
||||||
})
|
|
||||||
LOGGER.info("Client events have been registered.")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
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 {
|
|
||||||
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
|
|
||||||
* */
|
|
||||||
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
|
|
||||||
}
|
|
||||||
if (!MinecraftClient.getInstance().player!!.isCreative)
|
|
||||||
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 (!MinecraftClient.getInstance().player!!.isCreative)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (CURRENT_MODE.incompatibleModifiers.contains(mod)){
|
|
||||||
if (TEMP_DISABLED_MODIFIERS.contains(mod))
|
|
||||||
TEMP_DISABLED_MODIFIERS.remove(mod)
|
|
||||||
else
|
|
||||||
TEMP_DISABLED_MODIFIERS.add(mod)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (CURRENT_MODE_MODIFIER.contains(mod))
|
|
||||||
CURRENT_MODE_MODIFIER.remove(mod)
|
|
||||||
else
|
|
||||||
CURRENT_MODE_MODIFIER.add(mod)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onUpdated()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onUpdated() {
|
|
||||||
CURRENT_MODE_MODIFIER.sortBy {
|
|
||||||
it.displayName
|
|
||||||
}
|
|
||||||
this.checkForIncompatibleModeModifiers()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This runs on Mode updated
|
|
||||||
*/
|
|
||||||
private fun checkForIncompatibleModeModifiers() {
|
|
||||||
if (TEMP_DISABLED_MODIFIERS.size > 0) {
|
|
||||||
CURRENT_MODE_MODIFIER.addAll(
|
|
||||||
TEMP_DISABLED_MODIFIERS
|
|
||||||
)
|
|
||||||
TEMP_DISABLED_MODIFIERS.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
val incompatibleModeModifiers = CURRENT_MODE.incompatibleModifiers
|
|
||||||
for (mod in CURRENT_MODE_MODIFIER) {
|
|
||||||
if (incompatibleModeModifiers.contains(mod)) {
|
|
||||||
TEMP_DISABLED_MODIFIERS.add(mod)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (mod in TEMP_DISABLED_MODIFIERS) {
|
|
||||||
if (CURRENT_MODE_MODIFIER.contains(mod)) { // This check is probably useless.
|
|
||||||
CURRENT_MODE_MODIFIER.remove(mod)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CURRENT_MODE_MODIFIER.sortBy {
|
|
||||||
it.displayName
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update State
|
|
||||||
this.updateServerState()
|
|
||||||
|
|
||||||
if(TEMP_DISABLED_MODIFIERS.isNotEmpty()) {
|
|
||||||
ChatUtil.showToastToSelf("${CURRENT_MODE.displayName} Mode disabled", getListAsString(TEMP_DISABLED_MODIFIERS), MinecraftClient.getInstance())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getListAsString(list: List<ModeModifier>): String{
|
|
||||||
if(list.isEmpty())
|
|
||||||
return "Empty list"
|
|
||||||
val sb = StringBuilder()
|
|
||||||
for (mod in list) {
|
|
||||||
sb.append(mod.displayName)
|
|
||||||
sb.append(", ")
|
|
||||||
}
|
|
||||||
return sb.toString().dropLast(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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() && MinecraftClient.getInstance().player?.isCreative == true) {
|
|
||||||
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() || !MinecraftClient.getInstance().player?.isCreative!!) {
|
|
||||||
displayText.clear()
|
|
||||||
displayText.append("[GIMBLE DISABLED]")
|
|
||||||
}
|
|
||||||
return Text.of(displayText.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCurrentColor(): Int {
|
|
||||||
return CURRENT_MODE.color
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
|
|
||||||
object KeybindingManager {
|
|
||||||
|
|
||||||
private val shortcuts = mutableListOf<GimbleShortcut>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a shortcut. This will also register the keybinding.
|
|
||||||
* */
|
|
||||||
fun registerShortcut(shortcut: GimbleShortcut) {
|
|
||||||
shortcuts.add(shortcut)
|
|
||||||
KeyBindingRegistryImpl.registerKeyBinding(shortcut.keyBinding)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onClientTick(client: MinecraftClient){
|
|
||||||
// Sadly, this cannot be done without iterating over all shortcuts :madge:
|
|
||||||
for (shortcut in shortcuts)
|
|
||||||
if (shortcut.keyBinding.wasPressed())
|
|
||||||
shortcut.onPressed(client)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
|
|
||||||
abstract class GimbleShortcut(val keyBinding: KeyBinding) {
|
|
||||||
|
|
||||||
abstract fun onPressed(client: MinecraftClient)
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.editormode
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.editor.state.mode.Mode
|
|
||||||
|
|
||||||
|
|
||||||
class EnableInsertModeShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ClientEditor.setMode(Mode.INSERT)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.editormode
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.editor.state.mode.Mode
|
|
||||||
|
|
||||||
|
|
||||||
class EnableReplaceModeShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ClientEditor.setMode(Mode.REPLACE)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.editormode
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.editor.state.mode.Mode
|
|
||||||
|
|
||||||
|
|
||||||
class EnableVisualModeShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ClientEditor.setMode(Mode.VISUAL)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.editormodemodifier
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.editor.state.mode.ModeModifier
|
|
||||||
|
|
||||||
class ToggleBulldozerModifierShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ClientEditor.toggleModifier(ModeModifier.BULLDOZER)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.editormodemodifier
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.editor.state.mode.ModeModifier
|
|
||||||
|
|
||||||
class ToggleForcePlaceModifierShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ClientEditor.toggleModifier(ModeModifier.FORCE_PLACE)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.editormodemodifier
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.editor.state.mode.ModeModifier
|
|
||||||
|
|
||||||
class ToggleNoClipModifierShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ClientEditor.toggleModifier(ModeModifier.NO_CLIP)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.editormodemodifier
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.editor.state.mode.ModeModifier
|
|
||||||
|
|
||||||
class ToggleNoUpdatesModifierShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ClientEditor.toggleModifier(ModeModifier.NO_UPDATES)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.gamemode
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.client.util.ChatUtil
|
|
||||||
|
|
||||||
class CreativeModeShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ChatUtil.sendCommand("/gamemode creative", client, false)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.gamemode
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.client.util.ChatUtil
|
|
||||||
|
|
||||||
class SpectatorModeShortcut(key: KeyBinding): GimbleShortcut(key) {
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ChatUtil.sendCommand("/gamemode spectator", client, false)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package net.moonleay.gimble.client.keybindings.impl.gamemode
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.option.KeyBinding
|
|
||||||
import net.moonleay.gimble.client.keybindings.impl.GimbleShortcut
|
|
||||||
import net.moonleay.gimble.client.util.ChatUtil
|
|
||||||
|
|
||||||
|
|
||||||
class SurvivalModeShortcut(key: KeyBinding) : GimbleShortcut(key) {
|
|
||||||
|
|
||||||
override fun onPressed(client: MinecraftClient) {
|
|
||||||
ChatUtil.sendCommand("/gamemode survival", client, false)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package net.moonleay.gimble.client.util
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.client.toast.SystemToast
|
|
||||||
import net.minecraft.text.Text
|
|
||||||
|
|
||||||
object ChatUtil {
|
|
||||||
/**
|
|
||||||
* Note: command arg should contain "/" at the beginning.
|
|
||||||
* */
|
|
||||||
fun sendCommand(command: String, client: MinecraftClient, addToHistory: Boolean = true): Boolean {
|
|
||||||
if (addToHistory) {
|
|
||||||
client.inGameHud.chatHud.addToMessageHistory(command)
|
|
||||||
}
|
|
||||||
return client.player?.sendCommand(command.substring(1))?: false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addToChatHistory(message: String, client: MinecraftClient) {
|
|
||||||
client.inGameHud.chatHud.addMessage(Text.of(message))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun showToastToSelf(title: String, description: String, client: MinecraftClient) {
|
|
||||||
val toast = SystemToast(SystemToast.Type.PERIODIC_NOTIFICATION, Text.of(title), Text.of(description))
|
|
||||||
client.toastManager.add(toast)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package net.moonleay.gimble.datagen
|
|
||||||
|
|
||||||
import net.moonleay.gimble.build.BuildConstants
|
|
||||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint
|
|
||||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
|
|
||||||
import org.apache.logging.log4j.LogManager
|
|
||||||
|
|
||||||
internal class DataGenerator : DataGeneratorEntrypoint {
|
|
||||||
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
|
||||||
|
|
||||||
override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) {
|
|
||||||
LOGGER.info("Starting Data Generation")
|
|
||||||
fabricDataGenerator.addProvider(En_us_GimbleLanguageProvider(fabricDataGenerator))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package net.moonleay.gimble.datagen
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
|
|
||||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider
|
|
||||||
|
|
||||||
class En_us_GimbleLanguageProvider(dataGenerator: FabricDataGenerator?) :
|
|
||||||
FabricLanguageProvider(dataGenerator, "en_us") {
|
|
||||||
|
|
||||||
override fun generateTranslations(translationBuilder: TranslationBuilder?) {
|
|
||||||
if (translationBuilder == null) return
|
|
||||||
// Editor modes
|
|
||||||
translationBuilder.add("gimble.category.editormode", "Editor Modes")
|
|
||||||
translationBuilder.add("gimble.key.editor.mode.insert", "Enter Insert Mode")
|
|
||||||
translationBuilder.add("gimble.key.editor.mode.replace", "Enter Replace Mode")
|
|
||||||
translationBuilder.add("gimble.key.editor.mode.visual", "Enter Visual Mode")
|
|
||||||
|
|
||||||
|
|
||||||
// Editor mode modifiers
|
|
||||||
translationBuilder.add("gimble.category.editormodifier", "Editor Mode Modifiers")
|
|
||||||
translationBuilder.add("gimble.key.editor.modifier.bulldozer", "Toggle Bulldozer Modifier")
|
|
||||||
translationBuilder.add("gimble.key.editor.modifier.forceplace", "Toggle Force Place Modifier")
|
|
||||||
translationBuilder.add("gimble.key.editor.modifier.noupdates", "Toggle No Updates Modifier")
|
|
||||||
translationBuilder.add("gimble.key.editor.modifier.noclip", "Toggle No Clip Modifier")
|
|
||||||
|
|
||||||
// Game mode
|
|
||||||
translationBuilder.add("gimble.category.gamemode", "Game Mode")
|
|
||||||
translationBuilder.add("gimble.key.game.mode.survival", "Enable Survival Mode")
|
|
||||||
translationBuilder.add("gimble.key.game.mode.creative", "Enable Creative Mode")
|
|
||||||
translationBuilder.add("gimble.key.game.mode.spectator", "Enable Spectator Mode")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
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.Capability
|
|
||||||
import net.moonleay.gimble.editor.util.EditorUtil
|
|
||||||
import org.apache.logging.log4j.LogManager
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object ServerEditorManager {
|
|
||||||
private val LOGGER = LogManager.getLogger(BuildConstants.modName)
|
|
||||||
|
|
||||||
private val STATEMAP = mutableMapOf<UUID, EditorState>()
|
|
||||||
|
|
||||||
fun updateEditorState(playerUUID: UUID, editorState: EditorState) {
|
|
||||||
STATEMAP[playerUUID] = editorState
|
|
||||||
LOGGER.info("$playerUUID: ${editorState.editorMode} with ${editorState.editorModifier}")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if a player should be able to perform an action
|
|
||||||
* */
|
|
||||||
fun shouldPlayer(playerUUID: UUID, capability: Capability): Boolean {
|
|
||||||
if (!STATEMAP.containsKey(playerUUID))
|
|
||||||
return 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
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package net.moonleay.gimble.editor.state
|
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import net.moonleay.gimble.editor.state.mode.Mode
|
|
||||||
import net.moonleay.gimble.editor.state.mode.ModeModifier
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class EditorState(
|
|
||||||
var editorMode: Mode,
|
|
||||||
var editorModifier: MutableList<ModeModifier>,
|
|
||||||
)
|
|
|
@ -1,7 +0,0 @@
|
||||||
package net.moonleay.gimble.editor.state
|
|
||||||
|
|
||||||
enum class GimblePolicyType {
|
|
||||||
ALLOWED,
|
|
||||||
DENIED,
|
|
||||||
NOT_PRESENT
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package net.moonleay.gimble.editor.state.mode
|
|
||||||
|
|
||||||
enum class Capability {
|
|
||||||
INSERT,
|
|
||||||
REPLACE,
|
|
||||||
CAN_INTERACT,
|
|
||||||
NO_CLIP,
|
|
||||||
FORCE_PLACE,
|
|
||||||
NO_UPDATES,
|
|
||||||
BULLDOZER,
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
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
|
|
||||||
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
|
|
||||||
VISUAL("VISUAL", 0x6a9fb5, listOf(ModeModifier.BULLDOZER)), // Do fancy stuff with WE
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package net.moonleay.gimble.editor.state.mode
|
|
||||||
|
|
||||||
enum class ModeModifier(val displayName: String) {
|
|
||||||
// NONE("None"), // No Modifiers - default behavior
|
|
||||||
NO_UPDATES("NO UPDATES"), // Do not update blocks when placing
|
|
||||||
BULLDOZER("BULLDOZER"), // Break blocks fast
|
|
||||||
FORCE_PLACE("FORCE"), // Ignore block placement restrictions
|
|
||||||
NO_CLIP("NO CLIP"), // Do not collide with blocks
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package net.moonleay.gimble.editor.util
|
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import net.moonleay.gimble.editor.state.GimblePolicyType
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class GimblePolicy(
|
|
||||||
val policy: GimblePolicyType,
|
|
||||||
)
|
|
|
@ -1,43 +0,0 @@
|
||||||
package net.moonleay.gimble.mixin;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor;
|
|
||||||
import net.moonleay.gimble.editor.state.mode.Capability;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Mixin(MinecraftClient.class)
|
|
||||||
public abstract class BulldozerMixin {
|
|
||||||
|
|
||||||
@Shadow protected int attackCooldown;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Nullable
|
|
||||||
public ClientPlayerEntity player;
|
|
||||||
|
|
||||||
@Inject(method = "doAttack", at = @At(value = "HEAD"))
|
|
||||||
private void func(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.player).isCreative()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.attackCooldown = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "handleBlockBreaking", at = @At(value = "HEAD"))
|
|
||||||
private void func2(boolean breaking, CallbackInfo ci) {
|
|
||||||
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !breaking || !Objects.requireNonNull(this.player).isCreative()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.attackCooldown = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package net.moonleay.gimble.mixin;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
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.Capability;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
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.Objects;
|
|
||||||
|
|
||||||
@Mixin(ClientPlayerInteractionManager.class)
|
|
||||||
public class BulldozerMixin2 {
|
|
||||||
|
|
||||||
@Shadow private int blockBreakingCooldown;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private MinecraftClient client;
|
|
||||||
|
|
||||||
@Inject(method = "updateBlockBreakingProgress", at = @At("HEAD"))
|
|
||||||
private void func(BlockPos pos, Direction direction, CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.client.player).isCreative()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.blockBreakingCooldown = 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package net.moonleay.gimble.mixin;
|
|
||||||
|
|
||||||
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.moonleay.gimble.client.editor.ClientEditor;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(InGameHud.class)
|
|
||||||
public class HudMixin {
|
|
||||||
|
|
||||||
@Shadow @Final private MinecraftClient client;
|
|
||||||
|
|
||||||
@Inject(method = "renderStatusEffectOverlay", at = @At("HEAD"))
|
|
||||||
private void render(MatrixStack matrices, CallbackInfo ci) {
|
|
||||||
TextRenderer tr = this.client.textRenderer;
|
|
||||||
tr.drawWithShadow(matrices,
|
|
||||||
ClientEditor.INSTANCE.getModeDisplayText(),
|
|
||||||
4, 4,
|
|
||||||
ClientEditor.INSTANCE.getCurrentColor());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package net.moonleay.gimble.mixin;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.render.Camera;
|
|
||||||
import net.moonleay.gimble.client.editor.ClientEditor;
|
|
||||||
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;
|
|
||||||
|
|
||||||
@Mixin(Camera.class)
|
|
||||||
public class NoClipCameraFixMixin {
|
|
||||||
|
|
||||||
@Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true)
|
|
||||||
private void fixCameraInNoClip(double desiredCameraDistance, CallbackInfoReturnable<Double> cir) {
|
|
||||||
if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP) || (!(MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().player.isCreative()))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cir.setReturnValue(desiredCameraDistance);
|
|
||||||
cir.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package net.moonleay.gimble.mixin;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import net.minecraft.entity.EntityPose;
|
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
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.Capability;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
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.UUID;
|
|
||||||
|
|
||||||
@Mixin(PlayerEntity.class)
|
|
||||||
public abstract class NoClipMixin extends LivingEntity {
|
|
||||||
@Shadow public abstract GameProfile getGameProfile();
|
|
||||||
|
|
||||||
@Shadow public abstract PlayerAbilities getAbilities();
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public abstract boolean isCreative();
|
|
||||||
|
|
||||||
protected NoClipMixin(EntityType<? extends LivingEntity> entityType, World world) {
|
|
||||||
super(entityType, world);
|
|
||||||
} // Server side
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At(value = "FIELD",
|
|
||||||
target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z", shift = At.Shift.AFTER)
|
|
||||||
) private void enoClip(CallbackInfo ci) {
|
|
||||||
if (!this.isCreative())
|
|
||||||
return;
|
|
||||||
UUID uuid = this.getGameProfile().getId();
|
|
||||||
|
|
||||||
if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) {
|
|
||||||
return; // NoClip is not enabled
|
|
||||||
}
|
|
||||||
if (!this.getAbilities().flying) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Enable NoClip
|
|
||||||
this.noClip = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "updatePose", at = @At("HEAD"))
|
|
||||||
private void onUpdatePose(CallbackInfo ci) {
|
|
||||||
UUID uuid = this.getGameProfile().getId();
|
|
||||||
|
|
||||||
if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP))
|
|
||||||
return; // NoClip is not enabled
|
|
||||||
if (!this.getAbilities().flying)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Force standing pose in NoClip mode
|
|
||||||
|
|
||||||
this.setPose(EntityPose.STANDING);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package net.moonleay.gimble.mixin;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
|
||||||
import net.minecraft.client.network.ClientPlayerInteractionManager;
|
|
||||||
import net.minecraft.client.particle.ParticleManager;
|
|
||||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
|
||||||
import net.minecraft.util.Hand;
|
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
|
||||||
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.Capability;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(MinecraftClient.class)
|
|
||||||
public abstract class ReplaceModeMixin {
|
|
||||||
|
|
||||||
|
|
||||||
@Shadow protected abstract void handleBlockBreaking(boolean breaking);
|
|
||||||
|
|
||||||
@Shadow @Nullable public ClientPlayerInteractionManager interactionManager;
|
|
||||||
|
|
||||||
@Shadow @Final public ParticleManager particleManager;
|
|
||||||
|
|
||||||
@Shadow @Nullable public ClientPlayerEntity player;
|
|
||||||
|
|
||||||
@Shadow @Nullable public HitResult crosshairTarget;
|
|
||||||
|
|
||||||
@Inject(method = "doItemUse", at = @At("HEAD"))
|
|
||||||
private void replaceBlock(CallbackInfo ci) {
|
|
||||||
assert this.player != null;
|
|
||||||
if (!this.player.isCreative())
|
|
||||||
return;
|
|
||||||
// Check if should run
|
|
||||||
if (!ClientEditor.INSTANCE.shouldClient(Capability.REPLACE))
|
|
||||||
return; // Mode is not REPLACE, ignore
|
|
||||||
MinecraftClient client = MinecraftClient.getInstance();
|
|
||||||
assert this.interactionManager != null;
|
|
||||||
if (!this.interactionManager.getCurrentGameMode().isCreative())
|
|
||||||
return;
|
|
||||||
if (!(this.crosshairTarget instanceof BlockHitResult blockHitResult))
|
|
||||||
return;
|
|
||||||
if (blockHitResult == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Gather data
|
|
||||||
BlockPos pos = blockHitResult.getBlockPos();
|
|
||||||
Direction direction = blockHitResult.getSide();
|
|
||||||
BlockState blockState = client.world.getBlockState(pos);
|
|
||||||
|
|
||||||
// Start sending shit
|
|
||||||
client.getTutorialManager().onBlockBreaking(client.world, pos, blockState, 1.0F);
|
|
||||||
this.interactionManager.sendSequencedPacket(client.world, sequence -> {
|
|
||||||
this.interactionManager.breakBlock(pos);
|
|
||||||
return new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence);
|
|
||||||
});
|
|
||||||
this.player.swingHand(Hand.MAIN_HAND);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
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.
|
|
||||||
*/
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
|
||||||
fun sendEditorState(state: EditorState) {
|
|
||||||
val buf = PacketByteBufs.create()
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
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.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 {
|
|
||||||
|
|
||||||
fun registerPacketHandler() {
|
|
||||||
ServerPlayNetworking
|
|
||||||
.registerGlobalReceiver(PacketIDs.UPDATE_EDITOR_STATE_ID)
|
|
||||||
{ 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){
|
|
||||||
val state = Cbor.decodeFromByteArray<EditorState>(buf.readByteArray())
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue