前言
ClassFilter是kjs的一个保护机制,笔者在这里不建议进行对ClassFilter动手脚
此篇仅以替换kjs的ClassFilter为例子讲解部分java的反射机制在kjs的使用
本文使用:CC-BY-NC-SA 4.0协议
话不多说,先上成品
这是在kjs里面使用反射爆破kjs的classfilter的实例
let $ClassFilter = Java.loadClass("dev.latvian.mods.kubejs.util.ClassFilter")
let $ServerScriptManager = Java.loadClass("dev.latvian.mods.kubejs.server.ServerScriptManager")
let $KubeJS = Java.loadClass("dev.latvian.mods.kubejs.KubeJS")
let ScriptManagers = {
CLIENT: $KubeJS.getClientScriptManager(),
SERVER: $ServerScriptManager.instance,
STARTUP: $KubeJS.getStartupScriptManager(),
}
/**@type {Internal.Class<$JavaWrapper_>} */
let clazz = Java.class
/**@type {Internal.Class<$ScriptManager_>} */
let $ScriptManager = clazz.getClassLoader().loadClass("dev.latvian.mods.kubejs.script.ScriptManager")
let classFilterField = $ScriptManager.getDeclaredField('classFilter')
classFilterField.setAccessible(true)
classFilterField.set(ScriptManagers.SERVER, new $ClassFilter())
下面进行解析
let $ClassFilter = Java.loadClass("dev.latvian.mods.kubejs.util.ClassFilter")
这一步是为获取新的ClassFilter以获取实例以替换已经完成的构建的ClassFilter
let $ServerScriptManager = Java.loadClass("dev.latvian.mods.kubejs.server.ServerScriptManager")
let $KubeJS = Java.loadClass("dev.latvian.mods.kubejs.KubeJS")
let ScriptManagers = {
CLIENT: $KubeJS.getClientScriptManager(),
SERVER: $ServerScriptManager.instance,
STARTUP: $KubeJS.getStartupScriptManager(),
}
在这步获取了全部的ScriptManager
let clazz = Java.class
这一步获取了Class<JavaWrapper>实例,在后面用于获取类加载器去加载我们需要的类
let $ScriptManager = clazz.getClassLoader().loadClass("dev.latvian.mods.kubejs.script.ScriptManager")
获取Class<ScriptManager>
let classFilterField = $ScriptManager.getDeclaredField('classFilter')
获取Class<ScriptManager>的classFilter字段(这是我们需要修改的地方)
classFilterField.setAccessible(true)
因为classFilter字段是私有的,我们需要开放他的权限
classFilterField.set(ScriptManagers.SERVER, new $ClassFilter())
将set方法的第一个参数的classFilter字符替换为我们的新ClassFilter
(此处仅替换了server的,有其他的需要替换就修改第一个参数)
至此,kjs的classfilter就被我们优雅(雾)的处理掉了