From 44e41013a9bbbcddf9c49c978ecde57691912fd9 Mon Sep 17 00:00:00 2001 From: Abdulaziz Date: Thu, 12 Dec 2024 07:39:21 +0300 Subject: [PATCH 1/6] Going back to java + Navigator compact --- addon.gradle | 25 --- dependencies.gradle | 14 +- gradle.properties | 29 ++- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 7 +- gradlew.bat | 2 + localization-generator/.gitignore | 32 --- localization-generator/build.gradle | 16 -- .../localization/Localization.kt | 4 - .../localizationgenerator/LocalizationData.kt | 4 - .../LocalizationGenerator.kt | 76 ------- .../LocalizationSymbolProcessor.kt | 29 --- .../LocalizationSymbolProcessorProvider.kt | 11 -- ...ols.ksp.processing.SymbolProcessorProvider | 1 - settings.gradle | 5 +- .../sharewhereiam/ShareWhereIAm.java | 8 +- .../sharewhereiam/ShareWhereIAmLateMixin.java | 22 +++ .../sharewhereiam/client/key/KeyShare.java | 15 ++ .../sharewhereiam/command/CommandError.java | 20 ++ .../command/CommandWaypointSave.java | 53 +++++ .../command/CommandWaypointShareLocation.java | 33 ++++ .../CommandWaypointToggleTempBeacon.java | 35 ++++ .../command/base/CommandWaypointBase.java | 71 +++++++ .../sharewhereiam/core/ShareWhereIAmCore.java | 46 +++++ .../sharewhereiam/event/EventHandler.java | 71 +++++++ .../sharewhereiam/integration/Mods.java | 27 +++ .../journeymap/WaypointManager.java | 66 +++++++ .../journeymap/WaypointMarker.java | 94 +++++++++ .../sharewhereiam/loader/CommandLoader.java | 22 +++ .../sharewhereiam/loader/EventLoader.java | 17 ++ .../loader/IntegrationLoader.java | 14 ++ .../sharewhereiam/loader/KeyLoader.java | 17 ++ .../sharewhereiam/loader/NetworkLoader.java | 28 +++ .../sharewhereiam/localization/Lang.java | 74 +++++++ .../mixinplugin/MixinPlugin.java | 81 -------- .../sharewhereiam/mixins/Mixins.java | 186 ++++++++++++++++++ .../sharewhereiam/mixins/TargetedMod.java | 32 +++ .../journeymap/MixinFullscreen.java | 10 +- .../journeymap/MixinRenderWaypointBeacon.java | 2 +- .../journeymap/MixinWaypointManagerItem.java | 4 +- .../journeymap/MixinWaypointStore.java | 2 +- .../network/MessageMarkWaypoint.java | 73 +++++++ .../network/MessageShareWaypoint.java | 82 ++++++++ .../sharewhereiam/network/NetworkHandler.java | 16 ++ .../sharewhereiam/proxy/ClientProxy.java | 17 ++ .../sharewhereiam/proxy/CommonProxy.java | 16 ++ .../sharewhereiam/util/VPWaypointUtil.java | 64 ++++++ .../sharewhereiam/util/WaypointUtil.java | 144 ++++++++++++++ .../sharewhereiam/client/KeyBinding.kt | 12 -- .../sharewhereiam/command/CommandError.kt | 12 -- .../command/CommandWaypointSave.kt | 40 ---- .../command/CommandWaypointShareLocation.kt | 21 -- .../CommandWaypointToggleTempBeacon.kt | 22 --- .../command/base/CommandWaypointBase.kt | 52 ----- .../sharewhereiam/event/EventHandler.kt | 55 ------ .../sharewhereiam/integration/Mods.kt | 17 -- .../integration/journeymap/WaypointManager.kt | 45 ----- .../integration/journeymap/WaypointMarker.kt | 86 -------- .../sharewhereiam/loader/CommandLoader.kt | 17 -- .../sharewhereiam/loader/EventLoader.kt | 12 -- .../sharewhereiam/loader/IntegrationLoader.kt | 10 - .../sharewhereiam/loader/KeyLoader.kt | 13 -- .../sharewhereiam/loader/NetworkLoader.kt | 28 --- .../sharewhereiam/localization/Lang.kt | 72 ------- .../network/MessageMarkWaypoint.kt | 59 ------ .../network/MessageShareWaypoint.kt | 70 ------- .../sharewhereiam/network/NetworkHandler.kt | 13 -- .../sharewhereiam/proxy/ClientProxy.kt | 13 -- .../sharewhereiam/proxy/CommonProxy.kt | 20 -- .../sharewhereiam/util/VPWaypointUtil.kt | 47 ----- .../sharewhereiam/util/WaypointUtil.kt | 163 --------------- .../assets/sharewhereiam/lang/en_US.lang | 22 +++ 73 files changed, 1425 insertions(+), 1215 deletions(-) delete mode 100644 addon.gradle delete mode 100644 localization-generator/.gitignore delete mode 100644 localization-generator/build.gradle delete mode 100644 localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Localization.kt delete mode 100644 localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationData.kt delete mode 100644 localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationGenerator.kt delete mode 100644 localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessor.kt delete mode 100644 localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessorProvider.kt delete mode 100644 localization-generator/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAmLateMixin.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/command/CommandError.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java delete mode 100644 src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/MixinPlugin.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java rename src/main/java/com/muxiu1997/sharewhereiam/mixins/{ => late}/journeymap/MixinFullscreen.java (87%) rename src/main/java/com/muxiu1997/sharewhereiam/mixins/{ => late}/journeymap/MixinRenderWaypointBeacon.java (95%) rename src/main/java/com/muxiu1997/sharewhereiam/mixins/{ => late}/journeymap/MixinWaypointManagerItem.java (96%) rename src/main/java/com/muxiu1997/sharewhereiam/mixins/{ => late}/journeymap/MixinWaypointStore.java (92%) create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/network/NetworkHandler.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/client/KeyBinding.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandError.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/event/EventHandler.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/integration/Mods.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/loader/CommandLoader.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/loader/EventLoader.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/loader/KeyLoader.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/loader/NetworkLoader.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Lang.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/network/NetworkHandler.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/ClientProxy.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/CommonProxy.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.kt delete mode 100644 src/main/kotlin/com/muxiu1997/sharewhereiam/util/WaypointUtil.kt create mode 100644 src/main/resources/assets/sharewhereiam/lang/en_US.lang diff --git a/addon.gradle b/addon.gradle deleted file mode 100644 index b8d37d4..0000000 --- a/addon.gradle +++ /dev/null @@ -1,25 +0,0 @@ -apply plugin: 'org.jetbrains.kotlin.jvm' -apply plugin: 'com.google.devtools.ksp' - -kotlin { - sourceSets { - main.kotlin.srcDirs += 'build/generated/ksp/main/kotlin' - test.kotlin.srcDirs += 'build/generated/ksp/test/kotlin' - } -} - -idea { - module { - sourceDirs = sourceDirs + file('build/generated/ksp/main/kotlin') - testSourceDirs = testSourceDirs + file('build/generated/ksp/test/kotlin') - generatedSourceDirs = generatedSourceDirs + file('build/generated/ksp/main/kotlin') + file('build/generated/ksp/test/kotlin') - } -} - -//configurations { -// kspPatchedMcKotlin { -// attributes { -// attribute(com.gtnewhorizons.retrofuturagradle.ObfuscationAttribute.OBFUSCATION_ATTRIBUTE, com.gtnewhorizons.retrofuturagradle.ObfuscationAttribute.getNoMinecraft(objects)) -// } -// } -//} diff --git a/dependencies.gradle b/dependencies.gradle index b20fe95..b58ba7b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,11 +1,13 @@ dependencies { - api 'com.github.GTNewHorizons:Forgelin:1.9.8-GTNH' - compileOnly('com.github.GTNewHorizons:NotEnoughItems:2.5.4-GTNH:dev') { transitive = false } - compileOnly('curse.maven:journeymap-32274:2367915') { transitive = false } - compileOnly('com.github.GTNewHorizons:VisualProspecting:1.2.4:dev') { transitive = false } - implementation project(':localization-generator') - ksp project(':localization-generator') + compileOnly('com.github.GTNewHorizons:NotEnoughItems:2.6.51-GTNH:dev') { transitive = false } + compileOnly('curse.maven:journeymap-32274:5769353') { transitive = false } + compileOnly('com.github.GTNewHorizons:VisualProspecting:1.3.28:dev') { transitive = false } + compileOnly('com.github.GTNewHorizons:Navigator:1.0.15:dev') { transitive = false } + compileOnly(deobfCurse('xaeros-minimap-263420:5637000')) + compileOnly(deobfCurse('xaeros-world-map-317780:5658209')) + + } diff --git a/gradle.properties b/gradle.properties index 189e5e6..a7a6cce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,7 @@ channel = stable mappingsVersion = 12 # Defines other MCP mappings for dependency deobfuscation. -remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/ +remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/ # Select a default username for testing your mod. You can always override this per-run by running # `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE. @@ -61,6 +61,9 @@ gradleTokenModId = # [DEPRECATED] Mod name replacement token. gradleTokenModName = +# [DEPRECATED] Mod Group replacement token. +gradleTokenGroupName = + # [DEPRECATED] # Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java # public static final String VERSION = "GRADLETOKEN_VERSION"; @@ -82,11 +85,16 @@ accessTransformersFile = # Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled! usesMixins = true +# Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main. +# This can speed up compile times thanks to not running the mixin annotation processor on all input sources. +# Mixin classes will have access to "main" classes, but not the other way around. +separateMixinSourceSet = + # Adds some debug arguments like verbose output and class export. -usesMixinDebug = false +usesMixinDebug = true # Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise. -mixinPlugin = mixinplugin.MixinPlugin +mixinPlugin = # Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! mixinsPackage = mixins @@ -94,7 +102,7 @@ mixinsPackage = mixins # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! # This parameter is for legacy compatibility only # Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin -coreModClass = +coreModClass = core.ShareWhereIAmCore # If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class # that is annotated with @Mod) you want this to be true. When in doubt: leave it on false! @@ -114,16 +122,22 @@ minimizeShadowedDependencies = true # If disabled, won't rename the shadowed classes. relocateShadowedDependencies = true -# Adds the GTNH maven, CurseMaven, IC2/Player maven, and some more well-known 1.7.10 repositories. +# Adds CurseMaven, Modrinth, and some more well-known 1.7.10 repositories. includeWellKnownRepositories = true +# A list of repositories to exclude from the includeWellKnownRepositories setting. Should be a space separated +# list of strings, with the acceptable keys being(case does not matter): +# cursemaven +# modrinth +excludeWellKnownRepositories = + # Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven. # Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables. # If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle. usesMavenPublishing = true # Maven repository to publish the mod to. -# mavenPublishUrl = https://nexus.gtnewhorizons.com/repository/releases/ +# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/ # Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token. # @@ -188,5 +202,4 @@ curseForgeRelations = # ideaCheckSpotlessOnBuild = true # Non-GTNH properties -gradleTokenGroupName = -rfg.disableDependencyDeobfuscation = true +#rfg.disableDependencyDeobfuscation = true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 34592 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 delta 34555 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a80b22c..e2847c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a4..f5feea6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30d..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/localization-generator/.gitignore b/localization-generator/.gitignore deleted file mode 100644 index 48c525b..0000000 --- a/localization-generator/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -.gradle -.settings -/.idea/ -/.vscode/ -/run/ -/build/ -/eclipse/ -.classpath -.project -/bin/ -/config/ -/crash-reports/ -/logs/ -options.txt -/saves/ -usernamecache.json -banned-ips.json -banned-players.json -eula.txt -ops.json -server.properties -servers.dat -usercache.json -whitelist.json -/out/ -*.iml -*.ipr -*.iws -src/main/resources/mixins.*.json -*.bat -*.DS_Store -!gradlew.bat diff --git a/localization-generator/build.gradle b/localization-generator/build.gradle deleted file mode 100644 index 5334fda..0000000 --- a/localization-generator/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' -} - -repositories { - mavenCentral() -} - -kotlin { - jvmToolchain(8) -} - -dependencies { - implementation 'com.google.devtools.ksp:symbol-processing-api:1.8.0-1.0.9' - implementation 'com.squareup:kotlinpoet:1.12.0' -} diff --git a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Localization.kt b/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Localization.kt deleted file mode 100644 index facaffe..0000000 --- a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Localization.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.muxiu1997.sharewhereiam.localization - -@Target(AnnotationTarget.PROPERTY) -annotation class Localization(val prefix: String, val en: String) diff --git a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationData.kt b/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationData.kt deleted file mode 100644 index af3618f..0000000 --- a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationData.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.muxiu1997.sharewhereiam.localizationgenerator - -data class LocalizationData(val cls: String, val name: String, val key: String, val en: String) { -} diff --git a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationGenerator.kt b/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationGenerator.kt deleted file mode 100644 index 701da1a..0000000 --- a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationGenerator.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.muxiu1997.sharewhereiam.localizationgenerator - -import com.google.devtools.ksp.processing.CodeGenerator -import com.google.devtools.ksp.processing.Dependencies -import com.google.devtools.ksp.symbol.KSPropertyDeclaration -import com.google.devtools.ksp.symbol.KSType -import com.squareup.kotlinpoet.FileSpec -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.MemberName -import com.squareup.kotlinpoet.TypeSpec -import com.squareup.kotlinpoet.ClassName - -import kotlin.concurrent.thread - -object LocalizationGenerator { - private val properties = mutableListOf() - - fun generate(codeGenerator: CodeGenerator) { - thread(true) { - val fileSpec = FileSpec.builder("com.muxiu1997.sharewhereiam.loader", "LocalizationLoader") - .addType( - TypeSpec.objectBuilder("LocalizationLoader") - .addFunction( - FunSpec.builder("load").also { funBuilder -> - properties.forEach { data -> - propertyToStatement(funBuilder, data) - } - } - .build() - ).build() - ).build() - codeGenerator.createNewFile( - dependencies = Dependencies(true), - packageName = fileSpec.packageName, - fileName = fileSpec.name, - ).use { outputStream -> - outputStream.writer().use { - fileSpec.writeTo(it) - } - } - val langFile = StringBuilder() - properties.forEach { langFile.append("${it.key}=${it.en}\n") } - codeGenerator.createNewFile( - dependencies = Dependencies(true), - packageName = "assets.sharewhereiam.lang", - fileName = "en_US", - extensionName = "lang" - ).use { outputStream -> - outputStream.writer().use { - it.write(langFile.toString()) - } - } - } - } - - fun add(property: KSPropertyDeclaration, annotationType: KSType) { - val qualifiedName = property.qualifiedName!! - val anno = property.annotations.find { it.annotationType.resolve() == annotationType }!! - val key = - "${anno.arguments.find { it.name?.getShortName() == "prefix" }!!.value!!}.${qualifiedName.getShortName()}" - val en = anno.arguments.find { it.name?.getShortName() == "en" }!!.value!!.toString() - val data = LocalizationData( - cls = qualifiedName.getQualifier(), - name = qualifiedName.getShortName(), - key = key, - en = en - ) - properties.add(data) - } - - private fun propertyToStatement(funBuilder: FunSpec.Builder, data: LocalizationData) { - val p = MemberName(data.cls, data.name) - val localizedString = ClassName(data.cls, "LocalizedString") - funBuilder.addStatement("%M = %T(%S)", p, localizedString, data.key) - } -} diff --git a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessor.kt b/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessor.kt deleted file mode 100644 index 90ffd65..0000000 --- a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessor.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.muxiu1997.sharewhereiam.localizationgenerator - -import com.google.devtools.ksp.processing.Resolver -import com.google.devtools.ksp.processing.SymbolProcessor -import com.google.devtools.ksp.processing.SymbolProcessorEnvironment -import com.google.devtools.ksp.symbol.KSAnnotated -import com.google.devtools.ksp.symbol.KSPropertyDeclaration -import com.muxiu1997.sharewhereiam.localization.Localization - -class LocalizationSymbolProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcessor { - override fun process(resolver: Resolver): List { - val annoType = resolver.getClassDeclarationByName( - resolver.getKSNameFromString(LocalizationAnnoName) - )?.asType(emptyList())!! - - resolver.getSymbolsWithAnnotation(LocalizationAnnoName) - .filterIsInstance() - .forEach { - LocalizationGenerator.add(it, annoType) - } - - LocalizationGenerator.generate(env.codeGenerator) - return emptyList() - } - - companion object { - val LocalizationAnnoName = requireNotNull(Localization::class.qualifiedName) - } -} diff --git a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessorProvider.kt b/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessorProvider.kt deleted file mode 100644 index 74cd67c..0000000 --- a/localization-generator/src/main/kotlin/com/muxiu1997/sharewhereiam/localizationgenerator/LocalizationSymbolProcessorProvider.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.muxiu1997.sharewhereiam.localizationgenerator - -import com.google.devtools.ksp.processing.SymbolProcessor -import com.google.devtools.ksp.processing.SymbolProcessorEnvironment -import com.google.devtools.ksp.processing.SymbolProcessorProvider - -class LocalizationSymbolProcessorProvider : SymbolProcessorProvider { - override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { - return LocalizationSymbolProcessor(environment) - } -} diff --git a/localization-generator/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/localization-generator/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider deleted file mode 100644 index ba14a4d..0000000 --- a/localization-generator/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +++ /dev/null @@ -1 +0,0 @@ -com.muxiu1997.sharewhereiam.localizationgenerator.LocalizationSymbolProcessorProvider diff --git a/settings.gradle b/settings.gradle index 12bf83a..0147a99 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,10 +17,7 @@ pluginManagement { } plugins { - id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.8' + id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.30' } - -include 'localization-generator' - diff --git a/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAm.java b/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAm.java index 08e9068..bca4148 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAm.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAm.java @@ -8,14 +8,13 @@ import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLPostInitializationEvent; -import cpw.mods.fml.common.event.FMLPreInitializationEvent; @Mod( modid = "sharewhereiam", version = Tags.VERSION, name = "Share Where I am", acceptedMinecraftVersions = "[1.7.10]", - dependencies = "required-after:spongemixins@[1.1.0,);") + dependencies = "required-after:gtnhmixins") public class ShareWhereIAm { @SuppressWarnings("unused") @@ -26,11 +25,6 @@ public class ShareWhereIAm { serverSide = "com.muxiu1997.sharewhereiam.proxy.CommonProxy") public static CommonProxy proxy; - @Mod.EventHandler - public void preInit(FMLPreInitializationEvent event) { - proxy.preInit(event); - } - @Mod.EventHandler public void postInit(FMLPostInitializationEvent event) { proxy.postInit(event); diff --git a/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAmLateMixin.java b/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAmLateMixin.java new file mode 100644 index 0000000..1d3d224 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAmLateMixin.java @@ -0,0 +1,22 @@ +package com.muxiu1997.sharewhereiam; + +import java.util.List; +import java.util.Set; + +import com.gtnewhorizon.gtnhmixins.ILateMixinLoader; +import com.gtnewhorizon.gtnhmixins.LateMixin; +import com.muxiu1997.sharewhereiam.mixins.Mixins; + +@LateMixin +public class ShareWhereIAmLateMixin implements ILateMixinLoader { + + @Override + public String getMixinConfig() { + return "mixins.sharewhereiam.late.json"; + } + + @Override + public List getMixins(Set loadedMods) { + return Mixins.getLateMixins(loadedMods); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java b/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java new file mode 100644 index 0000000..6f4fa43 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java @@ -0,0 +1,15 @@ +package com.muxiu1997.sharewhereiam.client.key; + +import net.minecraft.client.settings.KeyBinding; + +import org.lwjgl.input.Keyboard; + +import com.muxiu1997.sharewhereiam.localization.Lang; + +public class KeyShare { + + public static final KeyBinding INSTANCE = new KeyBinding( + Lang.KEYBINDING_SHARE_NAME.getKey(), + Keyboard.KEY_INSERT, + Lang.KEYBINDING_SHARE_CATEGORY.getKey()); +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandError.java b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandError.java new file mode 100644 index 0000000..8a4ee82 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandError.java @@ -0,0 +1,20 @@ +package com.muxiu1997.sharewhereiam.command; + +import net.minecraft.command.CommandException; + +import com.muxiu1997.sharewhereiam.localization.Lang; + +public enum CommandError { + + INVALID_WAYPOINT_CODE(Lang.ERROR_INVALID_WAYPOINT_CODE.getKey()); + + private final String localizationKey; + + CommandError(String localizationKey) { + this.localizationKey = localizationKey; + } + + public CommandException exception() { + return new CommandException(localizationKey); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java new file mode 100644 index 0000000..b5584af --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java @@ -0,0 +1,53 @@ +package com.muxiu1997.sharewhereiam.command; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; + +import com.muxiu1997.sharewhereiam.command.base.CommandWaypointBase; +import com.muxiu1997.sharewhereiam.localization.Lang; +import com.muxiu1997.sharewhereiam.mixininterfaces.IMixinWaypointStore; + +import journeymap.client.model.Waypoint; +import journeymap.client.ui.UIManager; +import journeymap.client.waypoint.WaypointStore; + +public class CommandWaypointSave extends CommandWaypointBase { + + public static CommandWaypointSave INSTANCE = new CommandWaypointSave(); + + public CommandWaypointSave() { + super("savewaypoint"); + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return Lang.SAVE_WAYPOINT_USAGE.getKey(); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + ensureArgsLength(args, 1, 2); + final Waypoint waypoint = parseWaypoint(args[0]); + boolean openWaypointEditor = parseOpenWaypointEditor(sender, args); + if (openWaypointEditor) { + UIManager.getInstance().openWaypointEditor(waypoint, true, null); + return; + } + if (((IMixinWaypointStore) WaypointStore.instance()).exists(waypoint)) { + sender.addChatMessage(new ChatComponentText(Lang.SAVE_WAYPOINT_EXISTS.translate())); + return; + } + WaypointStore.instance().add(waypoint); + sender.addChatMessage(new ChatComponentText(Lang.SAVE_WAYPOINT_SUCCESS.translate())); + } + + private boolean parseOpenWaypointEditor(ICommandSender sender, String[] args) throws CommandException { + boolean openWaypointEditor = true; + if (args.length == 2) { + openWaypointEditor = CommandBase.parseBoolean(sender, args[1]); + } + return openWaypointEditor; + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java new file mode 100644 index 0000000..37c59b3 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java @@ -0,0 +1,33 @@ +package com.muxiu1997.sharewhereiam.command; + +import static com.muxiu1997.sharewhereiam.network.NetworkHandler.network; + +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; + +import com.muxiu1997.sharewhereiam.command.base.CommandWaypointBase; +import com.muxiu1997.sharewhereiam.localization.Lang; +import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint; +import com.muxiu1997.sharewhereiam.util.WaypointUtil; + +public class CommandWaypointShareLocation extends CommandWaypointBase { + + public static CommandWaypointShareLocation INSTANCE = new CommandWaypointShareLocation(); + + public CommandWaypointShareLocation() { + super("sharewhereiam"); + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return Lang.SHARE_WHERE_I_AM_USAGE.getKey(); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + ensureArgsLength(args, 0); + assert sender instanceof EntityPlayer; + network.sendToServer(new MessageShareWaypoint(WaypointUtil.waypointOfLocation())); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java new file mode 100644 index 0000000..f70d5ed --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java @@ -0,0 +1,35 @@ +package com.muxiu1997.sharewhereiam.command; + +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; + +import com.muxiu1997.sharewhereiam.command.base.CommandWaypointBase; +import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointManager; +import com.muxiu1997.sharewhereiam.localization.Lang; + +import journeymap.client.model.Waypoint; + +public class CommandWaypointToggleTempBeacon extends CommandWaypointBase { + + public static CommandWaypointToggleTempBeacon INSTANCE = new CommandWaypointToggleTempBeacon(); + + public CommandWaypointToggleTempBeacon() { + super("toggletempbeacon"); + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return Lang.TOGGLE_TEMP_BEACON_USAGE.getKey(); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + ensureArgsLength(args, 0, 1); + if (args.length == 0) { + WaypointManager.clearActiveTempBeacon(); + return; + } + Waypoint waypoint = parseWaypoint(args[0]); + WaypointManager.toggleActiveTempBeacon(waypoint); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java b/src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java new file mode 100644 index 0000000..fd17dbd --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java @@ -0,0 +1,71 @@ +package com.muxiu1997.sharewhereiam.command.base; + +import static com.muxiu1997.sharewhereiam.util.WaypointUtil.fromBase64; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; + +import com.muxiu1997.sharewhereiam.command.CommandError; + +import journeymap.client.model.Waypoint; + +public abstract class CommandWaypointBase extends CommandBase { + + final protected String commandName; + protected String commandUsage; + + public CommandWaypointBase(@Nonnull String commandName) { + super(); + this.commandName = commandName; + } + + @Override + @Nonnull + public String getCommandName() { + return this.commandName; + } + + @Override + public int getRequiredPermissionLevel() { + return 0; + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender sender) { + if (!(sender instanceof AbstractClientPlayer)) return false; + return super.canCommandSenderUseCommand(sender); + } + + @Override + @Nonnull + public String getCommandUsage(ICommandSender sender) { + return commandUsage; + } + + @Nonnull + protected Waypoint parseWaypoint(@Nonnull String waypointCode) throws CommandException { + final Waypoint waypoint; + try { + waypoint = fromBase64(waypointCode); + } catch (Exception ignored) { + throw CommandError.INVALID_WAYPOINT_CODE.exception(); + } + return waypoint; + } + + protected void ensureArgsLength(@Nullable String[] args, int min, int max) throws CommandException { + final int argsLength = args != null ? args.length : 0; + if (argsLength < min || argsLength > max) new CommandException(commandUsage); + } + + protected void ensureArgsLength(@Nullable String[] args, int length) throws CommandException { + final int argsLength = args != null ? args.length : 0; + if (argsLength != length) new CommandException(commandUsage); + } + +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java b/src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java new file mode 100644 index 0000000..df2a44a --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java @@ -0,0 +1,46 @@ +package com.muxiu1997.sharewhereiam.core; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader; +import com.muxiu1997.sharewhereiam.mixins.Mixins; + +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; + +public class ShareWhereIAmCore implements IFMLLoadingPlugin, IEarlyMixinLoader { + + @Override + public String[] getASMTransformerClass() { + return new String[0]; + } + + @Override + public String getModContainerClass() { + return null; + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map data) {} + + @Override + public String getAccessTransformerClass() { + return null; + } + + @Override + public String getMixinConfig() { + return "mixins.sharewhereiam.early.json"; + } + + @Override + public List getMixins(Set loadedCoreMods) { + return Mixins.getEarlyMixins(loadedCoreMods); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java b/src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java new file mode 100644 index 0000000..a29b230 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java @@ -0,0 +1,71 @@ +package com.muxiu1997.sharewhereiam.event; + +import static com.muxiu1997.sharewhereiam.network.NetworkHandler.network; +import static com.muxiu1997.sharewhereiam.util.WaypointUtil.waypointOfLocation; +import static com.muxiu1997.sharewhereiam.util.WaypointUtil.waypointOfRayTrace; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; + +import org.lwjgl.input.Keyboard; + +import com.muxiu1997.sharewhereiam.client.key.KeyShare; +import com.muxiu1997.sharewhereiam.integration.Mods; +import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointManager; +import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointMarker; +import com.muxiu1997.sharewhereiam.network.MessageMarkWaypoint; +import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint; +import com.muxiu1997.sharewhereiam.util.WaypointUtil; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.InputEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class EventHandler { + + public static final EventHandler INSTANCE = new EventHandler(); + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public void handleEntityJoinWorld(EntityJoinWorldEvent event) { + if (event.world.isRemote && Mods.JourneyMap.isLoaded()) { + if (event.entity instanceof EntityPlayer) { + WaypointManager.clearActiveTempBeacon(); + } + } + } + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public void handleKeyInput(InputEvent.KeyInputEvent event) { + if (!KeyShare.INSTANCE.isPressed()) return; + + if (Mods.JourneyMap.isLoaded()) { + // Determine the waypoint based on Shift key state + WaypointUtil.PlayerWaypoint playerWaypoint; + if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { + playerWaypoint = waypointOfLocation(); + } else { + playerWaypoint = waypointOfRayTrace(); + } + + // Send the message based on Control key state + if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { + network.sendToServer(new MessageShareWaypoint(playerWaypoint)); + } else { + network.sendToServer(new MessageMarkWaypoint(playerWaypoint)); + } + } + } + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public void handleRenderWorldLast(RenderWorldLastEvent event) { + if (Mods.JourneyMap.isLoaded()) { + WaypointMarker.render(event); + } + } + +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java b/src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java new file mode 100644 index 0000000..5cf2d84 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java @@ -0,0 +1,27 @@ +package com.muxiu1997.sharewhereiam.integration; + +import cpw.mods.fml.common.Loader; + +public enum Mods { + + VisualProspecting("visualprospecting"), + JourneyMap("journeymap"), + Navigator("navigator"), + + ; + + public final String modid; + private boolean loaded; + + Mods(String modid) { + this.modid = modid; + } + + public boolean isLoaded() { + return loaded; + } + + public void check() { + this.loaded = Loader.isModLoaded(modid); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java new file mode 100644 index 0000000..a6d5b27 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java @@ -0,0 +1,66 @@ +package com.muxiu1997.sharewhereiam.integration.journeymap; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; + +import net.minecraft.client.Minecraft; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import journeymap.client.model.Waypoint; + +@SideOnly(Side.CLIENT) +public class WaypointManager { + + public static WaypointManager INSTANCE = new WaypointManager(); + + public static Waypoint tempBeacon = null; + private static final Map transientBeaconCache = new HashMap<>(); + + @Nullable + public Waypoint getTempBeacon() { + return this.tempBeacon; + } + + public static boolean hasActiveTempBeacon() { + return tempBeacon != null; + } + + public static void clearActiveTempBeacon() { + tempBeacon = null; + } + + public static void toggleActiveTempBeacon(Waypoint waypoint) { + if (waypoint.equals(tempBeacon)) { + tempBeacon = null; + return; + } + tempBeacon = waypoint; + } + + public static void addTransientBeacon(String playerName, Waypoint waypoint) { + transientBeaconCache.put(playerName, new TransientBeacon(waypoint, Minecraft.getSystemTime())); + } + + public static List getTransientBeacons() { + long currentTime = Minecraft.getSystemTime(); + transientBeaconCache.entrySet().removeIf(entry -> currentTime - entry.getValue().start > 3000); + return transientBeaconCache.values().stream().map(transientBeacon -> transientBeacon.waypoint) + .collect(Collectors.toList()); + } + + public static class TransientBeacon { + + public final Waypoint waypoint; + public final long start; + + public TransientBeacon(Waypoint waypoint, long start) { + this.waypoint = waypoint; + this.start = start; + } + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java new file mode 100644 index 0000000..cbf38dd --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java @@ -0,0 +1,94 @@ +package com.muxiu1997.sharewhereiam.integration.journeymap; + +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.client.event.RenderWorldLastEvent; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import journeymap.client.model.Waypoint; + +@SideOnly(Side.CLIENT) +public class WaypointMarker { + + public static void render(RenderWorldLastEvent event) { + List transientBeacons = WaypointManager.INSTANCE.getTransientBeacons(); + if (transientBeacons.isEmpty()) return; + + float partialTicks = event.partialTicks; + Minecraft minecraft = Minecraft.getMinecraft(); + double posX = minecraft.thePlayer.prevPosX + + (minecraft.thePlayer.posX - minecraft.thePlayer.prevPosX) * partialTicks; + double posY = minecraft.thePlayer.prevPosY + + (minecraft.thePlayer.posY - minecraft.thePlayer.prevPosY) * partialTicks; + double posZ = minecraft.thePlayer.prevPosZ + + (minecraft.thePlayer.posZ - minecraft.thePlayer.prevPosZ) * partialTicks; + + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + GL11.glPushMatrix(); + GL11.glTranslated(-posX, -posY, -posZ); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST); + + GL11.glBegin(GL11.GL_QUADS); + for (Waypoint waypoint : transientBeacons) { + markWaypoint(waypoint); + } + GL11.glEnd(); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glPopMatrix(); + GL11.glPopAttrib(); + } + + private static void markWaypoint(Waypoint waypoint) { + double x = waypoint.getX(); + double y = waypoint.getY(); + double z = waypoint.getZ(); + + GL11.glColor4d(255.0, 255.0, 255.0, 0.8); + + // NORTH + GL11.glVertex3d(x, y + 1, z); + GL11.glVertex3d(x + 1, y + 1, z); + GL11.glVertex3d(x + 1, y, z); + GL11.glVertex3d(x, y, z); + + // EAST + GL11.glVertex3d(x + 1, y, z + 1); + GL11.glVertex3d(x + 1, y, z); + GL11.glVertex3d(x + 1, y + 1, z); + GL11.glVertex3d(x + 1, y + 1, z + 1); + + // SOUTH + GL11.glVertex3d(x + 1, y + 1, z + 1); + GL11.glVertex3d(x, y + 1, z + 1); + GL11.glVertex3d(x, y, z + 1); + GL11.glVertex3d(x + 1, y, z + 1); + + // WEST + GL11.glVertex3d(x, y + 1, z + 1); + GL11.glVertex3d(x, y + 1, z); + GL11.glVertex3d(x, y, z); + GL11.glVertex3d(x, y, z + 1); + + // TOP + GL11.glVertex3d(x, y + 1, z); + GL11.glVertex3d(x, y + 1, z + 1); + GL11.glVertex3d(x + 1, y + 1, z + 1); + GL11.glVertex3d(x + 1, y + 1, z); + + // BOTTOM + GL11.glVertex3d(x + 1, y, z); + GL11.glVertex3d(x + 1, y, z + 1); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java new file mode 100644 index 0000000..a7e67c9 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java @@ -0,0 +1,22 @@ +package com.muxiu1997.sharewhereiam.loader; + +import net.minecraftforge.client.ClientCommandHandler; + +import com.muxiu1997.sharewhereiam.command.CommandWaypointSave; +import com.muxiu1997.sharewhereiam.command.CommandWaypointShareLocation; +import com.muxiu1997.sharewhereiam.command.CommandWaypointToggleTempBeacon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class CommandLoader { + + public static CommandLoader INSTANCE = new CommandLoader(); + + @SideOnly(Side.CLIENT) + public void clientLoad() { + ClientCommandHandler.instance.registerCommand(CommandWaypointSave.INSTANCE); + ClientCommandHandler.instance.registerCommand(CommandWaypointShareLocation.INSTANCE); + ClientCommandHandler.instance.registerCommand(CommandWaypointToggleTempBeacon.INSTANCE); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java new file mode 100644 index 0000000..56132c8 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java @@ -0,0 +1,17 @@ +package com.muxiu1997.sharewhereiam.loader; + +import net.minecraftforge.common.MinecraftForge; + +import com.muxiu1997.sharewhereiam.event.EventHandler; + +import cpw.mods.fml.common.FMLCommonHandler; + +public class EventLoader { + + public static final EventLoader INSTANCE = new EventLoader(); + + public void load() { + MinecraftForge.EVENT_BUS.register(EventHandler.INSTANCE); + FMLCommonHandler.instance().bus().register(EventHandler.INSTANCE); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java new file mode 100644 index 0000000..90457c7 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java @@ -0,0 +1,14 @@ +package com.muxiu1997.sharewhereiam.loader; + +import java.util.Arrays; + +import com.muxiu1997.sharewhereiam.integration.Mods; + +public class IntegrationLoader { + + public static final IntegrationLoader INSTANCE = new IntegrationLoader(); + + public void load() { + Arrays.stream(Mods.values()).forEach(Mods::check); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java new file mode 100644 index 0000000..a7a4a93 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java @@ -0,0 +1,17 @@ +package com.muxiu1997.sharewhereiam.loader; + +import com.muxiu1997.sharewhereiam.client.key.KeyShare; + +import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class KeyLoader { + + public static final KeyLoader INSTANCE = new KeyLoader(); + + public void clientLoad() { + ClientRegistry.registerKeyBinding(KeyShare.INSTANCE); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java new file mode 100644 index 0000000..4ef16fd --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java @@ -0,0 +1,28 @@ +package com.muxiu1997.sharewhereiam.loader; + +import static com.muxiu1997.sharewhereiam.network.NetworkHandler.network; + +import com.muxiu1997.sharewhereiam.network.MessageMarkWaypoint; +import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.relauncher.Side; + +public class NetworkLoader { + + public static final NetworkLoader INSTANCE = new NetworkLoader(); + + private static int nextID = 0; + + public static void load() { + register(MessageShareWaypoint.Handler.class, MessageShareWaypoint.class); + register(MessageMarkWaypoint.Handler.class, MessageMarkWaypoint.class); + } + + private static void register( + Class> messageHandler, Class requestMessageType) { + network.registerMessage(messageHandler, requestMessageType, nextID++, Side.SERVER); + network.registerMessage(messageHandler, requestMessageType, nextID++, Side.CLIENT); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java b/src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java new file mode 100644 index 0000000..4fae79e --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java @@ -0,0 +1,74 @@ +package com.muxiu1997.sharewhereiam.localization; + +import net.minecraft.client.resources.I18n; + +public class Lang { + + // Localized strings + public static LocalizedString SAVE_WAYPOINT_USAGE; + public static LocalizedString SAVE_WAYPOINT_SUCCESS; + public static LocalizedString SAVE_WAYPOINT_EXISTS; + public static LocalizedString SHARE_WHERE_I_AM_USAGE; + public static LocalizedString TOGGLE_TEMP_BEACON_USAGE; + public static LocalizedString ERROR_INVALID_WAYPOINT_CODE; + public static LocalizedString SHARE_WAYPOINT_MSG; + public static LocalizedString SHARE_WAYPOINT_SAVE; + public static LocalizedString SHARE_WAYPOINT_SAVE_DESC; + public static LocalizedString SHARE_WAYPOINT_EDIT; + public static LocalizedString SHARE_WAYPOINT_EDIT_DESC; + public static LocalizedString SHARE_WAYPOINT_TOGGLE; + public static LocalizedString SHARE_WAYPOINT_TOGGLE_DESC; + public static LocalizedString SHARE_WAYPOINT_VP; + public static LocalizedString KEYBINDING_SHARE_NAME; + public static LocalizedString KEYBINDING_SHARE_CATEGORY; + public static LocalizedString TEXT_DEFAULT_WAYPOINT_NAME; + public static LocalizedString TEXT_JM_WAYPOINT_BUTTON; + + // Constants for prefix + private static final String PREFIX_COMMAND = "sharewhereiam.command"; + private static final String PREFIX_COMMAND_ERROR = "sharewhereiam.commanderror"; + private static final String PREFIX_CHAT = "sharewhereiam.chat"; + private static final String PREFIX_KEYBINDING = "sharewhereiam.keybinding"; + private static final String PREFIX_TEXT = "sharewhereiam.text"; + + // Initialize the localized strings + static { + SAVE_WAYPOINT_USAGE = new LocalizedString(PREFIX_COMMAND + ".usage"); + SAVE_WAYPOINT_SUCCESS = new LocalizedString(PREFIX_COMMAND + ".save.success"); + SAVE_WAYPOINT_EXISTS = new LocalizedString(PREFIX_COMMAND + ".save.exists"); + SHARE_WHERE_I_AM_USAGE = new LocalizedString(PREFIX_COMMAND + ".sharewhereiam.usage"); + TOGGLE_TEMP_BEACON_USAGE = new LocalizedString(PREFIX_COMMAND + ".toggletempbeacon.usage"); + ERROR_INVALID_WAYPOINT_CODE = new LocalizedString(PREFIX_COMMAND_ERROR + ".invalidcode"); + SHARE_WAYPOINT_MSG = new LocalizedString(PREFIX_CHAT + ".share"); + SHARE_WAYPOINT_SAVE = new LocalizedString(PREFIX_CHAT + ".save"); + SHARE_WAYPOINT_SAVE_DESC = new LocalizedString(PREFIX_CHAT + ".save.desc"); + SHARE_WAYPOINT_EDIT = new LocalizedString(PREFIX_CHAT + ".edit"); + SHARE_WAYPOINT_EDIT_DESC = new LocalizedString(PREFIX_CHAT + ".edit.desc"); + SHARE_WAYPOINT_TOGGLE = new LocalizedString(PREFIX_CHAT + ".toggle"); + SHARE_WAYPOINT_TOGGLE_DESC = new LocalizedString(PREFIX_CHAT + ".toggle.desc"); + SHARE_WAYPOINT_VP = new LocalizedString(PREFIX_CHAT + ".additionalInformation.VP"); + KEYBINDING_SHARE_NAME = new LocalizedString(PREFIX_KEYBINDING + ".share.name"); + KEYBINDING_SHARE_CATEGORY = new LocalizedString(PREFIX_KEYBINDING + ".share.category"); + TEXT_DEFAULT_WAYPOINT_NAME = new LocalizedString(PREFIX_TEXT + ".default_waypoint_name"); + TEXT_JM_WAYPOINT_BUTTON = new LocalizedString(PREFIX_TEXT + ".jm.waypoint.share"); + } + + // LocalizedString class + public static class LocalizedString { + + private final String key; + + public LocalizedString(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + // Method to translate the string using Minecraft's I18n system + public String translate() { + return I18n.format(key); + } + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/MixinPlugin.java b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/MixinPlugin.java deleted file mode 100644 index 3ef8aba..0000000 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/MixinPlugin.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.muxiu1997.sharewhereiam.mixinplugin; - -import static java.nio.file.Files.walk; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import net.minecraft.launchwrapper.Launch; - -import org.spongepowered.asm.lib.tree.ClassNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; - -import com.google.common.io.Files; - -import cpw.mods.fml.relauncher.FMLLaunchHandler; -import ru.timeconqueror.spongemixins.MinecraftURLClassPath; - -public class MixinPlugin implements IMixinConfigPlugin { - - @Override - public void onLoad(String mixinPackage) {} - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - return true; - } - - @Override - public void acceptTargets(Set myTargets, Set otherTargets) {} - - @Override - public List getMixins() { - final File journeyMapModJar = findJourneyMapModJar(); - if (journeyMapModJar == null) return null; - if (!journeyMapModJar.exists()) return null; - try { - MinecraftURLClassPath.addJar(journeyMapModJar); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - final List mixins = new ArrayList<>(4); - if (FMLLaunchHandler.side().isClient()) { - mixins.add("journeymap.MixinWaypointManagerItem"); - mixins.add("journeymap.MixinWaypointStore"); - mixins.add("journeymap.MixinRenderWaypointBeacon"); - mixins.add("journeymap.MixinFullscreen"); - } - return mixins; - } - - @SuppressWarnings({ "UnstableApiUsage", "resource" }) - private static File findJourneyMapModJar() { - try { - return walk(new File(Launch.minecraftHome, "mods/").toPath()).filter(path -> { - final String pathString = path.toString(); - final String nameLowerCase = Files.getNameWithoutExtension(pathString).toLowerCase(); - final String fileExtension = Files.getFileExtension(pathString); - return nameLowerCase.startsWith("journeymap-1.7.10") && "jar".equals(fileExtension); - }).map(Path::toFile).findFirst().orElse(null); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} - - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} -} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java new file mode 100644 index 0000000..cce5edb --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java @@ -0,0 +1,186 @@ +package com.muxiu1997.sharewhereiam.mixins; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import com.muxiu1997.sharewhereiam.ShareWhereIAm; + +import cpw.mods.fml.relauncher.FMLLaunchHandler; + +public enum Mixins { + + JOURNEYMAP_(new Builder("JourneyMap integration").addTargetedMod(TargetedMod.JOURNEYMAP).setSide(Side.CLIENT) + .setPhase(Phase.LATE).addMixinClasses( + "journeymap.MixinFullscreen", + "journeymap.MixinRenderWaypointBeacon", + "journeymap.MixinWaypointManagerItem", + "journeymap.MixinWaypointStore")), + NAVIGATOR_(new Builder("Navigator integration").addTargetedMod(TargetedMod.NAVIGATOR).setSide(Side.CLIENT) + .setPhase(Phase.LATE).addMixinClasses( + "navigator.HoveredDrawStepAccessor", + "navigator.HoveredRenderStepAccessor" + )); + + + private final List mixinClasses; + private final Supplier applyIf; + private final Phase phase; + private final Side side; + private final List targetedMods; + private final List excludedMods; + + Mixins(Builder builder) { + this.mixinClasses = builder.mixinClasses; + this.applyIf = builder.applyIf; + this.side = builder.side; + this.targetedMods = builder.targetedMods; + this.excludedMods = builder.excludedMods; + this.phase = builder.phase; + if (this.targetedMods.isEmpty()) { + throw new RuntimeException("No targeted mods specified for " + this.name()); + } + if (this.applyIf == null) { + throw new RuntimeException("No ApplyIf function specified for " + this.name()); + } + } + + public static List getEarlyMixins(Set loadedCoreMods) { + // This may be possible to handle differently or fix. + final List mixins = new ArrayList<>(); + final List notLoading = new ArrayList<>(); + for (Mixins mixin : Mixins.values()) { + if (mixin.phase == Mixins.Phase.EARLY) { + if (mixin.shouldLoad(loadedCoreMods, Collections.emptySet())) { + mixins.addAll(mixin.mixinClasses); + } else { + notLoading.addAll(mixin.mixinClasses); + } + } + } + ShareWhereIAm.logger.info("Not loading the following EARLY mixins: {}", notLoading); + return mixins; + } + + public static List getLateMixins(Set loadedMods) { + final List mixins = new ArrayList<>(); + final List notLoading = new ArrayList<>(); + for (Mixins mixin : Mixins.values()) { + if (mixin.phase == Mixins.Phase.LATE) { + if (mixin.shouldLoad(Collections.emptySet(), loadedMods)) { + mixins.addAll(mixin.mixinClasses); + } else { + notLoading.addAll(mixin.mixinClasses); + } + } + } + ShareWhereIAm.logger.info("Not loading the following LATE mixins: {}", notLoading.toString()); + return mixins; + } + + private boolean shouldLoadSide() { + return side == Side.BOTH || (side == Side.SERVER && FMLLaunchHandler.side().isServer()) + || (side == Side.CLIENT && FMLLaunchHandler.side().isClient()); + } + + private boolean allModsLoaded(List targetedMods, Set loadedCoreMods, Set loadedMods) { + if (targetedMods.isEmpty()) return false; + + for (TargetedMod target : targetedMods) { + if (target == TargetedMod.VANILLA) continue; + + // Check coremod first + if (!loadedCoreMods.isEmpty() && target.coreModClass != null + && !loadedCoreMods.contains(target.coreModClass)) + return false; + else if (!loadedMods.isEmpty() && target.modId != null && !loadedMods.contains(target.modId)) return false; + } + + return true; + } + + private boolean noModsLoaded(List targetedMods, Set loadedCoreMods, Set loadedMods) { + if (targetedMods.isEmpty()) return true; + + for (TargetedMod target : targetedMods) { + if (target == TargetedMod.VANILLA) continue; + + // Check coremod first + if (!loadedCoreMods.isEmpty() && target.coreModClass != null + && loadedCoreMods.contains(target.coreModClass)) + return false; + else if (!loadedMods.isEmpty() && target.modId != null && loadedMods.contains(target.modId)) return false; + } + + return true; + } + + private boolean shouldLoad(Set loadedCoreMods, Set loadedMods) { + return (shouldLoadSide() && applyIf.get() + && allModsLoaded(targetedMods, loadedCoreMods, loadedMods) + && noModsLoaded(excludedMods, loadedCoreMods, loadedMods)); + } + + private static class Builder { + + private final List mixinClasses = new ArrayList<>(); + private Supplier applyIf = () -> true; + private Side side = Side.BOTH; + private Phase phase = Phase.LATE; + private final List targetedMods = new ArrayList<>(); + private final List excludedMods = new ArrayList<>(); + + public Builder(@SuppressWarnings("unused") String description) {} + + public Builder addMixinClasses(String... mixinClasses) { + this.mixinClasses.addAll(Arrays.asList(mixinClasses)); + return this; + } + + public Builder setPhase(Phase phase) { + this.phase = phase; + return this; + } + + public Builder setSide(Side side) { + this.side = side; + return this; + } + + public Builder setApplyIf(Supplier applyIf) { + this.applyIf = applyIf; + return this; + } + + public Builder addTargetedMod(TargetedMod mod) { + this.targetedMods.add(mod); + return this; + } + + public Builder addExcludedMod(TargetedMod mod) { + this.excludedMods.add(mod); + return this; + } + } + + @SuppressWarnings("SimplifyStreamApiCallChains") + private static String[] addPrefix(String prefix, String... values) { + return Arrays.stream(values).map(s -> prefix + s).collect(Collectors.toList()) + .toArray(new String[values.length]); + } + + private enum Side { + BOTH, + CLIENT, + SERVER + } + + private enum Phase { + EARLY, + LATE, + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java new file mode 100644 index 0000000..88ff401 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java @@ -0,0 +1,32 @@ +package com.muxiu1997.sharewhereiam.mixins; + +public enum TargetedMod { + + VANILLA("Minecraft", null), + JOURNEYMAP("JourneyMap", null, "journeymap"), + XAEROMINIMAP("Xaero's Minimap", "xaero.common.core.XaeroMinimapPlugin", "XaeroMinimap"), + XAEROWORLDMAP("Xaero's World Map", "xaero.map.core.XaeroWorldMapPlugin", "XaeroWorldMap"), + NAVIGATOR("Navigator","com.gtnewhorizons.navigator.core","navigator"); + + /** The "name" in the @Mod annotation */ + public final String modName; + /** Class that implements the IFMLLoadingPlugin interface */ + public final String coreModClass; + /** The "modid" in the @Mod annotation */ + public final String modId; + + TargetedMod(String modName, String coreModClass) { + this(modName, coreModClass, null); + } + + TargetedMod(String modName, String coreModClass, String modId) { + this.modName = modName; + this.coreModClass = coreModClass; + this.modId = modId; + } + + @Override + public String toString() { + return "TargetedMod{modName='" + modName + "', coreModClass='" + coreModClass + "', modId='" + modId + "'}"; + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinFullscreen.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinFullscreen.java similarity index 87% rename from src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinFullscreen.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinFullscreen.java index ced212f..743bc21 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinFullscreen.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinFullscreen.java @@ -1,4 +1,4 @@ -package com.muxiu1997.sharewhereiam.mixins.journeymap; +package com.muxiu1997.sharewhereiam.mixins.late.journeymap; import static com.muxiu1997.sharewhereiam.network.NetworkHandler.network; @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.muxiu1997.sharewhereiam.client.KeyBinding; +import com.muxiu1997.sharewhereiam.client.key.KeyShare; import com.muxiu1997.sharewhereiam.integration.Mods; import com.muxiu1997.sharewhereiam.localization.Lang; import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint; @@ -40,8 +40,8 @@ public MixinFullscreen() { @Inject(method = "func_73869_a", at = @At(value = "HEAD"), remap = false, require = 1, cancellable = true) private void inject_func_73869_a(CallbackInfo callbackInfo) { - if (!Mods.VISUAL_PROSPECTING.isLoaded()) return; - if ((chat == null || chat.isHidden()) && Constants.isPressed(KeyBinding.KeyShare)) { + if (!Mods.VisualProspecting.isLoaded()) return; + if ((chat == null || chat.isHidden()) && Constants.isPressed(KeyShare.INSTANCE)) { @Nullable final Waypoint waypoint = VPWaypointUtil.getHoveredWaypoint(); if (waypoint == null) return; @@ -49,7 +49,7 @@ private void inject_func_73869_a(CallbackInfo callbackInfo) { network.sendToServer( new MessageShareWaypoint( new WaypointUtil.PlayerWaypoint(player, waypoint), - Lang.SHARE_WAYPOINT_VP.invoke())); + Lang.SHARE_WAYPOINT_VP.translate())); callbackInfo.cancel(); } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinRenderWaypointBeacon.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinRenderWaypointBeacon.java similarity index 95% rename from src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinRenderWaypointBeacon.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinRenderWaypointBeacon.java index 55edc65..256c5ef 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinRenderWaypointBeacon.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinRenderWaypointBeacon.java @@ -1,4 +1,4 @@ -package com.muxiu1997.sharewhereiam.mixins.journeymap; +package com.muxiu1997.sharewhereiam.mixins.late.journeymap; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinWaypointManagerItem.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointManagerItem.java similarity index 96% rename from src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinWaypointManagerItem.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointManagerItem.java index b1e650e..3fac424 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinWaypointManagerItem.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointManagerItem.java @@ -1,4 +1,4 @@ -package com.muxiu1997.sharewhereiam.mixins.journeymap; +package com.muxiu1997.sharewhereiam.mixins.late.journeymap; import static com.muxiu1997.sharewhereiam.network.NetworkHandler.network; @@ -40,7 +40,7 @@ public abstract class MixinWaypointManagerItem { require = 1, remap = false) private Button[] redirect_init(Button[] buttons) { - this.buttonShare = new Button(Lang.TEXT_JM_WAYPOINT_BUTTON.invoke()); + this.buttonShare = new Button(Lang.TEXT_JM_WAYPOINT_BUTTON.translate()); Button[] newButtons = new Button[buttons.length + 1]; System.arraycopy(buttons, 0, newButtons, 1, buttons.length); newButtons[0] = this.buttonShare; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinWaypointStore.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointStore.java similarity index 92% rename from src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinWaypointStore.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointStore.java index 743c8c4..c0158dc 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/journeymap/MixinWaypointStore.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointStore.java @@ -1,4 +1,4 @@ -package com.muxiu1997.sharewhereiam.mixins.journeymap; +package com.muxiu1997.sharewhereiam.mixins.late.journeymap; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java new file mode 100644 index 0000000..5a4e1c2 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java @@ -0,0 +1,73 @@ +package com.muxiu1997.sharewhereiam.network; + +import static com.muxiu1997.sharewhereiam.network.NetworkHandler.network; + +import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointManager; +import com.muxiu1997.sharewhereiam.util.WaypointUtil; + +import cpw.mods.fml.common.network.ByteBufUtils; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import journeymap.client.model.Waypoint; + +public class MessageMarkWaypoint implements IMessage { + + private String playerName; + private String waypointJson; + + // Default constructor + public MessageMarkWaypoint() {} + + // Client-side constructor + @SideOnly(Side.CLIENT) + public MessageMarkWaypoint(WaypointUtil.PlayerWaypoint playerWaypoint) { + this.playerName = playerWaypoint.player.getDisplayName(); + this.waypointJson = playerWaypoint.waypoint.toString(); + } + + @Override + public void fromBytes(ByteBuf buf) { + playerName = ByteBufUtils.readUTF8String(buf); + waypointJson = ByteBufUtils.readUTF8String(buf); + } + + @Override + public void toBytes(ByteBuf buf) { + ByteBufUtils.writeUTF8String(buf, playerName); + ByteBufUtils.writeUTF8String(buf, waypointJson); + } + + public static class Handler implements IMessageHandler, + NetworkHandler.IClientSideHandler, NetworkHandler.IServerSideHandler { + + @Override + public IMessage onMessage(MessageMarkWaypoint message, MessageContext ctx) { + switch (ctx.side) { + case CLIENT: + handleClientSideMessage(message); + break; + case SERVER: + handleServerSideMessage(message); + break; + default: + // No action for other sides + break; + } + return null; + } + + @SideOnly(Side.CLIENT) + private void handleClientSideMessage(MessageMarkWaypoint message) { + WaypointManager.addTransientBeacon(message.playerName, Waypoint.fromString(message.waypointJson)); + } + + private void handleServerSideMessage(MessageMarkWaypoint message) { + // Assuming 'network' is properly initialized and refers to the network instance to send the message + network.sendToAll(message); + } + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java new file mode 100644 index 0000000..e4e28c8 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java @@ -0,0 +1,82 @@ +package com.muxiu1997.sharewhereiam.network; + +import static com.muxiu1997.sharewhereiam.network.NetworkHandler.network; + +import com.muxiu1997.sharewhereiam.integration.Mods; +import com.muxiu1997.sharewhereiam.util.WaypointUtil; + +import cpw.mods.fml.common.network.ByteBufUtils; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; + +public class MessageShareWaypoint implements IMessage { + + public String playerName; + public String waypointJson; + public String additionalInformation; + + public MessageShareWaypoint() {} + + // Client-side constructor + @SideOnly(Side.CLIENT) + public MessageShareWaypoint(WaypointUtil.PlayerWaypoint playerWaypoint) { + this(playerWaypoint, ""); + } + + // Client-side constructor with additional information + @SideOnly(Side.CLIENT) + public MessageShareWaypoint(WaypointUtil.PlayerWaypoint playerWaypoint, String additionalInformation) { + this.playerName = playerWaypoint.player.getDisplayName(); + this.waypointJson = playerWaypoint.waypoint.toString(); + this.additionalInformation = additionalInformation; + } + + @Override + public void fromBytes(ByteBuf buf) { + playerName = ByteBufUtils.readUTF8String(buf); + waypointJson = ByteBufUtils.readUTF8String(buf); + additionalInformation = ByteBufUtils.readUTF8String(buf); + } + + @Override + public void toBytes(ByteBuf buf) { + ByteBufUtils.writeUTF8String(buf, playerName); + ByteBufUtils.writeUTF8String(buf, waypointJson); + ByteBufUtils.writeUTF8String(buf, additionalInformation); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(MessageShareWaypoint message, MessageContext ctx) { + if (ctx.side.isClient()) { + handleClientSideMessage(message); + } else { + handleServerSideMessage(message); + } + return null; + } + + // Client-side handler for displaying the waypoint information + @SideOnly(Side.CLIENT) + private static void handleClientSideMessage(MessageShareWaypoint message) { + if (Mods.JourneyMap.isLoaded()) { + WaypointUtil.addShareWaypointChat( + message.playerName, + WaypointUtil.waypointFromString(message.waypointJson), // Dereferences JourneyMap class import + // to stop crashes on + // clients that don't have JourneyMap installed. + message.additionalInformation); + } + } + + // Server-side handler for sending the message to all clients + private static void handleServerSideMessage(MessageShareWaypoint message) { + network.sendToAll(message); + } + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/network/NetworkHandler.java b/src/main/java/com/muxiu1997/sharewhereiam/network/NetworkHandler.java new file mode 100644 index 0000000..9951d72 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/network/NetworkHandler.java @@ -0,0 +1,16 @@ +package com.muxiu1997.sharewhereiam.network; + +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; + +public class NetworkHandler { + + public static final SimpleNetworkWrapper network = NetworkRegistry.INSTANCE.newSimpleChannel("sharewhereiam"); + + // Define empty interfaces for client and server-side handlers + public interface IServerSideHandler { + } + + public interface IClientSideHandler { + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java b/src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java new file mode 100644 index 0000000..b1062e6 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java @@ -0,0 +1,17 @@ +package com.muxiu1997.sharewhereiam.proxy; + +import com.muxiu1997.sharewhereiam.loader.CommandLoader; +import com.muxiu1997.sharewhereiam.loader.KeyLoader; + +import cpw.mods.fml.common.event.FMLPostInitializationEvent; + +@SuppressWarnings("unused") +public class ClientProxy extends CommonProxy { + + @Override + public void postInit(FMLPostInitializationEvent event) { + super.postInit(event); + CommandLoader.INSTANCE.clientLoad(); + KeyLoader.INSTANCE.clientLoad(); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java b/src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java new file mode 100644 index 0000000..11856ba --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java @@ -0,0 +1,16 @@ +package com.muxiu1997.sharewhereiam.proxy; + +import com.muxiu1997.sharewhereiam.loader.EventLoader; +import com.muxiu1997.sharewhereiam.loader.IntegrationLoader; +import com.muxiu1997.sharewhereiam.loader.NetworkLoader; + +import cpw.mods.fml.common.event.FMLPostInitializationEvent; + +public class CommonProxy { + + public void postInit(FMLPostInitializationEvent event) { + IntegrationLoader.INSTANCE.load(); + EventLoader.INSTANCE.load(); + NetworkLoader.INSTANCE.load(); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java b/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java new file mode 100644 index 0000000..f75ff50 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java @@ -0,0 +1,64 @@ +package com.muxiu1997.sharewhereiam.util; + +import java.awt.Color; +import java.lang.reflect.Field; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.gtnewhorizons.navigator.api.NavigatorApi; +import com.gtnewhorizons.navigator.api.journeymap.drawsteps.JMInteractableStep; +import com.gtnewhorizons.navigator.api.journeymap.render.JMInteractableLayerRenderer; +import com.gtnewhorizons.navigator.api.model.SupportedMods; +import com.gtnewhorizons.navigator.api.model.layers.InteractableLayerManager; +import com.gtnewhorizons.navigator.api.model.layers.LayerManager; + +import com.gtnewhorizons.navigator.api.model.layers.LayerRenderer; +import com.gtnewhorizons.navigator.api.model.layers.UniversalInteractableRenderer; +import com.gtnewhorizons.navigator.api.model.steps.RenderStep; +import com.gtnewhorizons.navigator.api.model.steps.UniversalInteractableStep; +import com.gtnewhorizons.navigator.api.model.waypoints.Waypoint; + +import com.sinthoras.visualprospecting.integration.model.layers.OreVeinLayerManager; +import com.sinthoras.visualprospecting.integration.model.locations.OreVeinLocation; +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.relauncher.ReflectionHelper; + + +public class VPWaypointUtil { + + @Nullable + @Optional.Method(modid = "navigator") + public static journeymap.client.model.Waypoint getHoveredWaypoint() { + for (LayerRenderer layer : NavigatorApi.getActiveRenderersFor(SupportedMods.JourneyMap)) { + if (layer instanceof UniversalInteractableRenderer) { + final Field FieldHoveredDrawStep = ReflectionHelper.findField(UniversalInteractableRenderer.class, "hoveredRenderStep"); + @Nullable UniversalInteractableStep hoveredRenderStep = null; + try { + hoveredRenderStep = (UniversalInteractableStep) FieldHoveredDrawStep.get(layer); + } catch (Exception ignored) {} + if (hoveredRenderStep != null) { + final Waypoint waypoint = hoveredRenderStep.getLocation().toWaypoint(); + if (waypoint != null) { + return getJMWaypoint(waypoint); + } + } + } + } + return null; + } + + @Nonnull + @Optional.Method(modid = "navigator") + public static journeymap.client.model.Waypoint getJMWaypoint(@Nonnull Waypoint waypoint) { + return new journeymap.client.model.Waypoint( + waypoint.label, + waypoint.blockX, + waypoint.blockY, + waypoint.blockZ, + new Color(waypoint.color), + journeymap.client.model.Waypoint.Type.Normal, + waypoint.dimensionId); + } +} + diff --git a/src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java b/src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java new file mode 100644 index 0000000..3a6094c --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java @@ -0,0 +1,144 @@ +package com.muxiu1997.sharewhereiam.util; + +import static journeymap.client.cartography.RGB.WHITE_RGB; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.event.ClickEvent; +import net.minecraft.event.HoverEvent; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.MovingObjectPosition; + +import com.muxiu1997.sharewhereiam.localization.Lang; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import journeymap.client.model.Waypoint; + +@SideOnly(Side.CLIENT) +public class WaypointUtil { + + public static PlayerWaypoint waypointOfLocation() { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + Waypoint waypoint = Waypoint.of(player); + waypoint.setName(player.getDisplayName()); + waypoint.setColor(WHITE_RGB); + return new PlayerWaypoint(player, waypoint); + } + + public static PlayerWaypoint waypointOfRayTrace() { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + // Assuming rayTrace is a method to get the player's looking position + MovingObjectPosition position = player.rayTrace(128.0, 1.0f); + Waypoint waypoint = Waypoint.at( + position.blockX, + position.blockY, + position.blockZ, + Waypoint.Type.Normal, + player.worldObj.provider.dimensionId); + waypoint.setName(player.getDisplayName()); + waypoint.setColor(WHITE_RGB); + return new PlayerWaypoint(player, waypoint); + } + + public static class PlayerWaypoint { + + public final EntityPlayer player; + public final Waypoint waypoint; + + public PlayerWaypoint(EntityPlayer player, Waypoint waypoint) { + this.player = player; + this.waypoint = waypoint; + } + + // Getter methods for player and waypoint can be added if needed + } + + public static String toBase64(Waypoint waypoint) { + String waypointJSON = waypoint.toString(); + return Base64.getEncoder().encodeToString(waypointJSON.getBytes(StandardCharsets.UTF_8)); + } + + public static Waypoint fromBase64(String base64) { + String waypointJSON = new String(Base64.getDecoder().decode(base64), StandardCharsets.UTF_8); + return Waypoint.fromString(waypointJSON); + } + + public static void addShareWaypointChat(String playerName, Waypoint waypoint, String additionalInformation) { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + String waypointBase64 = toBase64(waypoint); + + IChatComponent chatPartA = new ChatComponentText("").appendSibling( + new ChatComponentText("[JourneyMap]").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW))) + .appendText(" ") + .appendSibling( + new ChatComponentText(playerName) + .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN))) + .appendText(" ").appendText(Lang.SHARE_WAYPOINT_MSG.translate()); + + IChatComponent chatPartB = new ChatComponentText("") + .appendSibling(new ChatComponentText(waypoint.getName()).setChatStyle(new ChatStyle().setBold(true))) + .appendText(" ") + .appendSibling( + new ChatComponentText( + String.format("(%d, %d, %d)", waypoint.getX(), waypoint.getY(), waypoint.getZ())) + .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GRAY))) + .appendText(" ") + // appendSaveAction + .appendSibling( + new ChatComponentText("[Save]").setChatStyle( + new ChatStyle().setBold(true).setColor(EnumChatFormatting.BLUE).setChatHoverEvent( + new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new ChatComponentText(Lang.SHARE_WAYPOINT_SAVE_DESC.translate()))) + .setChatClickEvent( + new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + "/savewaypoint " + waypointBase64 + " false")))) + // appendEditAction + .appendText(" ") + .appendSibling( + new ChatComponentText("[Edit]").setChatStyle( + new ChatStyle().setBold(true).setColor(EnumChatFormatting.BLUE).setChatHoverEvent( + new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new ChatComponentText(Lang.SHARE_WAYPOINT_EDIT_DESC.translate()))) + .setChatClickEvent( + new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + "/savewaypoint " + waypointBase64)))) + // appendToggleAction + .appendText(" ").appendSibling( + new ChatComponentText("[Toggle]").setChatStyle( + new ChatStyle().setBold(true).setColor(EnumChatFormatting.BLUE).setChatHoverEvent( + new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new ChatComponentText(Lang.SHARE_WAYPOINT_TOGGLE_DESC.translate()))) + .setChatClickEvent( + new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + "/toggletempbeacon " + waypointBase64)))); + + IChatComponent chatPartC = (additionalInformation != null && !additionalInformation.isEmpty()) + ? new ChatComponentText(additionalInformation) + .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GRAY)) + : null; + + player.addChatComponentMessage(chatPartA); + player.addChatComponentMessage(chatPartB); + + if (chatPartC != null) { + player.addChatComponentMessage(chatPartC); + } + } + + public static Waypoint waypointFromString(String s) { + return Waypoint.fromString(s); + } +} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/client/KeyBinding.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/client/KeyBinding.kt deleted file mode 100644 index 0bf096f..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/client/KeyBinding.kt +++ /dev/null @@ -1,12 +0,0 @@ -@file:JvmName("KeyBinding") - -package com.muxiu1997.sharewhereiam.client - -import com.muxiu1997.sharewhereiam.localization.Lang -import net.minecraft.client.settings.KeyBinding -import org.lwjgl.input.Keyboard - -@JvmField -val KeyShare = - KeyBinding( - Lang.KEYBINDING_SHARE_NAME.key, Keyboard.KEY_INSERT, Lang.KEYBINDING_SHARE_CATEGORY.key) diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandError.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandError.kt deleted file mode 100644 index fc078b0..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandError.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.muxiu1997.sharewhereiam.command - -import com.muxiu1997.sharewhereiam.localization.Lang -import net.minecraft.command.CommandException - -enum class CommandError(private val localizationKey: String) { - INVALID_WAYPOINT_CODE(Lang.ERROR_INVALID_WAYPOINT_CODE.key); - - fun exception(): CommandException { - return CommandException(localizationKey) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.kt deleted file mode 100644 index fe5ee72..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.muxiu1997.sharewhereiam.command - -import com.muxiu1997.sharewhereiam.command.base.CommandWaypointBase -import com.muxiu1997.sharewhereiam.localization.Lang -import com.muxiu1997.sharewhereiam.mixininterfaces.IMixinWaypointStore -import journeymap.client.ui.UIManager -import journeymap.client.waypoint.WaypointStore -import net.minecraft.command.CommandException -import net.minecraft.command.ICommandSender -import net.minecraft.util.ChatComponentText - -object CommandWaypointSave : CommandWaypointBase("savewaypoint") { - override val commandUsage = Lang.SAVE_WAYPOINT_USAGE.key - - @Throws(CommandException::class) - override fun processCommand(sender: ICommandSender, args: Array) { - ensureArgsLength(args, 1, 2) - val waypoint = parseWaypoint(args[0]) - val openWaypointEditor = parseOpenWaypointEditor(sender, args) - if (openWaypointEditor) { - UIManager.getInstance().openWaypointEditor(waypoint, true, null) - return - } - if ((WaypointStore.instance() as IMixinWaypointStore).exists(waypoint)) { - sender.addChatMessage(ChatComponentText(Lang.SAVE_WAYPOINT_EXISTS())) - return - } - WaypointStore.instance().add(waypoint) - sender.addChatMessage(ChatComponentText(Lang.SAVE_WAYPOINT_SUCCESS())) - } - - @Throws(CommandException::class) - private fun parseOpenWaypointEditor(sender: ICommandSender, args: Array): Boolean { - var openWaypointEditor = true - if (args.size == 2) { - openWaypointEditor = parseBoolean(sender, args[1]) - } - return openWaypointEditor - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.kt deleted file mode 100644 index 409f4e8..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.muxiu1997.sharewhereiam.command - -import com.muxiu1997.sharewhereiam.command.base.CommandWaypointBase -import com.muxiu1997.sharewhereiam.localization.Lang -import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint -import com.muxiu1997.sharewhereiam.network.network -import com.muxiu1997.sharewhereiam.util.WaypointUtil.waypointOfLocation -import net.minecraft.command.CommandException -import net.minecraft.command.ICommandSender -import net.minecraft.entity.player.EntityPlayer - -object CommandWaypointShareLocation : CommandWaypointBase("sharewhereiam") { - override val commandUsage = Lang.SHARE_WHERE_I_AM_USAGE.key - - @Throws(CommandException::class) - override fun processCommand(sender: ICommandSender, args: Array) { - ensureArgsLength(args, 0) - assert(sender is EntityPlayer) - network.sendToServer(MessageShareWaypoint(waypointOfLocation())) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.kt deleted file mode 100644 index b624c84..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.muxiu1997.sharewhereiam.command - -import com.muxiu1997.sharewhereiam.command.base.CommandWaypointBase -import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointManager -import com.muxiu1997.sharewhereiam.localization.Lang -import net.minecraft.command.CommandException -import net.minecraft.command.ICommandSender - -object CommandWaypointToggleTempBeacon : CommandWaypointBase("toggletempbeacon") { - override val commandUsage = Lang.TOGGLE_TEMP_BEACON_USAGE.key - - @Throws(CommandException::class) - override fun processCommand(sender: ICommandSender, args: Array) { - ensureArgsLength(args, 0, 1) - if (args.isEmpty()) { - WaypointManager.clearActiveTempBeacon() - return - } - val waypoint = parseWaypoint(args[0]) - WaypointManager.toggleActiveTempBeacon(waypoint) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.kt deleted file mode 100644 index 74f623a..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.muxiu1997.sharewhereiam.command.base - -import com.muxiu1997.sharewhereiam.command.CommandError -import com.muxiu1997.sharewhereiam.util.WaypointUtil.fromBase64 -import journeymap.client.model.Waypoint -import net.minecraft.client.entity.AbstractClientPlayer -import net.minecraft.command.CommandBase -import net.minecraft.command.CommandException -import net.minecraft.command.ICommandSender - -abstract class CommandWaypointBase(private val commandName: String) : CommandBase() { - abstract val commandUsage: String - private val commandException: CommandException - get() = CommandException(commandUsage) - - override fun getCommandName(): String { - return commandName - } - - override fun getCommandUsage(sender: ICommandSender): String { - return commandUsage - } - - override fun getRequiredPermissionLevel(): Int { - return 0 - } - - override fun canCommandSenderUseCommand(sender: ICommandSender): Boolean { - return if (sender !is AbstractClientPlayer) false else super.canCommandSenderUseCommand(sender) - } - - @Throws(CommandException::class) - protected fun parseWaypoint(waypointCode: String): Waypoint { - return try { - fromBase64(waypointCode) - } catch (ignored: Exception) { - throw CommandError.INVALID_WAYPOINT_CODE.exception() - } - } - - @Throws(CommandException::class) - protected fun ensureArgsLength(args: Array?, min: Int, max: Int) { - val argsLength = args?.size ?: 0 - if (argsLength < min || argsLength > max) throw commandException - } - - @Throws(CommandException::class) - protected fun ensureArgsLength(args: Array?, length: Int) { - val argsLength = args?.size ?: 0 - if (argsLength != length) throw commandException - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/event/EventHandler.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/event/EventHandler.kt deleted file mode 100644 index 720a1d7..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/event/EventHandler.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.muxiu1997.sharewhereiam.event - -import com.muxiu1997.sharewhereiam.client.KeyShare -import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointManager -import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointMarker -import com.muxiu1997.sharewhereiam.network.MessageMarkWaypoint -import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint -import com.muxiu1997.sharewhereiam.network.network -import com.muxiu1997.sharewhereiam.util.WaypointUtil.waypointOfLocation -import com.muxiu1997.sharewhereiam.util.WaypointUtil.waypointOfRayTrace -import cpw.mods.fml.common.eventhandler.SubscribeEvent -import cpw.mods.fml.common.gameevent.InputEvent -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly -import net.minecraft.entity.player.EntityPlayer -import net.minecraftforge.client.event.RenderWorldLastEvent -import net.minecraftforge.event.entity.EntityJoinWorldEvent -import org.lwjgl.input.Keyboard - -object EventHandler { - @SideOnly(Side.CLIENT) - @SubscribeEvent - fun handleEntityJoinWorld(event: EntityJoinWorldEvent) { - if (event.world.isRemote) { - if (event.entity is EntityPlayer) { - WaypointManager.clearActiveTempBeacon() - } - } - } - - @SideOnly(Side.CLIENT) - @SubscribeEvent - fun handleKeyInput(event: InputEvent.KeyInputEvent) { - if (KeyShare.isPressed.not()) return - - val playerWaypoint = - if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { - waypointOfLocation() - } else { - waypointOfRayTrace() - } - - if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { - network.sendToServer(MessageShareWaypoint(playerWaypoint)) - } else { - network.sendToServer(MessageMarkWaypoint(playerWaypoint)) - } - } - - @SideOnly(Side.CLIENT) - @SubscribeEvent - fun handleRenderWorldLast(event: RenderWorldLastEvent) { - WaypointMarker.render(event) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/Mods.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/Mods.kt deleted file mode 100644 index 094946e..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/Mods.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.muxiu1997.sharewhereiam.integration - -import cpw.mods.fml.common.Loader - -const val VISUAL_PROSPECTING_MODID = "visualprospecting" - -enum class Mods(val modid: String) { - VISUAL_PROSPECTING(VISUAL_PROSPECTING_MODID), - ; - - var isLoaded = false - private set - - fun check() { - isLoaded = Loader.isModLoaded(modid) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.kt deleted file mode 100644 index 8a90f72..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.muxiu1997.sharewhereiam.integration.journeymap - -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly -import journeymap.client.model.Waypoint -import net.minecraft.client.Minecraft - -@SideOnly(Side.CLIENT) -object WaypointManager { - var tempBeacon: Waypoint? = null - private set - - private val transientBeaconCache = mutableMapOf() - - fun hasActiveTempBeacon(): Boolean { - return tempBeacon != null - } - - fun clearActiveTempBeacon() { - tempBeacon = null - } - - fun toggleActiveTempBeacon(waypoint: Waypoint) { - if (waypoint == this.tempBeacon) { - this.tempBeacon = null - return - } - this.tempBeacon = waypoint - } - - fun addTransientBeacon(playerName: String, waypoint: Waypoint) { - transientBeaconCache[playerName] = TransientBeacon(waypoint, Minecraft.getSystemTime()) - } - - fun getTransientBeacons(): List { - transientBeaconCache - .filterValues { transientBeacon -> - Minecraft.getSystemTime() - transientBeacon.start > 3000 - } - .forEach { (playerName, _) -> transientBeaconCache.remove(playerName) } - return transientBeaconCache.values.map { it.waypoint } - } - - data class TransientBeacon(val waypoint: Waypoint, val start: Long) -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.kt deleted file mode 100644 index 7cfc554..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.kt +++ /dev/null @@ -1,86 +0,0 @@ -package com.muxiu1997.sharewhereiam.integration.journeymap - -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly -import journeymap.client.model.Waypoint -import net.minecraft.client.Minecraft -import net.minecraftforge.client.event.RenderWorldLastEvent -import org.lwjgl.opengl.GL11 - -@SideOnly(Side.CLIENT) -object WaypointMarker { - fun render(event: RenderWorldLastEvent) { - val transientBeacons = WaypointManager.getTransientBeacons() - if (transientBeacons.isEmpty()) return - - val partialTicks: Float = event.partialTicks - val player = Minecraft.getMinecraft().thePlayer - val posX: Double = player.prevPosX + (player.posX - player.prevPosX) * partialTicks - val posY: Double = player.prevPosY + (player.posY - player.prevPosY) * partialTicks - val posZ: Double = player.prevPosZ + (player.posZ - player.prevPosZ) * partialTicks - - GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) - GL11.glPushMatrix() - GL11.glTranslated(-posX, -posY, -posZ) - GL11.glDisable(GL11.GL_LIGHTING) - GL11.glDisable(GL11.GL_TEXTURE_2D) - GL11.glDisable(GL11.GL_DEPTH_TEST) - GL11.glEnable(GL11.GL_BLEND) - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA) - GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST) - - GL11.glBegin(GL11.GL_QUADS) - transientBeacons.forEach { markWaypoint(it) } - GL11.glEnd() - - GL11.glEnable(GL11.GL_LIGHTING) - GL11.glEnable(GL11.GL_DEPTH_TEST) - GL11.glDisable(GL11.GL_TEXTURE_2D) - GL11.glPopMatrix() - GL11.glPopAttrib() - } - - private fun markWaypoint(waypoint: Waypoint) { - val x = waypoint.x.toDouble() - val y = waypoint.y.toDouble() - val z = waypoint.z.toDouble() - - GL11.glColor4d(255.0, 255.0, 255.0, 0.8) - - // NORTH - GL11.glVertex3d(x, y + 1, z) - GL11.glVertex3d(x + 1, y + 1, z) - GL11.glVertex3d(x + 1, y, z) - GL11.glVertex3d(x, y, z) - - // EAST - GL11.glVertex3d(x + 1, y, z + 1) - GL11.glVertex3d(x + 1, y, z) - GL11.glVertex3d(x + 1, y + 1, z) - GL11.glVertex3d(x + 1, y + 1, z + 1) - - // SOUTH - GL11.glVertex3d(x + 1, y + 1, z + 1) - GL11.glVertex3d(x, y + 1, z + 1) - GL11.glVertex3d(x, y, z + 1) - GL11.glVertex3d(x + 1, y, z + 1) - - // WEST - GL11.glVertex3d(x, y + 1, z + 1) - GL11.glVertex3d(x, y + 1, z) - GL11.glVertex3d(x, y, z) - GL11.glVertex3d(x, y, z + 1) - - // TOP - GL11.glVertex3d(x, y + 1, z) - GL11.glVertex3d(x, y + 1, z + 1) - GL11.glVertex3d(x + 1, y + 1, z + 1) - GL11.glVertex3d(x + 1, y + 1, z) - - // BOTTOM - GL11.glVertex3d(x + 1, y, z) - GL11.glVertex3d(x + 1, y, z + 1) - GL11.glVertex3d(x, y, z + 1) - GL11.glVertex3d(x, y, z) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/CommandLoader.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/CommandLoader.kt deleted file mode 100644 index 9aa22fe..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/CommandLoader.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader - -import com.muxiu1997.sharewhereiam.command.CommandWaypointSave -import com.muxiu1997.sharewhereiam.command.CommandWaypointShareLocation -import com.muxiu1997.sharewhereiam.command.CommandWaypointToggleTempBeacon -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly -import net.minecraftforge.client.ClientCommandHandler - -object CommandLoader { - @SideOnly(Side.CLIENT) - fun clientLoad() { - ClientCommandHandler.instance.registerCommand(CommandWaypointSave) - ClientCommandHandler.instance.registerCommand(CommandWaypointShareLocation) - ClientCommandHandler.instance.registerCommand(CommandWaypointToggleTempBeacon) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/EventLoader.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/EventLoader.kt deleted file mode 100644 index 4067f04..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/EventLoader.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader - -import com.muxiu1997.sharewhereiam.event.EventHandler -import cpw.mods.fml.common.FMLCommonHandler -import net.minecraftforge.common.MinecraftForge - -object EventLoader { - fun load() { - MinecraftForge.EVENT_BUS.register(EventHandler) - FMLCommonHandler.instance().bus().register(EventHandler) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.kt deleted file mode 100644 index e42039b..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader - -import com.muxiu1997.sharewhereiam.integration.Mods -import java.util.Arrays - -object IntegrationLoader { - fun load() { - Arrays.stream(Mods.values()).forEach { obj: Mods -> obj.check() } - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/KeyLoader.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/KeyLoader.kt deleted file mode 100644 index d30b4e6..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/KeyLoader.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader - -import com.muxiu1997.sharewhereiam.client.KeyShare -import cpw.mods.fml.client.registry.ClientRegistry -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly - -@SideOnly(Side.CLIENT) -object KeyLoader { - fun clientLoad() { - ClientRegistry.registerKeyBinding(KeyShare) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/NetworkLoader.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/NetworkLoader.kt deleted file mode 100644 index 95a352c..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/loader/NetworkLoader.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader - -import com.muxiu1997.sharewhereiam.network.IClientSideHandler -import com.muxiu1997.sharewhereiam.network.IServerSideHandler -import com.muxiu1997.sharewhereiam.network.MessageMarkWaypoint -import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint -import com.muxiu1997.sharewhereiam.network.network -import cpw.mods.fml.common.network.simpleimpl.IMessage -import cpw.mods.fml.common.network.simpleimpl.IMessageHandler -import cpw.mods.fml.relauncher.Side - -object NetworkLoader { - fun load() { - register(MessageShareWaypoint.Companion.Handler) - register(MessageMarkWaypoint.Companion.Handler) - } - - private inline fun register( - messageHandler: IMessageHandler, - ) { - if (messageHandler is IClientSideHandler) - network.registerMessage(messageHandler, REQ::class.java, nextID++, Side.CLIENT) - if (messageHandler is IServerSideHandler) - network.registerMessage(messageHandler, REQ::class.java, nextID++, Side.SERVER) - } - - private var nextID = 0 -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Lang.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Lang.kt deleted file mode 100644 index 5c8e560..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/localization/Lang.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.muxiu1997.sharewhereiam.localization - -import net.minecraft.util.StatCollector - -object Lang { - @Localization( - prefix = PREFIX_COMMAND, - en = "Usage: /savewaypoint [neet to open editor? default: true]") - lateinit var SAVE_WAYPOINT_USAGE: LocalizedString - - @Localization(prefix = PREFIX_COMMAND, en = "Waypoint saved") - lateinit var SAVE_WAYPOINT_SUCCESS: LocalizedString - - @Localization(prefix = PREFIX_COMMAND, en = "Waypoint exists, can't save") - lateinit var SAVE_WAYPOINT_EXISTS: LocalizedString - - @Localization(prefix = PREFIX_COMMAND, en = "Usage: /sharewhereiam") - lateinit var SHARE_WHERE_I_AM_USAGE: LocalizedString - - @Localization(prefix = PREFIX_COMMAND, en = "Usage: /toggletempbeacon [waypoint code]") - lateinit var TOGGLE_TEMP_BEACON_USAGE: LocalizedString - - @Localization(prefix = PREFIX_COMMAND_ERROR, en = "Invalid waypoint code") - lateinit var ERROR_INVALID_WAYPOINT_CODE: LocalizedString - - @Localization(prefix = PREFIX_CHAT, en = "shared a waypoint:") - lateinit var SHARE_WAYPOINT_MSG: LocalizedString - - @Localization(prefix = PREFIX_CHAT, en = "SAVE") lateinit var SHARE_WAYPOINT_SAVE: LocalizedString - - @Localization(prefix = PREFIX_CHAT, en = "Save this waypoint to your JourneyMap") - lateinit var SHARE_WAYPOINT_SAVE_DESC: LocalizedString - - @Localization(prefix = PREFIX_CHAT, en = "EDIT") lateinit var SHARE_WAYPOINT_EDIT: LocalizedString - - @Localization(prefix = PREFIX_CHAT, en = "Open this Waypoint in Editor") - lateinit var SHARE_WAYPOINT_EDIT_DESC: LocalizedString - - @Localization(prefix = PREFIX_CHAT, en = "Enable/Disable") - lateinit var SHARE_WAYPOINT_TOGGLE: LocalizedString - - @Localization(prefix = PREFIX_CHAT, en = "Enable/Disable as Temporary Beacon") - lateinit var SHARE_WAYPOINT_TOGGLE_DESC: LocalizedString - - @Localization( - prefix = PREFIX_CHAT, - en = - "This is a VisualProspecting Waypoint, you still need to add the Waypoint to the VP in the way that the VP allows") - lateinit var SHARE_WAYPOINT_VP: LocalizedString - - @Localization(prefix = PREFIX_KEYBINDING, en = "Share") - lateinit var KEYBINDING_SHARE_NAME: LocalizedString - - @Localization(prefix = PREFIX_KEYBINDING, en = "Share Where I am") - lateinit var KEYBINDING_SHARE_CATEGORY: LocalizedString - - @Localization(prefix = PREFIX_TEXT, en = "Current Location") - lateinit var TEXT_DEFAULT_WAYPOINT_NAME: LocalizedString - - @Localization(prefix = PREFIX_TEXT, en = "Share") - lateinit var TEXT_JM_WAYPOINT_BUTTON: LocalizedString - - private const val PREFIX_COMMAND = "sharewhereiam.command" - private const val PREFIX_COMMAND_ERROR = "sharewhereiam.commanderror" - private const val PREFIX_CHAT = "sharewhereiam.chat" - private const val PREFIX_KEYBINDING = "sharewhereiam.keybinding" - private const val PREFIX_TEXT = "sharewhereiam.text" - - data class LocalizedString(val key: String) { - operator fun invoke(): String = StatCollector.translateToLocal(key) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.kt deleted file mode 100644 index 24affef..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.muxiu1997.sharewhereiam.network - -import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointManager -import com.muxiu1997.sharewhereiam.util.WaypointUtil -import cpw.mods.fml.common.network.ByteBufUtils -import cpw.mods.fml.common.network.simpleimpl.IMessage -import cpw.mods.fml.common.network.simpleimpl.IMessageHandler -import cpw.mods.fml.common.network.simpleimpl.MessageContext -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly -import io.netty.buffer.ByteBuf -import journeymap.client.model.Waypoint - -class MessageMarkWaypoint : IMessage { - lateinit var playerName: String - lateinit var waypointJson: String - - @Suppress("unused") constructor() - - @SideOnly(Side.CLIENT) - constructor(playerWaypoint: WaypointUtil.PlayerWaypoint) { - this.playerName = playerWaypoint.player.displayName - this.waypointJson = playerWaypoint.waypoint.toString() - } - - override fun fromBytes(buf: ByteBuf) { - playerName = ByteBufUtils.readUTF8String(buf) - waypointJson = ByteBufUtils.readUTF8String(buf) - } - - override fun toBytes(buf: ByteBuf) { - ByteBufUtils.writeUTF8String(buf, playerName) - ByteBufUtils.writeUTF8String(buf, waypointJson) - } - - companion object { - object Handler : - IMessageHandler, IClientSideHandler, IServerSideHandler { - override fun onMessage(message: MessageMarkWaypoint, ctx: MessageContext): IMessage? { - when (ctx.side) { - Side.CLIENT -> handleClientSideMessage(message) - Side.SERVER -> handleServerSideMessage(message) - else -> {} - } - return null - } - - @SideOnly(Side.CLIENT) - private fun handleClientSideMessage(message: MessageMarkWaypoint) { - WaypointManager.addTransientBeacon( - message.playerName, Waypoint.fromString(message.waypointJson)) - } - - private fun handleServerSideMessage(message: MessageMarkWaypoint) { - network.sendToAll(message) - } - } - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.kt deleted file mode 100644 index 9d705a4..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.kt +++ /dev/null @@ -1,70 +0,0 @@ -package com.muxiu1997.sharewhereiam.network - -import com.muxiu1997.sharewhereiam.util.WaypointUtil -import cpw.mods.fml.common.network.ByteBufUtils -import cpw.mods.fml.common.network.simpleimpl.IMessage -import cpw.mods.fml.common.network.simpleimpl.IMessageHandler -import cpw.mods.fml.common.network.simpleimpl.MessageContext -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly -import io.netty.buffer.ByteBuf - -class MessageShareWaypoint : IMessage { - lateinit var playerName: String - lateinit var waypointJson: String - lateinit var additionalInformation: String - - @Suppress("unused") constructor() - - @SideOnly(Side.CLIENT) - constructor(playerWaypoint: WaypointUtil.PlayerWaypoint) : this(playerWaypoint, "") - - @SideOnly(Side.CLIENT) - constructor(playerWaypoint: WaypointUtil.PlayerWaypoint, additionalInformation: String) { - this.playerName = playerWaypoint.player.displayName - this.waypointJson = playerWaypoint.waypoint.toString() - this.additionalInformation = additionalInformation - } - - override fun fromBytes(buf: ByteBuf) { - playerName = ByteBufUtils.readUTF8String(buf) - waypointJson = ByteBufUtils.readUTF8String(buf) - additionalInformation = ByteBufUtils.readUTF8String(buf) - } - - override fun toBytes(buf: ByteBuf) { - ByteBufUtils.writeUTF8String(buf, playerName) - ByteBufUtils.writeUTF8String(buf, waypointJson) - ByteBufUtils.writeUTF8String(buf, additionalInformation) - } - - companion object { - object Handler : - IMessageHandler, IClientSideHandler, IServerSideHandler { - override fun onMessage(message: MessageShareWaypoint, ctx: MessageContext): IMessage? { - if (ctx.side.isClient) { - handleClientSideMessage(message) - } else { - handleServerSideMessage(message) - } - return null - } - - @SideOnly(Side.CLIENT) - private fun handleClientSideMessage(message: MessageShareWaypoint) { - if (WaypointUtil.isJourneyMapLoaded) - WaypointUtil.addShareWaypointChat( - message.playerName, - WaypointUtil.waypointFromString( - message - .waypointJson), // Dereferences JourneyMap class import to stop crashes on - // clients that don't have JourneyMap installed. - message.additionalInformation) - } - - private fun handleServerSideMessage(message: MessageShareWaypoint) { - network.sendToAll(message) - } - } - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/network/NetworkHandler.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/network/NetworkHandler.kt deleted file mode 100644 index 23c2d63..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/network/NetworkHandler.kt +++ /dev/null @@ -1,13 +0,0 @@ -@file:JvmName("NetworkHandler") - -package com.muxiu1997.sharewhereiam.network - -import cpw.mods.fml.common.network.NetworkRegistry -import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper - -@JvmField -val network: SimpleNetworkWrapper = NetworkRegistry.INSTANCE.newSimpleChannel("sharewhereiam") - -interface IServerSideHandler - -interface IClientSideHandler diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/ClientProxy.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/ClientProxy.kt deleted file mode 100644 index 2bfdb0c..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/ClientProxy.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.muxiu1997.sharewhereiam.proxy - -import com.muxiu1997.sharewhereiam.loader.CommandLoader -import com.muxiu1997.sharewhereiam.loader.KeyLoader -import cpw.mods.fml.common.event.FMLPostInitializationEvent - -class ClientProxy : CommonProxy() { - override fun postInit(event: FMLPostInitializationEvent) { - super.postInit(event) - CommandLoader.clientLoad() - KeyLoader.clientLoad() - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/CommonProxy.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/CommonProxy.kt deleted file mode 100644 index 8138042..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/proxy/CommonProxy.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.muxiu1997.sharewhereiam.proxy - -import com.muxiu1997.sharewhereiam.loader.EventLoader -import com.muxiu1997.sharewhereiam.loader.IntegrationLoader -import com.muxiu1997.sharewhereiam.loader.LocalizationLoader -import com.muxiu1997.sharewhereiam.loader.NetworkLoader -import cpw.mods.fml.common.event.FMLPostInitializationEvent -import cpw.mods.fml.common.event.FMLPreInitializationEvent - -open class CommonProxy { - open fun preInit(event: FMLPreInitializationEvent) { - LocalizationLoader.load() - } - - open fun postInit(event: FMLPostInitializationEvent) { - IntegrationLoader.load() - EventLoader.load() - NetworkLoader.load() - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.kt deleted file mode 100644 index 1b460c1..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.muxiu1997.sharewhereiam.util - -import com.muxiu1997.sharewhereiam.integration.VISUAL_PROSPECTING_MODID -import com.sinthoras.visualprospecting.integration.journeymap.JourneyMapState -import com.sinthoras.visualprospecting.integration.journeymap.drawsteps.ClickableDrawStep -import com.sinthoras.visualprospecting.integration.journeymap.render.WaypointProviderLayerRenderer -import cpw.mods.fml.common.Optional -import cpw.mods.fml.relauncher.ReflectionHelper -import java.awt.Color -import journeymap.client.model.Waypoint - -object VPWaypointUtil { - @JvmStatic - @Optional.Method(modid = VISUAL_PROSPECTING_MODID) - fun getHoveredWaypoint(): Waypoint? { - val fieldHoveredDrawStep = - ReflectionHelper.findField( - WaypointProviderLayerRenderer::class.java, - "hoveredDrawStep", - ) - for (layer in JourneyMapState.instance.renderers) { - if (layer !is WaypointProviderLayerRenderer) continue - val hoveredDrawStep = - try { - fieldHoveredDrawStep[layer] as ClickableDrawStep - } catch (ignored: Exception) { - continue - } - val waypoint = hoveredDrawStep.locationProvider?.toWaypoint() ?: continue - return waypoint.getJMWaypoint() - } - return null - } - - @Optional.Method(modid = VISUAL_PROSPECTING_MODID) - private fun com.sinthoras.visualprospecting.integration.model.waypoints.Waypoint.getJMWaypoint(): - Waypoint { - return Waypoint( - this.label, - this.blockX, - this.blockY, - this.blockZ, - Color(this.color), - Waypoint.Type.Normal, - this.dimensionId) - } -} diff --git a/src/main/kotlin/com/muxiu1997/sharewhereiam/util/WaypointUtil.kt b/src/main/kotlin/com/muxiu1997/sharewhereiam/util/WaypointUtil.kt deleted file mode 100644 index 27f5be4..0000000 --- a/src/main/kotlin/com/muxiu1997/sharewhereiam/util/WaypointUtil.kt +++ /dev/null @@ -1,163 +0,0 @@ -package com.muxiu1997.sharewhereiam.util - -import com.muxiu1997.sharewhereiam.localization.Lang -import cpw.mods.fml.common.Loader -import cpw.mods.fml.relauncher.Side -import cpw.mods.fml.relauncher.SideOnly -import java.nio.charset.StandardCharsets -import java.util.Base64 -import journeymap.client.cartography.RGB.WHITE_RGB -import journeymap.client.model.Waypoint -import net.minecraft.client.Minecraft -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.event.ClickEvent -import net.minecraft.event.HoverEvent -import net.minecraft.util.ChatComponentText -import net.minecraft.util.ChatStyle -import net.minecraft.util.EnumChatFormatting -import net.minecraft.util.IChatComponent - -@SideOnly(Side.CLIENT) -object WaypointUtil { - fun waypointOfLocation(): PlayerWaypoint { - val player = Minecraft.getMinecraft().thePlayer - val waypoint = - Waypoint.of(player).apply { - name = player.displayName - color = WHITE_RGB - } - return PlayerWaypoint(player, waypoint) - } - - fun waypointOfRayTrace(): PlayerWaypoint { - val player = Minecraft.getMinecraft().thePlayer - val position = player.rayTrace(128.0, 1.0f) - val waypoint = - Waypoint.at( - position.blockX, - position.blockY, - position.blockZ, - Waypoint.Type.Normal, - player.worldObj.provider.dimensionId) - .apply { - name = player.displayName - color = WHITE_RGB - } - return PlayerWaypoint(player, waypoint) - } - - data class PlayerWaypoint(val player: EntityPlayer, val waypoint: Waypoint) - - fun toBase64(waypoint: Waypoint): String { - val waypointJSON = waypoint.toString() - return Base64.getEncoder().encodeToString(waypointJSON.toByteArray(StandardCharsets.UTF_8)) - } - - fun fromBase64(base64: String?): Waypoint { - val waypointJSON = String(Base64.getDecoder().decode(base64), StandardCharsets.UTF_8) - return Waypoint.fromString(waypointJSON) - } - - fun addShareWaypointChat(playerName: String, waypoint: Waypoint, additionalInformation: String?) { - val player = Minecraft.getMinecraft().thePlayer - val waypointBase64 = toBase64(waypoint) - val chatPartA = - ChatComponentText("") - .appendSibling( - ChatComponentText("[JourneyMap]") - .setChatStyle(ChatStyle().setColor(EnumChatFormatting.YELLOW))) - .appendText(" ") - .appendSibling( - ChatComponentText(playerName) - .setChatStyle(ChatStyle().setColor(EnumChatFormatting.GREEN))) - .appendText(" ") - .appendText(Lang.SHARE_WAYPOINT_MSG()) - - val chatPartB = - ChatComponentText("") - .appendSibling(ChatComponentText(waypoint.name).setChatStyle(ChatStyle().setBold(true))) - .appendText(" ") - .appendSibling( - ChatComponentText(String.format("(%d, %d, %d)", waypoint.x, waypoint.y, waypoint.z)) - .setChatStyle(ChatStyle().setColor(EnumChatFormatting.GRAY))) - .appendSaveAction(waypointBase64) - .appendEditAction(waypointBase64) - .appendToggleAction(waypointBase64) - - val chatPartC = - additionalInformation?.let { - if (it.isEmpty()) { - null - } else { - ChatComponentText(it).setChatStyle(ChatStyle().setColor(EnumChatFormatting.GRAY)) - } - } - - player.addChatComponentMessage(chatPartA) - player.addChatComponentMessage(chatPartB) - chatPartC ?: return - player.addChatComponentMessage(chatPartC) - } - - private fun IChatComponent.appendSaveAction(waypointBase64: String): IChatComponent { - return this.appendText(" ") - .appendSibling( - ChatComponentText("[${Lang.SHARE_WAYPOINT_SAVE()}]") - .setChatStyle( - ChatStyle() - .setBold(true) - .setColor(EnumChatFormatting.BLUE) - .setChatHoverEvent( - HoverEvent( - HoverEvent.Action.SHOW_TEXT, - ChatComponentText(Lang.SHARE_WAYPOINT_SAVE_DESC()))) - .setChatClickEvent( - ClickEvent( - ClickEvent.Action.RUN_COMMAND, - "/savewaypoint ${waypointBase64} false")))) - } - - private fun IChatComponent.appendEditAction(waypointBase64: String): IChatComponent { - return this.appendText(" ") - .appendSibling( - ChatComponentText("[${Lang.SHARE_WAYPOINT_EDIT()}]") - .setChatStyle( - ChatStyle() - .setBold(true) - .setColor(EnumChatFormatting.BLUE) - .setChatHoverEvent( - HoverEvent( - HoverEvent.Action.SHOW_TEXT, - ChatComponentText(Lang.SHARE_WAYPOINT_EDIT_DESC()))) - .setChatClickEvent( - ClickEvent( - ClickEvent.Action.RUN_COMMAND, "/savewaypoint $waypointBase64")))) - } - - private fun IChatComponent.appendToggleAction(waypointBase64: String): IChatComponent { - return this.appendText(" ") - .appendSibling( - ChatComponentText("[${Lang.SHARE_WAYPOINT_TOGGLE()}]") - .setChatStyle( - ChatStyle() - .setBold(true) - .setColor(EnumChatFormatting.BLUE) - .setChatHoverEvent( - HoverEvent( - HoverEvent.Action.SHOW_TEXT, - ChatComponentText(Lang.SHARE_WAYPOINT_TOGGLE_DESC()))) - .setChatClickEvent( - ClickEvent( - ClickEvent.Action.RUN_COMMAND, - "/toggletempbeacon $waypointBase64")))) - } - /** - * Dereferences JourneyMap class to avoid crashes on clients that don't have JourneyMap installed. - */ - fun waypointFromString(s: String): Waypoint { - return Waypoint.fromString(s) - } - - // Caches isModLoaded result to remove overhead from repeated calls. - val isJourneyMapLoaded: Boolean = Loader.isModLoaded("journeymap") -} diff --git a/src/main/resources/assets/sharewhereiam/lang/en_US.lang b/src/main/resources/assets/sharewhereiam/lang/en_US.lang new file mode 100644 index 0000000..e5c0c5e --- /dev/null +++ b/src/main/resources/assets/sharewhereiam/lang/en_US.lang @@ -0,0 +1,22 @@ +sharewhereiam.command.usage=Usage: /savewaypoint [neet to open editor? default: true] +sharewhereiam.command.save.success=Waypoint saved +sharewhereiam.command.save.exists=Waypoint exists, can't save +sharewhereiam.command.sharewhereiam.usage=Usage: /sharewhereiam +sharewhereiam.command.toggletempbeacon.usage=Usage: /toggletempbeacon [waypoint code] + +sharewhereiam.commanderror.invalidcode=Invalid waypoint code + +sharewhereiam.chat.share=shared a waypoint: +sharewhereiam.chat.save=SAVE +sharewhereiam.chat.save.desc=Save this waypoint to your JourneyMap +sharewhereiam.chat.edit=EDIT +sharewhereiam.chat.edit.desc=Open this Waypoint in Editor +sharewhereiam.chat.toggle=Enable/Disable +sharewhereiam.chat.toggle.desc=Enable/Disable as Temporary Beacon +sharewhereiam.chat.additionalInformation.VP=This is a VisualProspecting Waypoint, you still need to add the Waypoint to the VP in the way that the VP allows + +sharewhereiam.keybinding.share.name=Share +sharewhereiam.keybinding.share.category=Share Where I am + +sharewhereiam.text.default_waypoint_name=Current Location +sharewhereiam.text.jm.waypoint.share=Share From b8806c12234820cc138781c7667ae9f68be57434 Mon Sep 17 00:00:00 2001 From: Abdulaziz Date: Thu, 12 Dec 2024 08:10:38 +0300 Subject: [PATCH 2/6] Spotless --- .../sharewhereiam/mixins/Mixins.java | 8 +---- .../sharewhereiam/mixins/TargetedMod.java | 3 +- .../sharewhereiam/util/VPWaypointUtil.java | 30 +++++++------------ 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java index cce5edb..3fd5e68 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java @@ -19,13 +19,7 @@ public enum Mixins { "journeymap.MixinFullscreen", "journeymap.MixinRenderWaypointBeacon", "journeymap.MixinWaypointManagerItem", - "journeymap.MixinWaypointStore")), - NAVIGATOR_(new Builder("Navigator integration").addTargetedMod(TargetedMod.NAVIGATOR).setSide(Side.CLIENT) - .setPhase(Phase.LATE).addMixinClasses( - "navigator.HoveredDrawStepAccessor", - "navigator.HoveredRenderStepAccessor" - )); - + "journeymap.MixinWaypointStore")); private final List mixinClasses; private final Supplier applyIf; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java index 88ff401..1ebb9ca 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java @@ -5,8 +5,7 @@ public enum TargetedMod { VANILLA("Minecraft", null), JOURNEYMAP("JourneyMap", null, "journeymap"), XAEROMINIMAP("Xaero's Minimap", "xaero.common.core.XaeroMinimapPlugin", "XaeroMinimap"), - XAEROWORLDMAP("Xaero's World Map", "xaero.map.core.XaeroWorldMapPlugin", "XaeroWorldMap"), - NAVIGATOR("Navigator","com.gtnewhorizons.navigator.core","navigator"); + XAEROWORLDMAP("Xaero's World Map", "xaero.map.core.XaeroWorldMapPlugin", "XaeroWorldMap"); /** The "name" in the @Mod annotation */ public final String modName; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java b/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java index f75ff50..1467fa0 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java @@ -7,24 +7,15 @@ import javax.annotation.Nullable; import com.gtnewhorizons.navigator.api.NavigatorApi; -import com.gtnewhorizons.navigator.api.journeymap.drawsteps.JMInteractableStep; -import com.gtnewhorizons.navigator.api.journeymap.render.JMInteractableLayerRenderer; import com.gtnewhorizons.navigator.api.model.SupportedMods; -import com.gtnewhorizons.navigator.api.model.layers.InteractableLayerManager; -import com.gtnewhorizons.navigator.api.model.layers.LayerManager; - import com.gtnewhorizons.navigator.api.model.layers.LayerRenderer; import com.gtnewhorizons.navigator.api.model.layers.UniversalInteractableRenderer; -import com.gtnewhorizons.navigator.api.model.steps.RenderStep; import com.gtnewhorizons.navigator.api.model.steps.UniversalInteractableStep; import com.gtnewhorizons.navigator.api.model.waypoints.Waypoint; -import com.sinthoras.visualprospecting.integration.model.layers.OreVeinLayerManager; -import com.sinthoras.visualprospecting.integration.model.locations.OreVeinLocation; import cpw.mods.fml.common.Optional; import cpw.mods.fml.relauncher.ReflectionHelper; - public class VPWaypointUtil { @Nullable @@ -32,8 +23,10 @@ public class VPWaypointUtil { public static journeymap.client.model.Waypoint getHoveredWaypoint() { for (LayerRenderer layer : NavigatorApi.getActiveRenderersFor(SupportedMods.JourneyMap)) { if (layer instanceof UniversalInteractableRenderer) { - final Field FieldHoveredDrawStep = ReflectionHelper.findField(UniversalInteractableRenderer.class, "hoveredRenderStep"); - @Nullable UniversalInteractableStep hoveredRenderStep = null; + final Field FieldHoveredDrawStep = ReflectionHelper + .findField(UniversalInteractableRenderer.class, "hoveredRenderStep"); + @Nullable + UniversalInteractableStep hoveredRenderStep = null; try { hoveredRenderStep = (UniversalInteractableStep) FieldHoveredDrawStep.get(layer); } catch (Exception ignored) {} @@ -52,13 +45,12 @@ public static journeymap.client.model.Waypoint getHoveredWaypoint() { @Optional.Method(modid = "navigator") public static journeymap.client.model.Waypoint getJMWaypoint(@Nonnull Waypoint waypoint) { return new journeymap.client.model.Waypoint( - waypoint.label, - waypoint.blockX, - waypoint.blockY, - waypoint.blockZ, - new Color(waypoint.color), - journeymap.client.model.Waypoint.Type.Normal, - waypoint.dimensionId); + waypoint.label, + waypoint.blockX, + waypoint.blockY, + waypoint.blockZ, + new Color(waypoint.color), + journeymap.client.model.Waypoint.Type.Normal, + waypoint.dimensionId); } } - From 6e24c0fa1792d52d580761af2fc2b19280a4046f Mon Sep 17 00:00:00 2001 From: Abdulaziz Date: Thu, 12 Dec 2024 08:20:54 +0300 Subject: [PATCH 3/6] Cleanup --- gradle.properties | 2 +- .../muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java | 3 --- .../muxiu1997/sharewhereiam/network/MessageShareWaypoint.java | 4 ++-- .../java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java | 3 --- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/gradle.properties b/gradle.properties index a7a6cce..1bc4815 100644 --- a/gradle.properties +++ b/gradle.properties @@ -91,7 +91,7 @@ usesMixins = true separateMixinSourceSet = # Adds some debug arguments like verbose output and class export. -usesMixinDebug = true +usesMixinDebug = false # Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise. mixinPlugin = diff --git a/src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java index 5a4e1c2..b3cbe33 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageMarkWaypoint.java @@ -53,9 +53,6 @@ public IMessage onMessage(MessageMarkWaypoint message, MessageContext ctx) { case SERVER: handleServerSideMessage(message); break; - default: - // No action for other sides - break; } return null; } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java index e4e28c8..08520e4 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/network/MessageShareWaypoint.java @@ -68,8 +68,8 @@ private static void handleClientSideMessage(MessageShareWaypoint message) { WaypointUtil.addShareWaypointChat( message.playerName, WaypointUtil.waypointFromString(message.waypointJson), // Dereferences JourneyMap class import - // to stop crashes on - // clients that don't have JourneyMap installed. + // to stop crashes on clients that don't + // have JourneyMap installed. message.additionalInformation); } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java b/src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java index 3a6094c..77cc19a 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/util/WaypointUtil.java @@ -34,7 +34,6 @@ public static PlayerWaypoint waypointOfLocation() { public static PlayerWaypoint waypointOfRayTrace() { EntityPlayer player = Minecraft.getMinecraft().thePlayer; - // Assuming rayTrace is a method to get the player's looking position MovingObjectPosition position = player.rayTrace(128.0, 1.0f); Waypoint waypoint = Waypoint.at( position.blockX, @@ -56,8 +55,6 @@ public PlayerWaypoint(EntityPlayer player, Waypoint waypoint) { this.player = player; this.waypoint = waypoint; } - - // Getter methods for player and waypoint can be added if needed } public static String toBase64(Waypoint waypoint) { From f61b01ff842d50f48e65b1775f7e5cd7361e80b6 Mon Sep 17 00:00:00 2001 From: Abdulaziz Date: Thu, 12 Dec 2024 08:24:54 +0300 Subject: [PATCH 4/6] Fix Requirement --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d74afe..a649b99 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ `Share Where I am` is a mod for Minecraft 1.7.10 + JourneyMap. It allows you to share your waypoint/location with other players. -🚨 Requires SpongeMixins as a dependency 🚨 +🚨 Requires UniMixins as a dependency 🚨 From cd522b2c457c5c202e5140dfd422fbdbfabb9a30 Mon Sep 17 00:00:00 2001 From: Abdulaziz Date: Fri, 13 Dec 2024 00:20:25 +0300 Subject: [PATCH 5/6] Update --- .gitignore | 8 +++++++- src/main/resources/mixins.sharewhereiam.early.json | 8 ++++++++ src/main/resources/mixins.sharewhereiam.json | 8 ++++++++ src/main/resources/mixins.sharewhereiam.late.json | 8 ++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/mixins.sharewhereiam.early.json create mode 100644 src/main/resources/mixins.sharewhereiam.json create mode 100644 src/main/resources/mixins.sharewhereiam.late.json diff --git a/.gitignore b/.gitignore index 48c525b..5e80e0a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,13 @@ whitelist.json *.iml *.ipr *.iws -src/main/resources/mixins.*.json +src/main/resources/mixins.*([!.]).json *.bat *.DS_Store !gradlew.bat +.factorypath +addon.local.gradle +addon.local.gradle.kts +addon.late.local.gradle +addon.late.local.gradle.kts +layout.json diff --git a/src/main/resources/mixins.sharewhereiam.early.json b/src/main/resources/mixins.sharewhereiam.early.json new file mode 100644 index 0000000..82fffc7 --- /dev/null +++ b/src/main/resources/mixins.sharewhereiam.early.json @@ -0,0 +1,8 @@ +{ + "required": true, + "minVersion": "0.8.5-GTNH", + "package": "com.muxiu1997.sharewhereiam.mixins.early", + "refmap": "mixins.sharewhereiam.refmap.json", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8" +} diff --git a/src/main/resources/mixins.sharewhereiam.json b/src/main/resources/mixins.sharewhereiam.json new file mode 100644 index 0000000..b584b43 --- /dev/null +++ b/src/main/resources/mixins.sharewhereiam.json @@ -0,0 +1,8 @@ +{ + "required": true, + "minVersion": "0.8.5-GTNH", + "package": "com.muxiu1997.sharewhereiam.mixins", + "refmap": "mixins.sharewhereiam.refmap.json", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8" +} diff --git a/src/main/resources/mixins.sharewhereiam.late.json b/src/main/resources/mixins.sharewhereiam.late.json new file mode 100644 index 0000000..3aa73be --- /dev/null +++ b/src/main/resources/mixins.sharewhereiam.late.json @@ -0,0 +1,8 @@ +{ + "required": true, + "minVersion": "0.8.5-GTNH", + "package": "com.muxiu1997.sharewhereiam.mixins.late", + "refmap": "mixins.sharewhereiam.refmap.json", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8" +} From ad65f239b0ef47b9125775b96a3f209c14a69226 Mon Sep 17 00:00:00 2001 From: Abdulaziz Date: Sun, 29 Dec 2024 17:27:18 +0300 Subject: [PATCH 6/6] Addressing reviewer comments --- dependencies.gradle | 8 ++-- gradle.properties | 2 +- .../sharewhereiam/client/key/KeyBindings.java | 30 ++++++++++++ .../sharewhereiam/client/key/KeyShare.java | 15 ------ .../command/CommandWaypointSave.java | 4 +- .../command/CommandWaypointShareLocation.java | 7 ++- .../CommandWaypointToggleTempBeacon.java | 2 - .../command/base/CommandWaypointBase.java | 11 +++-- .../sharewhereiam/core/ShareWhereIAmCore.java | 46 ------------------- .../sharewhereiam/event/EventHandler.java | 6 +-- .../sharewhereiam/integration/Mods.java | 9 ++-- .../journeymap/WaypointManager.java | 6 +-- .../journeymap/WaypointMarker.java | 2 +- .../sharewhereiam/loader/CommandLoader.java | 22 --------- .../sharewhereiam/loader/EventLoader.java | 17 ------- .../loader/IntegrationLoader.java | 6 +-- .../sharewhereiam/loader/KeyLoader.java | 17 ------- .../sharewhereiam/loader/NetworkLoader.java | 2 - .../sharewhereiam/localization/Lang.java | 11 ++--- .../{mixins => mixinplugin}/Mixins.java | 9 ++-- .../ShareWhereIAmLateMixin.java | 3 +- .../{mixins => mixinplugin}/TargetedMod.java | 3 +- .../interfaces}/IMixinWaypointStore.java | 2 +- .../late/journeymap/MixinFullscreen.java | 4 +- .../journeymap/MixinRenderWaypointBeacon.java | 6 +-- .../late/journeymap/MixinWaypointStore.java | 2 +- ...UniversalInteractableRendererAccessor.java | 15 ++++++ .../sharewhereiam/proxy/ClientProxy.java | 20 ++++++-- .../sharewhereiam/proxy/CommonProxy.java | 15 ++++-- .../sharewhereiam/util/VPWaypointUtil.java | 12 ++--- .../assets/sharewhereiam/lang/en_US.lang | 6 +-- .../resources/mixins.sharewhereiam.early.json | 8 ---- 32 files changed, 124 insertions(+), 204 deletions(-) create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyBindings.java delete mode 100644 src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java delete mode 100644 src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java delete mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java delete mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java delete mode 100644 src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java rename src/main/java/com/muxiu1997/sharewhereiam/{mixins => mixinplugin}/Mixins.java (93%) rename src/main/java/com/muxiu1997/sharewhereiam/{ => mixinplugin}/ShareWhereIAmLateMixin.java (84%) rename src/main/java/com/muxiu1997/sharewhereiam/{mixins => mixinplugin}/TargetedMod.java (91%) rename src/main/java/com/muxiu1997/sharewhereiam/{mixininterfaces => mixinplugin/interfaces}/IMixinWaypointStore.java (67%) create mode 100644 src/main/java/com/muxiu1997/sharewhereiam/mixins/late/navigator/UniversalInteractableRendererAccessor.java delete mode 100644 src/main/resources/mixins.sharewhereiam.early.json diff --git a/dependencies.gradle b/dependencies.gradle index b58ba7b..7d5cddd 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -2,12 +2,12 @@ dependencies { - compileOnly('com.github.GTNewHorizons:NotEnoughItems:2.6.51-GTNH:dev') { transitive = false } - compileOnly('curse.maven:journeymap-32274:5769353') { transitive = false } + compileOnly('com.github.GTNewHorizons:NotEnoughItems:2.7.0-GTNH:dev') { transitive = false } compileOnly('com.github.GTNewHorizons:VisualProspecting:1.3.28:dev') { transitive = false } compileOnly('com.github.GTNewHorizons:Navigator:1.0.15:dev') { transitive = false } - compileOnly(deobfCurse('xaeros-minimap-263420:5637000')) - compileOnly(deobfCurse('xaeros-world-map-317780:5658209')) + compileOnly('curse.maven:journeymap-32274:5769353') + compileOnly('curse.maven:xaeros-minimap-263420:5637000') + compileOnly('curse.maven:xaeros-world-map-317780:5658209') } diff --git a/gradle.properties b/gradle.properties index 1bc4815..e23c230 100644 --- a/gradle.properties +++ b/gradle.properties @@ -102,7 +102,7 @@ mixinsPackage = mixins # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! # This parameter is for legacy compatibility only # Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin -coreModClass = core.ShareWhereIAmCore +coreModClass = # If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class # that is annotated with @Mod) you want this to be true. When in doubt: leave it on false! diff --git a/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyBindings.java b/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyBindings.java new file mode 100644 index 0000000..72974c8 --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyBindings.java @@ -0,0 +1,30 @@ +package com.muxiu1997.sharewhereiam.client.key; + +import net.minecraft.client.settings.KeyBinding; + +import org.lwjgl.input.Keyboard; + +import com.muxiu1997.sharewhereiam.localization.Lang; + +import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public final class KeyBindings { + + public static final KeyBinding WaypointShare; + + static { + WaypointShare = new KeyBinding( + Lang.KEYBINDING_SHARE_NAME.getKey(), + Keyboard.KEY_INSERT, + Lang.KEYBINDING_SHARE_CATEGORY.getKey()); + } + + private KeyBindings() {} + + public static void init() { + ClientRegistry.registerKeyBinding(WaypointShare); + } +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java b/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java deleted file mode 100644 index 6f4fa43..0000000 --- a/src/main/java/com/muxiu1997/sharewhereiam/client/key/KeyShare.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.muxiu1997.sharewhereiam.client.key; - -import net.minecraft.client.settings.KeyBinding; - -import org.lwjgl.input.Keyboard; - -import com.muxiu1997.sharewhereiam.localization.Lang; - -public class KeyShare { - - public static final KeyBinding INSTANCE = new KeyBinding( - Lang.KEYBINDING_SHARE_NAME.getKey(), - Keyboard.KEY_INSERT, - Lang.KEYBINDING_SHARE_CATEGORY.getKey()); -} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java index b5584af..166b87e 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointSave.java @@ -7,7 +7,7 @@ import com.muxiu1997.sharewhereiam.command.base.CommandWaypointBase; import com.muxiu1997.sharewhereiam.localization.Lang; -import com.muxiu1997.sharewhereiam.mixininterfaces.IMixinWaypointStore; +import com.muxiu1997.sharewhereiam.mixinplugin.interfaces.IMixinWaypointStore; import journeymap.client.model.Waypoint; import journeymap.client.ui.UIManager; @@ -15,8 +15,6 @@ public class CommandWaypointSave extends CommandWaypointBase { - public static CommandWaypointSave INSTANCE = new CommandWaypointSave(); - public CommandWaypointSave() { super("savewaypoint"); } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java index 37c59b3..f9842a9 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointShareLocation.java @@ -13,8 +13,6 @@ public class CommandWaypointShareLocation extends CommandWaypointBase { - public static CommandWaypointShareLocation INSTANCE = new CommandWaypointShareLocation(); - public CommandWaypointShareLocation() { super("sharewhereiam"); } @@ -27,7 +25,8 @@ public String getCommandUsage(ICommandSender sender) { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { ensureArgsLength(args, 0); - assert sender instanceof EntityPlayer; - network.sendToServer(new MessageShareWaypoint(WaypointUtil.waypointOfLocation())); + if (sender instanceof EntityPlayer) { + network.sendToServer(new MessageShareWaypoint(WaypointUtil.waypointOfLocation())); + } } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java index f70d5ed..7628362 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/CommandWaypointToggleTempBeacon.java @@ -11,8 +11,6 @@ public class CommandWaypointToggleTempBeacon extends CommandWaypointBase { - public static CommandWaypointToggleTempBeacon INSTANCE = new CommandWaypointToggleTempBeacon(); - public CommandWaypointToggleTempBeacon() { super("toggletempbeacon"); } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java b/src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java index fd17dbd..70af891 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/command/base/CommandWaypointBase.java @@ -17,7 +17,6 @@ public abstract class CommandWaypointBase extends CommandBase { final protected String commandName; - protected String commandUsage; public CommandWaypointBase(@Nonnull String commandName) { super(); @@ -44,7 +43,7 @@ public boolean canCommandSenderUseCommand(ICommandSender sender) { @Override @Nonnull public String getCommandUsage(ICommandSender sender) { - return commandUsage; + return ""; } @Nonnull @@ -60,12 +59,16 @@ protected Waypoint parseWaypoint(@Nonnull String waypointCode) throws CommandExc protected void ensureArgsLength(@Nullable String[] args, int min, int max) throws CommandException { final int argsLength = args != null ? args.length : 0; - if (argsLength < min || argsLength > max) new CommandException(commandUsage); + if (argsLength < min || argsLength > max) throw getCommandException(); } protected void ensureArgsLength(@Nullable String[] args, int length) throws CommandException { final int argsLength = args != null ? args.length : 0; - if (argsLength != length) new CommandException(commandUsage); + if (argsLength != length) throw getCommandException(); } + @Nonnull + public CommandException getCommandException() { + return new CommandException("sharewhereiam.command." + this.getCommandName() + ".usage"); + } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java b/src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java deleted file mode 100644 index df2a44a..0000000 --- a/src/main/java/com/muxiu1997/sharewhereiam/core/ShareWhereIAmCore.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.muxiu1997.sharewhereiam.core; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader; -import com.muxiu1997.sharewhereiam.mixins.Mixins; - -import cpw.mods.fml.relauncher.IFMLLoadingPlugin; - -public class ShareWhereIAmCore implements IFMLLoadingPlugin, IEarlyMixinLoader { - - @Override - public String[] getASMTransformerClass() { - return new String[0]; - } - - @Override - public String getModContainerClass() { - return null; - } - - @Override - public String getSetupClass() { - return null; - } - - @Override - public void injectData(Map data) {} - - @Override - public String getAccessTransformerClass() { - return null; - } - - @Override - public String getMixinConfig() { - return "mixins.sharewhereiam.early.json"; - } - - @Override - public List getMixins(Set loadedCoreMods) { - return Mixins.getEarlyMixins(loadedCoreMods); - } -} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java b/src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java index a29b230..4f501c7 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/event/EventHandler.java @@ -10,7 +10,7 @@ import org.lwjgl.input.Keyboard; -import com.muxiu1997.sharewhereiam.client.key.KeyShare; +import com.muxiu1997.sharewhereiam.client.key.KeyBindings; import com.muxiu1997.sharewhereiam.integration.Mods; import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointManager; import com.muxiu1997.sharewhereiam.integration.journeymap.WaypointMarker; @@ -25,8 +25,6 @@ public class EventHandler { - public static final EventHandler INSTANCE = new EventHandler(); - @SubscribeEvent @SideOnly(Side.CLIENT) public void handleEntityJoinWorld(EntityJoinWorldEvent event) { @@ -40,7 +38,7 @@ public void handleEntityJoinWorld(EntityJoinWorldEvent event) { @SubscribeEvent @SideOnly(Side.CLIENT) public void handleKeyInput(InputEvent.KeyInputEvent event) { - if (!KeyShare.INSTANCE.isPressed()) return; + if (!KeyBindings.WaypointShare.isPressed()) return; if (Mods.JourneyMap.isLoaded()) { // Determine the waypoint based on Shift key state diff --git a/src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java b/src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java index 5cf2d84..c068ddb 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/integration/Mods.java @@ -11,17 +11,16 @@ public enum Mods { ; public final String modid; - private boolean loaded; + private Boolean loaded; Mods(String modid) { this.modid = modid; } public boolean isLoaded() { + if (loaded == null) { + loaded = Loader.isModLoaded(modid); + } return loaded; } - - public void check() { - this.loaded = Loader.isModLoaded(modid); - } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java index a6d5b27..6ed14b2 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointManager.java @@ -16,14 +16,12 @@ @SideOnly(Side.CLIENT) public class WaypointManager { - public static WaypointManager INSTANCE = new WaypointManager(); - public static Waypoint tempBeacon = null; private static final Map transientBeaconCache = new HashMap<>(); @Nullable - public Waypoint getTempBeacon() { - return this.tempBeacon; + public static Waypoint getTempBeacon() { + return tempBeacon; } public static boolean hasActiveTempBeacon() { diff --git a/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java index cbf38dd..7817f51 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/integration/journeymap/WaypointMarker.java @@ -15,7 +15,7 @@ public class WaypointMarker { public static void render(RenderWorldLastEvent event) { - List transientBeacons = WaypointManager.INSTANCE.getTransientBeacons(); + List transientBeacons = WaypointManager.getTransientBeacons(); if (transientBeacons.isEmpty()) return; float partialTicks = event.partialTicks; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java deleted file mode 100644 index a7e67c9..0000000 --- a/src/main/java/com/muxiu1997/sharewhereiam/loader/CommandLoader.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader; - -import net.minecraftforge.client.ClientCommandHandler; - -import com.muxiu1997.sharewhereiam.command.CommandWaypointSave; -import com.muxiu1997.sharewhereiam.command.CommandWaypointShareLocation; -import com.muxiu1997.sharewhereiam.command.CommandWaypointToggleTempBeacon; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class CommandLoader { - - public static CommandLoader INSTANCE = new CommandLoader(); - - @SideOnly(Side.CLIENT) - public void clientLoad() { - ClientCommandHandler.instance.registerCommand(CommandWaypointSave.INSTANCE); - ClientCommandHandler.instance.registerCommand(CommandWaypointShareLocation.INSTANCE); - ClientCommandHandler.instance.registerCommand(CommandWaypointToggleTempBeacon.INSTANCE); - } -} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java deleted file mode 100644 index 56132c8..0000000 --- a/src/main/java/com/muxiu1997/sharewhereiam/loader/EventLoader.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader; - -import net.minecraftforge.common.MinecraftForge; - -import com.muxiu1997.sharewhereiam.event.EventHandler; - -import cpw.mods.fml.common.FMLCommonHandler; - -public class EventLoader { - - public static final EventLoader INSTANCE = new EventLoader(); - - public void load() { - MinecraftForge.EVENT_BUS.register(EventHandler.INSTANCE); - FMLCommonHandler.instance().bus().register(EventHandler.INSTANCE); - } -} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java index 90457c7..fa9d2a9 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/loader/IntegrationLoader.java @@ -6,9 +6,7 @@ public class IntegrationLoader { - public static final IntegrationLoader INSTANCE = new IntegrationLoader(); - - public void load() { - Arrays.stream(Mods.values()).forEach(Mods::check); + public static void load() { + Arrays.stream(Mods.values()).forEach(Mods::isLoaded); } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java deleted file mode 100644 index a7a4a93..0000000 --- a/src/main/java/com/muxiu1997/sharewhereiam/loader/KeyLoader.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.muxiu1997.sharewhereiam.loader; - -import com.muxiu1997.sharewhereiam.client.key.KeyShare; - -import cpw.mods.fml.client.registry.ClientRegistry; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class KeyLoader { - - public static final KeyLoader INSTANCE = new KeyLoader(); - - public void clientLoad() { - ClientRegistry.registerKeyBinding(KeyShare.INSTANCE); - } -} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java b/src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java index 4ef16fd..018e5cd 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/loader/NetworkLoader.java @@ -11,8 +11,6 @@ public class NetworkLoader { - public static final NetworkLoader INSTANCE = new NetworkLoader(); - private static int nextID = 0; public static void load() { diff --git a/src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java b/src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java index 4fae79e..afe0a5b 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/localization/Lang.java @@ -4,7 +4,6 @@ public class Lang { - // Localized strings public static LocalizedString SAVE_WAYPOINT_USAGE; public static LocalizedString SAVE_WAYPOINT_SUCCESS; public static LocalizedString SAVE_WAYPOINT_EXISTS; @@ -24,18 +23,16 @@ public class Lang { public static LocalizedString TEXT_DEFAULT_WAYPOINT_NAME; public static LocalizedString TEXT_JM_WAYPOINT_BUTTON; - // Constants for prefix private static final String PREFIX_COMMAND = "sharewhereiam.command"; private static final String PREFIX_COMMAND_ERROR = "sharewhereiam.commanderror"; private static final String PREFIX_CHAT = "sharewhereiam.chat"; private static final String PREFIX_KEYBINDING = "sharewhereiam.keybinding"; private static final String PREFIX_TEXT = "sharewhereiam.text"; - // Initialize the localized strings static { - SAVE_WAYPOINT_USAGE = new LocalizedString(PREFIX_COMMAND + ".usage"); - SAVE_WAYPOINT_SUCCESS = new LocalizedString(PREFIX_COMMAND + ".save.success"); - SAVE_WAYPOINT_EXISTS = new LocalizedString(PREFIX_COMMAND + ".save.exists"); + SAVE_WAYPOINT_USAGE = new LocalizedString(PREFIX_COMMAND + ".savewaypoint.usage"); + SAVE_WAYPOINT_SUCCESS = new LocalizedString(PREFIX_COMMAND + ".savewaypoint.save.success"); + SAVE_WAYPOINT_EXISTS = new LocalizedString(PREFIX_COMMAND + ".savewaypoint.save.exists"); SHARE_WHERE_I_AM_USAGE = new LocalizedString(PREFIX_COMMAND + ".sharewhereiam.usage"); TOGGLE_TEMP_BEACON_USAGE = new LocalizedString(PREFIX_COMMAND + ".toggletempbeacon.usage"); ERROR_INVALID_WAYPOINT_CODE = new LocalizedString(PREFIX_COMMAND_ERROR + ".invalidcode"); @@ -53,7 +50,6 @@ public class Lang { TEXT_JM_WAYPOINT_BUTTON = new LocalizedString(PREFIX_TEXT + ".jm.waypoint.share"); } - // LocalizedString class public static class LocalizedString { private final String key; @@ -66,7 +62,6 @@ public String getKey() { return key; } - // Method to translate the string using Minecraft's I18n system public String translate() { return I18n.format(key); } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/Mixins.java similarity index 93% rename from src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/Mixins.java index 3fd5e68..3733aac 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/Mixins.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/Mixins.java @@ -1,4 +1,4 @@ -package com.muxiu1997.sharewhereiam.mixins; +package com.muxiu1997.sharewhereiam.mixinplugin; import java.util.ArrayList; import java.util.Arrays; @@ -14,12 +14,15 @@ public enum Mixins { - JOURNEYMAP_(new Builder("JourneyMap integration").addTargetedMod(TargetedMod.JOURNEYMAP).setSide(Side.CLIENT) + JOURNEYMAP(new Builder("JourneyMap integration").addTargetedMod(TargetedMod.JOURNEYMAP).setSide(Side.CLIENT) .setPhase(Phase.LATE).addMixinClasses( "journeymap.MixinFullscreen", "journeymap.MixinRenderWaypointBeacon", "journeymap.MixinWaypointManagerItem", - "journeymap.MixinWaypointStore")); + "journeymap.MixinWaypointStore")), + + NAVIGATOR(new Builder("Navigator integration").addTargetedMod(TargetedMod.NAVIGATOR).setSide(Side.CLIENT) + .setPhase(Phase.LATE).addMixinClasses("navigator.UniversalInteractableRendererAccessor")); private final List mixinClasses; private final Supplier applyIf; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAmLateMixin.java b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/ShareWhereIAmLateMixin.java similarity index 84% rename from src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAmLateMixin.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/ShareWhereIAmLateMixin.java index 1d3d224..92cb14d 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/ShareWhereIAmLateMixin.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/ShareWhereIAmLateMixin.java @@ -1,11 +1,10 @@ -package com.muxiu1997.sharewhereiam; +package com.muxiu1997.sharewhereiam.mixinplugin; import java.util.List; import java.util.Set; import com.gtnewhorizon.gtnhmixins.ILateMixinLoader; import com.gtnewhorizon.gtnhmixins.LateMixin; -import com.muxiu1997.sharewhereiam.mixins.Mixins; @LateMixin public class ShareWhereIAmLateMixin implements ILateMixinLoader { diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/TargetedMod.java similarity index 91% rename from src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/TargetedMod.java index 1ebb9ca..f87d159 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/TargetedMod.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/TargetedMod.java @@ -1,8 +1,9 @@ -package com.muxiu1997.sharewhereiam.mixins; +package com.muxiu1997.sharewhereiam.mixinplugin; public enum TargetedMod { VANILLA("Minecraft", null), + NAVIGATOR("Navigator", null, "navigator"), JOURNEYMAP("JourneyMap", null, "journeymap"), XAEROMINIMAP("Xaero's Minimap", "xaero.common.core.XaeroMinimapPlugin", "XaeroMinimap"), XAEROWORLDMAP("Xaero's World Map", "xaero.map.core.XaeroWorldMapPlugin", "XaeroWorldMap"); diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixininterfaces/IMixinWaypointStore.java b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/interfaces/IMixinWaypointStore.java similarity index 67% rename from src/main/java/com/muxiu1997/sharewhereiam/mixininterfaces/IMixinWaypointStore.java rename to src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/interfaces/IMixinWaypointStore.java index 7127c98..6a0a96a 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixininterfaces/IMixinWaypointStore.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixinplugin/interfaces/IMixinWaypointStore.java @@ -1,4 +1,4 @@ -package com.muxiu1997.sharewhereiam.mixininterfaces; +package com.muxiu1997.sharewhereiam.mixinplugin.interfaces; import journeymap.client.model.Waypoint; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinFullscreen.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinFullscreen.java index 743bc21..5dc6c00 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinFullscreen.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinFullscreen.java @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.muxiu1997.sharewhereiam.client.key.KeyShare; +import com.muxiu1997.sharewhereiam.client.key.KeyBindings; import com.muxiu1997.sharewhereiam.integration.Mods; import com.muxiu1997.sharewhereiam.localization.Lang; import com.muxiu1997.sharewhereiam.network.MessageShareWaypoint; @@ -41,7 +41,7 @@ public MixinFullscreen() { @Inject(method = "func_73869_a", at = @At(value = "HEAD"), remap = false, require = 1, cancellable = true) private void inject_func_73869_a(CallbackInfo callbackInfo) { if (!Mods.VisualProspecting.isLoaded()) return; - if ((chat == null || chat.isHidden()) && Constants.isPressed(KeyShare.INSTANCE)) { + if ((chat == null || chat.isHidden()) && Constants.isPressed(KeyBindings.WaypointShare)) { @Nullable final Waypoint waypoint = VPWaypointUtil.getHoveredWaypoint(); if (waypoint == null) return; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinRenderWaypointBeacon.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinRenderWaypointBeacon.java index 256c5ef..d872cae 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinRenderWaypointBeacon.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinRenderWaypointBeacon.java @@ -25,14 +25,14 @@ static void doRender(Waypoint waypoint) {} @Inject(method = "renderAll", at = @At(value = "RETURN", remap = false), remap = false, require = 1) private static void inject_renderAll(CallbackInfo callbackInfo) { - if (WaypointManager.INSTANCE.hasActiveTempBeacon()) { - final Waypoint waypoint = WaypointManager.INSTANCE.getTempBeacon(); + if (WaypointManager.hasActiveTempBeacon()) { + final Waypoint waypoint = WaypointManager.getTempBeacon(); assert waypoint != null; if (waypoint.getDimensions().contains(mc.thePlayer.dimension)) { doRender(waypoint); } } - for (Waypoint waypoint : WaypointManager.INSTANCE.getTransientBeacons()) { + for (Waypoint waypoint : WaypointManager.getTransientBeacons()) { doRender(waypoint); } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointStore.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointStore.java index c0158dc..1a42fef 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointStore.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/journeymap/MixinWaypointStore.java @@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Shadow; import com.google.common.cache.Cache; -import com.muxiu1997.sharewhereiam.mixininterfaces.IMixinWaypointStore; +import com.muxiu1997.sharewhereiam.mixinplugin.interfaces.IMixinWaypointStore; import journeymap.client.model.Waypoint; import journeymap.client.waypoint.WaypointStore; diff --git a/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/navigator/UniversalInteractableRendererAccessor.java b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/navigator/UniversalInteractableRendererAccessor.java new file mode 100644 index 0000000..e20f93d --- /dev/null +++ b/src/main/java/com/muxiu1997/sharewhereiam/mixins/late/navigator/UniversalInteractableRendererAccessor.java @@ -0,0 +1,15 @@ +package com.muxiu1997.sharewhereiam.mixins.late.navigator; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import com.gtnewhorizons.navigator.api.model.layers.UniversalInteractableRenderer; +import com.gtnewhorizons.navigator.api.model.steps.UniversalInteractableStep; + +@Mixin(UniversalInteractableRenderer.class) +public interface UniversalInteractableRendererAccessor { + + @Accessor(value = "hoveredRenderStep", remap = false) + UniversalInteractableStep getHoveredRenderStep(); + +} diff --git a/src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java b/src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java index b1062e6..3ce8c98 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/proxy/ClientProxy.java @@ -1,17 +1,29 @@ package com.muxiu1997.sharewhereiam.proxy; -import com.muxiu1997.sharewhereiam.loader.CommandLoader; -import com.muxiu1997.sharewhereiam.loader.KeyLoader; +import net.minecraftforge.client.ClientCommandHandler; +import com.muxiu1997.sharewhereiam.client.key.KeyBindings; +import com.muxiu1997.sharewhereiam.command.CommandWaypointSave; +import com.muxiu1997.sharewhereiam.command.CommandWaypointShareLocation; +import com.muxiu1997.sharewhereiam.command.CommandWaypointToggleTempBeacon; + +import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; @SuppressWarnings("unused") public class ClientProxy extends CommonProxy { + @Override + public void init(FMLInitializationEvent event) { + super.init(event); + KeyBindings.init(); + } + @Override public void postInit(FMLPostInitializationEvent event) { super.postInit(event); - CommandLoader.INSTANCE.clientLoad(); - KeyLoader.INSTANCE.clientLoad(); + ClientCommandHandler.instance.registerCommand(new CommandWaypointSave()); + ClientCommandHandler.instance.registerCommand(new CommandWaypointShareLocation()); + ClientCommandHandler.instance.registerCommand(new CommandWaypointToggleTempBeacon()); } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java b/src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java index 11856ba..f738dd2 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/proxy/CommonProxy.java @@ -1,16 +1,23 @@ package com.muxiu1997.sharewhereiam.proxy; -import com.muxiu1997.sharewhereiam.loader.EventLoader; +import net.minecraftforge.common.MinecraftForge; + +import com.muxiu1997.sharewhereiam.event.EventHandler; import com.muxiu1997.sharewhereiam.loader.IntegrationLoader; import com.muxiu1997.sharewhereiam.loader.NetworkLoader; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; public class CommonProxy { + public void init(FMLInitializationEvent event) {} + public void postInit(FMLPostInitializationEvent event) { - IntegrationLoader.INSTANCE.load(); - EventLoader.INSTANCE.load(); - NetworkLoader.INSTANCE.load(); + MinecraftForge.EVENT_BUS.register(new EventHandler()); + FMLCommonHandler.instance().bus().register(new EventHandler()); + IntegrationLoader.load(); + NetworkLoader.load(); } } diff --git a/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java b/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java index 1467fa0..eccd407 100644 --- a/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java +++ b/src/main/java/com/muxiu1997/sharewhereiam/util/VPWaypointUtil.java @@ -1,7 +1,6 @@ package com.muxiu1997.sharewhereiam.util; import java.awt.Color; -import java.lang.reflect.Field; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -12,9 +11,9 @@ import com.gtnewhorizons.navigator.api.model.layers.UniversalInteractableRenderer; import com.gtnewhorizons.navigator.api.model.steps.UniversalInteractableStep; import com.gtnewhorizons.navigator.api.model.waypoints.Waypoint; +import com.muxiu1997.sharewhereiam.mixins.late.navigator.UniversalInteractableRendererAccessor; import cpw.mods.fml.common.Optional; -import cpw.mods.fml.relauncher.ReflectionHelper; public class VPWaypointUtil { @@ -23,13 +22,8 @@ public class VPWaypointUtil { public static journeymap.client.model.Waypoint getHoveredWaypoint() { for (LayerRenderer layer : NavigatorApi.getActiveRenderersFor(SupportedMods.JourneyMap)) { if (layer instanceof UniversalInteractableRenderer) { - final Field FieldHoveredDrawStep = ReflectionHelper - .findField(UniversalInteractableRenderer.class, "hoveredRenderStep"); - @Nullable - UniversalInteractableStep hoveredRenderStep = null; - try { - hoveredRenderStep = (UniversalInteractableStep) FieldHoveredDrawStep.get(layer); - } catch (Exception ignored) {} + UniversalInteractableStep hoveredRenderStep = ((UniversalInteractableRendererAccessor) layer) + .getHoveredRenderStep(); if (hoveredRenderStep != null) { final Waypoint waypoint = hoveredRenderStep.getLocation().toWaypoint(); if (waypoint != null) { diff --git a/src/main/resources/assets/sharewhereiam/lang/en_US.lang b/src/main/resources/assets/sharewhereiam/lang/en_US.lang index e5c0c5e..4387deb 100644 --- a/src/main/resources/assets/sharewhereiam/lang/en_US.lang +++ b/src/main/resources/assets/sharewhereiam/lang/en_US.lang @@ -1,6 +1,6 @@ -sharewhereiam.command.usage=Usage: /savewaypoint [neet to open editor? default: true] -sharewhereiam.command.save.success=Waypoint saved -sharewhereiam.command.save.exists=Waypoint exists, can't save +sharewhereiam.command.savewaypoint.usage=Usage: /savewaypoint [neet to open editor? default: true] +sharewhereiam.command.savewaypoint.save.success=Waypoint saved +sharewhereiam.command.savewaypoint.save.exists=Waypoint exists, can't save sharewhereiam.command.sharewhereiam.usage=Usage: /sharewhereiam sharewhereiam.command.toggletempbeacon.usage=Usage: /toggletempbeacon [waypoint code] diff --git a/src/main/resources/mixins.sharewhereiam.early.json b/src/main/resources/mixins.sharewhereiam.early.json deleted file mode 100644 index 82fffc7..0000000 --- a/src/main/resources/mixins.sharewhereiam.early.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "required": true, - "minVersion": "0.8.5-GTNH", - "package": "com.muxiu1997.sharewhereiam.mixins.early", - "refmap": "mixins.sharewhereiam.refmap.json", - "target": "@env(DEFAULT)", - "compatibilityLevel": "JAVA_8" -}