mirror of
https://github.com/TheWhiteDog9487/WhoProvideThisKeybind.git
synced 2026-09-16 15:04:19 +08:00
⭐ init: 完成
This commit is contained in:
+9
@@ -0,0 +1,9 @@
|
||||
package xyz.thewhitedog9487.client.mixin.Compatibility.Controlling;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
|
||||
public class MixinPlugin implements IMixinConfigPlugin {
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
return FabricLoader.getInstance().isModLoaded(("controlling")); } }
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package xyz.thewhitedog9487.client.mixin.Compatibility.Controlling;
|
||||
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import xyz.thewhitedog9487.client.MiscellaneousKt;
|
||||
import xyz.thewhitedog9487.client.SettingsKt;
|
||||
import xyz.thewhitedog9487.client.WhoProvideThisKeybindModClient;
|
||||
|
||||
/**
|
||||
* <a href="https://modrinth.com/mod/controlling">Controlling</a>把原版的UI直接给换了,因此需要注入到修改之后的UI中
|
||||
*
|
||||
* @see xyz.thewhitedog9487.client.mixin.Compatibility.Controlling.MixinPlugin
|
||||
*/
|
||||
@Pseudo
|
||||
@Mixin(targets = "com.blamejared.controlling.client.NewKeyBindsList$KeyEntry")
|
||||
public abstract class NewKeyBindsListMixin {
|
||||
@Shadow @Final private KeyMapping key;
|
||||
@Shadow @Final private Button btnChangeKeyBinding;
|
||||
@Inject(method = "refreshEntry", at = @At("TAIL"))
|
||||
private void SetNewTooltipInControllingUI(final CallbackInfo ci) {
|
||||
if (SettingsKt.getSettingsInstance().getShowDebugInfo()) {
|
||||
WhoProvideThisKeybindModClient.INSTANCE.getClientLogger().debug("SetNewTooltipInControllingUI函数被调用,Key:{}", key.getName()); }
|
||||
MiscellaneousKt.SetNewTooltip(btnChangeKeyBinding, key); } }
|
||||
@@ -0,0 +1,32 @@
|
||||
package xyz.thewhitedog9487.client.mixin;
|
||||
|
||||
import xyz.thewhitedog9487.client.MiscellaneousKt;
|
||||
import xyz.thewhitedog9487.client.SettingsKt;
|
||||
import xyz.thewhitedog9487.client.WhoProvideThisKeybindModClient;
|
||||
import xyz.thewhitedog9487.client.ModInfo;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.client.gui.screens.options.controls.KeyBindsList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* 针对原版的实现
|
||||
*/
|
||||
@Mixin(KeyBindsList.KeyEntry.class)
|
||||
public abstract class KeyBindsListKeyEntryMixin {
|
||||
@Shadow @Final private KeyMapping key;
|
||||
@Shadow @Final private Button changeButton;
|
||||
|
||||
@Inject(method = "refreshEntry", at = @At("RETURN"))
|
||||
private void SetTooltip(CallbackInfo ci) {
|
||||
if (SettingsKt.getSettingsInstance().getShowDebugInfo()) {
|
||||
WhoProvideThisKeybindModClient.INSTANCE.getClientLogger().debug("SetTooltip函数被调用,Key:{}", key.getName()); }
|
||||
MiscellaneousKt.SetNewTooltip(changeButton, key); } }
|
||||
@@ -0,0 +1,44 @@
|
||||
package xyz.thewhitedog9487.client.Event
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import dev.isxander.yacl3.config.v2.api.ConfigClassHandler
|
||||
import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
|
||||
import net.minecraft.resources.Identifier
|
||||
import xyz.thewhitedog9487.client.ConfigFilePath
|
||||
import xyz.thewhitedog9487.client.CurrentConfigurationVersionCode
|
||||
import xyz.thewhitedog9487.client.RegisterConfigFileReloadWatcher
|
||||
import xyz.thewhitedog9487.client.Settings
|
||||
import xyz.thewhitedog9487.client.SettingsHandler
|
||||
import xyz.thewhitedog9487.client.SettingsInstance
|
||||
import xyz.thewhitedog9487.client.WhoProvideThisKeybindModClient
|
||||
|
||||
fun RegisterClientLifecycleEvents() {
|
||||
ClientLifecycleEvents.CLIENT_STARTED.register { ClientInstance ->
|
||||
try {
|
||||
SettingsHandler = ConfigClassHandler
|
||||
.createBuilder(Settings::class.java)
|
||||
.id(Identifier.fromNamespaceAndPath(WhoProvideThisKeybindModClient.ModID, "settings_confighandler"))
|
||||
.serializer {
|
||||
GsonConfigSerializerBuilder.create(it)
|
||||
.setPath(ConfigFilePath)
|
||||
.setJson5(true)
|
||||
.appendGsonBuilder(GsonBuilder::setPrettyPrinting)
|
||||
.build() }
|
||||
.build()
|
||||
|
||||
WhoProvideThisKeybindModClient.ClientLogger.info("正在从${ConfigFilePath}加载设置...")
|
||||
SettingsHandler!!.load()
|
||||
SettingsInstance = SettingsHandler!!.instance()
|
||||
if (SettingsInstance.ConfigurationVersionCode != CurrentConfigurationVersionCode) {
|
||||
// 必要时手动处理升降级,现在不必要,就这么办了
|
||||
SettingsInstance.ConfigurationVersionCode = CurrentConfigurationVersionCode
|
||||
SettingsHandler!!.save() }
|
||||
RegisterConfigFileReloadWatcher() }
|
||||
catch (_: NoClassDefFoundError) {
|
||||
SettingsInstance = Settings()
|
||||
WhoProvideThisKeybindModClient.ClientLogger.warn("当前没有安装YetAnotherConfigLib,因此无法在调整和保持Mod配置") } }
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register { ClientInstance ->
|
||||
if (SettingsHandler == null) return@register
|
||||
WhoProvideThisKeybindModClient.ClientLogger.info("正在保存设置到$ConfigFilePath...")
|
||||
SettingsHandler!!.save() } }
|
||||
@@ -0,0 +1,60 @@
|
||||
package xyz.thewhitedog9487.client
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import net.fabricmc.loader.api.ModContainer
|
||||
import net.fabricmc.loader.api.metadata.ModMetadata
|
||||
import net.minecraft.client.KeyMapping
|
||||
import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.gui.components.Tooltip
|
||||
import net.minecraft.network.chat.Component
|
||||
|
||||
val VanillaMinecraftContainer: ModContainer = FabricLoader
|
||||
.getInstance()
|
||||
.getModContainer("minecraft")
|
||||
.get()
|
||||
|
||||
val KeyMapping.Provider: ModInfo get() {
|
||||
val KeyBindTranslationKey = name
|
||||
val CandidateModIds = KeyBindTranslationKey.split(".")
|
||||
if (CandidateModIds.size == 1){
|
||||
WhoProvideThisKeybindModClient.ClientLogger.warn("这是个什么东西,按键绑定ID只有一个部分,ID: $KeyBindTranslationKey")
|
||||
return ModInfo(null) }
|
||||
for (CandidateModId in CandidateModIds) {
|
||||
val ModContainer = FabricLoader.getInstance().getModContainer(CandidateModId)
|
||||
if (ModContainer.isPresent) {
|
||||
return ModContainer.map(::ModInfo).get() } }
|
||||
return ModInfo(VanillaMinecraftContainer) }
|
||||
|
||||
data class ModInfo(val ModContainerInstance: ModContainer?) {
|
||||
val ID: String = ModContainerInstance?.metadata?.id ?: Component.translatable("special_provider_UNKNOWN").string
|
||||
val MetaData: ModMetadata? = ModContainerInstance?.metadata
|
||||
val DisplayName: String = MetaData?.name ?: Component.translatable("special_provider_UNKNOWN").string
|
||||
val HumanFriendlyName: Component = Component.translatableWithFallback("modmenu.nameTranslation." + (MetaData?.id ?: "unknown"), DisplayName) }
|
||||
|
||||
fun Button.SetNewTooltip(Key: KeyMapping) {
|
||||
if (SettingsInstance.ModEnabled == false) return
|
||||
|
||||
val Mod = Key.Provider
|
||||
val NewTooltip = tooltip
|
||||
.get()
|
||||
?.message
|
||||
?.copy()
|
||||
?.append(Component.literal("\n"))
|
||||
?.append(Component.literal("\n"))
|
||||
?: Component.empty()
|
||||
|
||||
// 第一行:Mod的人类可读名称
|
||||
NewTooltip.append(Component.translatable("tooltip.provided_by",
|
||||
Mod.HumanFriendlyName))
|
||||
// 第二行:Mod的ID
|
||||
if (SettingsInstance.ShowModID) {
|
||||
NewTooltip.append(Component.literal("\n"))
|
||||
.append(Component.translatable("tooltip.provider_mod_id",
|
||||
Component.literal(Mod.ID))); }
|
||||
// 第三行:按键自身的ID
|
||||
if (SettingsInstance.ShowKeybindID) {
|
||||
NewTooltip.append(Component.literal("\n"))
|
||||
.append(Component.translatable("tooltip.key_id",
|
||||
Component.literal(Key.name))) }
|
||||
|
||||
setTooltip(Tooltip.create(NewTooltip)) }
|
||||
@@ -0,0 +1,49 @@
|
||||
package xyz.thewhitedog9487.client
|
||||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi
|
||||
import dev.isxander.yacl3.api.ConfigCategory
|
||||
import dev.isxander.yacl3.api.Option
|
||||
import dev.isxander.yacl3.api.OptionDescription
|
||||
import dev.isxander.yacl3.api.YetAnotherConfigLib
|
||||
import dev.isxander.yacl3.api.controller.BooleanControllerBuilder
|
||||
import net.minecraft.network.chat.Component
|
||||
|
||||
class ModMenuEntryPoint: ModMenuApi {
|
||||
override fun getModConfigScreenFactory() = ConfigScreenFactory { ParentScreen ->
|
||||
YetAnotherConfigLib.createBuilder()
|
||||
.title(Component.translatable("title.config"))
|
||||
.category {
|
||||
ConfigCategory.createBuilder()
|
||||
.name(Component.translatable("config.category.general"))
|
||||
.option {
|
||||
Option.createBuilder<Boolean>()
|
||||
.name(Component.translatable("option.ModEnabled"))
|
||||
.description { OptionDescription.of(Component.translatable("option.ModEnabled.description") ) }
|
||||
.binding( true, { SettingsInstance.ModEnabled }, { SettingsInstance.ModEnabled = it } )
|
||||
.controller(BooleanControllerBuilder::create )
|
||||
.build() }
|
||||
.option {
|
||||
Option.createBuilder<Boolean>()
|
||||
.name(Component.translatable("option.ShowModID"))
|
||||
.description { OptionDescription.of(Component.translatable("option.ShowModID.description") ) }
|
||||
.binding( false, { SettingsInstance.ShowModID }, { SettingsInstance.ShowModID = it } )
|
||||
.controller(BooleanControllerBuilder::create )
|
||||
.build() }
|
||||
.option {
|
||||
Option.createBuilder<Boolean>()
|
||||
.name(Component.translatable("option.ShowKeybindID"))
|
||||
.description { OptionDescription.of(Component.translatable("option.ShowKeybindID.description") ) }
|
||||
.binding( false, { SettingsInstance.ShowKeybindID }, { SettingsInstance.ShowKeybindID = it } )
|
||||
.controller(BooleanControllerBuilder::create )
|
||||
.build() }
|
||||
.option {
|
||||
Option.createBuilder<Boolean>()
|
||||
.name(Component.translatable("option.ShowDebugInfo"))
|
||||
.description { OptionDescription.of(Component.translatable("option.ShowDebugInfo.description") ) }
|
||||
.binding( false, { SettingsInstance.ShowDebugInfo }, { SettingsInstance.ShowDebugInfo = it } )
|
||||
.controller(BooleanControllerBuilder::create )
|
||||
.build() }
|
||||
.build() }
|
||||
.build()
|
||||
.generateScreen(ParentScreen) } }
|
||||
@@ -0,0 +1,102 @@
|
||||
package xyz.thewhitedog9487.client
|
||||
|
||||
import dev.isxander.yacl3.config.v2.api.ConfigClassHandler
|
||||
import dev.isxander.yacl3.config.v2.api.SerialEntry
|
||||
import kotlinx.io.IOException
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardWatchEventKinds
|
||||
import java.nio.file.StandardWatchEventKinds.*
|
||||
|
||||
const val CurrentConfigurationVersionCode: Long = 0
|
||||
class Settings {
|
||||
@SerialEntry(comment =
|
||||
"""
|
||||
配置文件版本号
|
||||
用于在配置文件结构发生变化且需要手动干预时进行兼容性处理
|
||||
非必要情况下你不应该手动修改这个数据,否则可能导致本Mod的配置文件出现损坏或其他问题
|
||||
类型:整数
|
||||
取值范围:0 ~ Long.MAX_VALUE
|
||||
当前值:0
|
||||
""")
|
||||
var ConfigurationVersionCode = CurrentConfigurationVersionCode
|
||||
|
||||
@SerialEntry(comment =
|
||||
"""
|
||||
是否启用本模组的功能
|
||||
类型:布尔值
|
||||
取值范围:true false
|
||||
默认值:true
|
||||
""")
|
||||
var ModEnabled = true
|
||||
|
||||
@SerialEntry(comment =
|
||||
"""
|
||||
是否在悬停信息中显示键位提供者的ID
|
||||
类型:布尔值
|
||||
取值范围:true false
|
||||
默认值:false
|
||||
""")
|
||||
var ShowModID = false
|
||||
|
||||
@SerialEntry(comment =
|
||||
"""
|
||||
是否在悬停信息中显示键位本身的ID
|
||||
类型:布尔值
|
||||
取值范围:true false
|
||||
默认值:false
|
||||
""")
|
||||
var ShowKeybindID = false
|
||||
|
||||
@SerialEntry(comment =
|
||||
"""
|
||||
是否显示调试信息
|
||||
这些信息用于出现和本Mod相关的问题时进行排查,一般情况下不需要开启
|
||||
类型:布尔值
|
||||
取值范围:true false
|
||||
默认值:false
|
||||
""")
|
||||
var ShowDebugInfo = false }
|
||||
|
||||
var SettingsHandler: ConfigClassHandler<Settings>? = null
|
||||
|
||||
val ConfigFilePath = FabricLoader
|
||||
.getInstance()
|
||||
.configDir
|
||||
.resolve(WhoProvideThisKeybindModClient.FriendlyModID + ".json5")
|
||||
.toAbsolutePath()
|
||||
|
||||
@Volatile var SettingsInstance = Settings()
|
||||
|
||||
// region 配置文件变更监听器
|
||||
fun RegisterConfigFileReloadWatcher() {
|
||||
// 由GPT 5.4 Mini生成
|
||||
Thread.startVirtualThread {
|
||||
WhoProvideThisKeybindModClient.ClientLogger.info("正在为${ConfigFilePath}注册配置文件变更监听器...")
|
||||
val ConfigDirectory = ConfigFilePath.parent
|
||||
try {
|
||||
val WatchService = FileSystems.getDefault().newWatchService()
|
||||
ConfigDirectory.register(WatchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE)
|
||||
while (!Thread.currentThread().isInterrupted) {
|
||||
val WatchKey = WatchService.take()
|
||||
var ShouldReload = false
|
||||
|
||||
for (EventInstance in WatchKey.pollEvents()) {
|
||||
val EventKind = EventInstance.kind()
|
||||
if (EventKind == StandardWatchEventKinds.OVERFLOW) {
|
||||
continue }
|
||||
val ChangedPath = EventInstance.context() as Path?
|
||||
if (ChangedPath != null && ChangedPath == ConfigFilePath.fileName) {
|
||||
ShouldReload = true } }
|
||||
if (ShouldReload) {
|
||||
SettingsHandler!!.load()
|
||||
SettingsInstance = SettingsHandler!!.instance()
|
||||
WhoProvideThisKeybindModClient.ClientLogger.info("检测到配置文件变更,已重新加载设置。") }
|
||||
if (!WatchKey.reset()) {
|
||||
break } }
|
||||
} catch (e: InterruptedException) {
|
||||
Thread.currentThread().interrupt()
|
||||
} catch (e: IOException) {
|
||||
throw RuntimeException(e) } } }
|
||||
// endregion
|
||||
@@ -0,0 +1,13 @@
|
||||
package xyz.thewhitedog9487.client
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer
|
||||
import org.slf4j.LoggerFactory
|
||||
import xyz.thewhitedog9487.client.Event.RegisterClientLifecycleEvents
|
||||
|
||||
object WhoProvideThisKeybindModClient : ClientModInitializer {
|
||||
const val ModID: String = "whoprovidethiskeybind"
|
||||
const val FriendlyModID = "WhoProvideThisKeybind"
|
||||
val ClientLogger = LoggerFactory.getLogger(FriendlyModID)
|
||||
|
||||
override fun onInitializeClient() {
|
||||
RegisterClientLifecycleEvents() } }
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"required": false,
|
||||
"package": "xyz.thewhitedog9487.client.mixin.Compatibility.Controlling",
|
||||
"compatibilityLevel": "JAVA_25",
|
||||
"plugin": "xyz.thewhitedog9487.client.mixin.Compatibility.Controlling.MixinPlugin",
|
||||
"client": [
|
||||
"NewKeyBindsListMixin" ],
|
||||
"injectors": {
|
||||
"defaultRequire": 0 }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "xyz.thewhitedog9487.client.mixin",
|
||||
"compatibilityLevel": "JAVA_25",
|
||||
"client": [
|
||||
"KeyBindsListKeyEntryMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"overwrites": {
|
||||
"requireAnnotations": true
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"modmenu.nameTranslation.whoprovidethiskeybind": "Who Provides This Keybind?",
|
||||
"modmenu.descriptionTranslation.whoprovidethiskeybind": "Adds hover information on keybind change buttons in the keybinding settings screen to show which mod provides the keybind\nTip: If you need to use the config menu, install the YetAnotherConfigLib mod",
|
||||
"link.bilibili": "Bilibili Homepage",
|
||||
"link.blog": "TheWhiteDog9487's Blog",
|
||||
"title.config": "Who Provides This Keybind?",
|
||||
"config.category.general": "General",
|
||||
"option.ModEnabled": "Enable Mod Functionality",
|
||||
"option.ModEnabled.description": "Changes take effect immediately after modification and save without restarting the game",
|
||||
"option.ShowModID": "Show Mod ID",
|
||||
"option.ShowModID.description": "Display the Mod ID of the provider in the tooltip",
|
||||
"option.ShowKeybindID": "Show Keybind ID",
|
||||
"option.ShowKeybindID.description": "Display the keybind's own ID in the tooltip",
|
||||
"option.ShowDebugInfo": "Show Debug Info",
|
||||
"option.ShowDebugInfo.description": "This information is used to troubleshoot issues related to this mod; it generally does not need to be enabled",
|
||||
"tooltip.provided_by": "Provided by: %s",
|
||||
"tooltip.provider_mod_id": "Provider Mod ID: %s",
|
||||
"tooltip.key_id": "Keybind ID: %s",
|
||||
"special_provider_UNKNOWN": "Unknown"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"modmenu.nameTranslation.whoprovidethiskeybind": "谁在提供这个键位?",
|
||||
"modmenu.descriptionTranslation.whoprovidethiskeybind": "在按键绑定设置界面的键位更改按钮上添加鼠标悬停信息,显示该按键绑定是由哪个Mod提供的\n提示:如果需要使用配置菜单,请安装YetAnotherConfigLib模组",
|
||||
"link.bilibili": "哔哩哔哩主页",
|
||||
"link.blog": "TheWhiteDog9487的博客",
|
||||
"title.config": "谁在提供这个键位?",
|
||||
"config.category.general": "通用",
|
||||
"option.ModEnabled": "是否启用模组功能",
|
||||
"option.ModEnabled.description": "无需重启游戏,修改并保存后立刻生效",
|
||||
"option.ShowModID": "是否显示Mod ID",
|
||||
"option.ShowModID.description": "在提示信息中显示提供该按键的Mod的ID",
|
||||
"option.ShowKeybindID": "是否显示键位ID",
|
||||
"option.ShowKeybindID.description": "在提示信息中显示该按键本身的ID",
|
||||
"option.ShowDebugInfo": "是否显示调试信息",
|
||||
"option.ShowDebugInfo.description": "这些信息用于出现和本Mod相关的问题时进行排查,一般情况下不需要开启",
|
||||
"tooltip.provided_by": "提供者:%s",
|
||||
"tooltip.provider_mod_id": "提供者ID:%s",
|
||||
"tooltip.key_id": "键位ID:%s",
|
||||
"special_provider_UNKNOWN": "未知"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "whoprovidethiskeybind",
|
||||
"version": "${version}",
|
||||
"name": "Who Provide This Keybind?",
|
||||
"description": "Shows which mod provides each key binding via a tooltip on the keybinds screen.",
|
||||
"authors": [
|
||||
"TheWhiteDog9487" ],
|
||||
"contact": {
|
||||
"homepage": "https://modrinth.com/project/who-provide-this-keybind",
|
||||
"sources": "https://github.com/TheWhiteDog9487/WhoProvideThisKeybind",
|
||||
"issues": "https://github.com/TheWhiteDog9487/WhoProvideThisKeybind/issues" },
|
||||
"license": "WTFPL",
|
||||
"icon": "assets/whoprovidethiskeybind/icon.png",
|
||||
"environment": "client",
|
||||
"entrypoints": {
|
||||
"client": [ {
|
||||
"value": "xyz.thewhitedog9487.client.WhoProvideThisKeybindModClient",
|
||||
"adapter": "kotlin" } ],
|
||||
"modmenu": [ "xyz.thewhitedog9487.client.ModMenuEntryPoint" ] },
|
||||
"mixins": [ {
|
||||
"config": "whoprovidethiskeybind.client.mixins.json",
|
||||
"environment": "client" }, {
|
||||
"config": "CompatibilityMixinConfig/controlling.mixins.json",
|
||||
"environment": "client" } ],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.19.5",
|
||||
"minecraft": "~26.2",
|
||||
"java": ">=25",
|
||||
"fabric-api": ">=0.159.0",
|
||||
"fabric-language-kotlin": ">=1.13.13+kotlin.2.4.10" },
|
||||
"suggests": {
|
||||
"modmenu": "*",
|
||||
"yet_another_config_lib_v3": "*" },
|
||||
"accessWidener": "whoprovidethiskeybind.classtweaker" ,
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"links": {
|
||||
"link.bilibili": "https://space.bilibili.com/401746666",
|
||||
"link.blog": "https://www.thewhitedog9487.xyz"},
|
||||
"update_checker": true } } }
|
||||
@@ -0,0 +1,4 @@
|
||||
classTweaker v1 official
|
||||
|
||||
accessible field net/minecraft/client/gui/components/AbstractWidget tooltip Lnet/minecraft/client/gui/components/WidgetTooltipHolder;
|
||||
accessible field net/minecraft/client/gui/components/Tooltip message Lnet/minecraft/network/chat/Component;
|
||||
Reference in New Issue
Block a user