跳转至内容

[原创][KubeJS 7][BrokenClassFilter]关于Nashorn在kjs中的应用

妙妙工具
3 3 190 1
  • 前言
    ClassFilter是kjs的一个保护机制,笔者在这里不建议进行对ClassFilter动手脚
    此篇仅以替换kjs的ClassFilter为例子展示Nashorn在kjs的使用
    本文使用:CC-BY-NC-SA 4.0协议

    因为1.21.1的kubejs ban了反射,因此只能在nashorn里面进行操作
    Nashorn比较复杂,这次就仅展示成品

    let $KubeJS = Java.loadClass("dev.latvian.mods.kubejs.KubeJS")
    
    let $ServerLifecycleHooks = Java.loadClass("net.neoforged.neoforge.server.ServerLifecycleHooks")
    /**@type {$MinecraftServer_} */
    let Server = $ServerLifecycleHooks.getCurrentServer()
    //所有的scriptmanager获取
    let ServerScriptMagager = Server.getServerResources().managers().kjs$getServerScriptManager()
    let ClientScriptMagager = $KubeJS.getClientScriptManager()
    let StartupScriptMagager = $KubeJS.getStartupScriptManager()
    
    
    
    let $ScriptEngineManager = Java.loadClass("javax.script.ScriptEngineManager")
    let Nashorn = new $ScriptEngineManager().getEngineFactories()[0].getScriptEngine()
    
    
    Nashorn.eval(`
      var Clazz = Java.type("java.lang.Class")
      var ClassFilter = Java.type("dev.latvian.mods.kubejs.plugin.ClassFilter")
      var HashSet = Java.type("java.util.HashSet")
      var ArrayList = Java.type("java.util.ArrayList")
    
      var ScriptManager$Clazz = Clazz.forName("dev.latvian.mods.kubejs.script.ScriptManager")
      var ScriptManager$classFilter$Field = ScriptManager$Clazz.getDeclaredField("classFilter")
    
      var ClassFilter$Clazz = Clazz.forName("dev.latvian.mods.kubejs.plugin.ClassFilter")
      var ClassFilter$denyStrong$Field = ClassFilter$Clazz.getDeclaredField("denyStrong")
      var ClassFilter$denyWeak$Field = ClassFilter$Clazz.getDeclaredField("denyWeak")
      
      ScriptManager$classFilter$Field.setAccessible(true)
      ClassFilter$denyStrong$Field.setAccessible(true)
      ClassFilter$denyWeak$Field.setAccessible(true)
    
      var unlock=function(ScriptMagager){
        var ClassFilter = ScriptManager$classFilter$Field.get(ScriptMagager)
        ClassFilter$denyStrong$Field.set(ClassFilter,new HashSet())
        ClassFilter$denyWeak$Field.set(ClassFilter,new ArrayList())
      }
    `)
    //参数传入scriptmanager即可爆破classfilter
    Nashorn.invokeFunction("unlock",ServerScriptMagager)
    let $File = Java.loadClass("java.io.File")
    
  • 要长脑子了😇

  • 补药在1.21.1偷走我的钱包😭


相关推荐


  • [原创][KubeJS 6] 物品投射实现飞剑

    灵感大王 kubejs entityjs
    2
    3 赞同
    2 帖子
    110 浏览
    不是客服M
    cool
  • [原创][Mod]通过特定格式文字进行查找结构

    妙妙工具 forge mixin
    1
    0 赞同
    1 帖子
    76 浏览
    昨天没做东西,今天也没K
    故事的起因是有帮twf写模组时,需要用到查找结构指令显示坐标给玩家,但是玩家不一定有权限或者ftbq发送并不会sendmessage给玩家,所以有了此代码。 我也将结构查找的功能写成了一个类,可以直接拿去用。 public class StructureLocator { private static final ResourceKey<Registry<ConfiguredStructureFeature<?, ?>>> STRUCTURE_REGISTRY_KEY = Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY; /** * 根据单个结构 ResourceLocation(如 "minecraft:village" 或者自定义 mod:id)查找最近的那个点。 * * @param level 当前维度 * @param center 中心搜索点 * @param id 结构的 ResourceLocation * @param radius 搜索半径(方块数) * @param skipKnown 是否跳过已探索过的结构 * @return 如果找到,返回 Pair(结构坐标, Holder<该结构>); 找不到则 empty() */ public static Optional<Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>>> findNearest( ServerLevel level, BlockPos center, ResourceLocation id, int radius, boolean skipKnown ) { Registry<ConfiguredStructureFeature<?, ?>> registry = level.registryAccess().registryOrThrow(STRUCTURE_REGISTRY_KEY); ResourceKey<ConfiguredStructureFeature<?, ?>> key = ResourceKey.create(STRUCTURE_REGISTRY_KEY, id); Holder<ConfiguredStructureFeature<?, ?>> holder = registry.getHolder(key).orElse(null); if (holder == null) return Optional.empty(); HolderSet<ConfiguredStructureFeature<?, ?>> holderSet = HolderSet.direct(holder); Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> result = level.getChunkSource() .getGenerator() .findNearestMapFeature(level, holderSet, center, radius, skipKnown); return Optional.ofNullable(result); } /** * 根据 TagKey(像 "#minecraft:village")来查找最近的结构。 * * @param level 当前维度 * @param center 中心搜索点 * @param tagKey 结构 TagKey(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY 下的 Tag) * @param radius 搜索半径 * @param skipKnown 是否跳过已探索结构 * @return 如果找到,返回 Pair(结构坐标, Holder<该结构>); 找不到则 empty() */ public static Optional<Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>>> findNearestByTag( ServerLevel level, BlockPos center, TagKey<ConfiguredStructureFeature<?, ?>> tagKey, int radius, boolean skipKnown ) { Registry<ConfiguredStructureFeature<?, ?>> registry = level.registryAccess().registryOrThrow(STRUCTURE_REGISTRY_KEY); HolderSet<ConfiguredStructureFeature<?, ?>> holderSet = registry.getOrCreateTag(tagKey); Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> result = level.getChunkSource() .getGenerator() .findNearestMapFeature(level, holderSet, center, radius, skipKnown); return Optional.ofNullable(result); } /** * 把查到的结果格式化成一个聊天用的组件(绿色坐标 + 距离)。 * * @param structureName 你想显示的结构名称(如 "minecraft:village" 或 "#minecraft:village") * @param origin 搜索中心 * @param pair findNearest 返回的 Pair * @param translateKey 翻译 key,通常用 "commands.locate.success" */ public static Component formatLocateResult( String structureName, BlockPos origin, Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> pair, String translateKey ) { BlockPos found = pair.getFirst(); int distance = Mth.floor( dist(origin.getX(), origin.getZ(), found.getX(), found.getZ()) ); MutableComponent coords = ComponentUtils.wrapInSquareBrackets( new TranslatableComponent("chat.coordinates", found.getX(), "~", found.getZ()) ); return new TranslatableComponent( translateKey, structureName, coords, distance ); } private static float dist(int x1, int z1, int x2, int z2) { int dx = x2 - x1, dz = z2 - z1; return Mth.sqrt((float) (dx * dx + dz * dz)); } } 这部分代码就是查找结构有关的类了,通过获取ConfiguredStructureFeature的注册表,然后再获取结构的Holder类,再给ChunkGenerator的findNearestMapFeature方法去获取到BlockPos。 @Mixin(ServerPlayer.class) public class ServerPlayerMixin { @ModifyArg(method = "sendMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundChatPacket;<init>(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), index = 0) public Component modifyMessage(Component component){ MutableComponent mutableComponent = component.copy(); String message = mutableComponent.getString(); ServerPlayer serverPlayer = (ServerPlayer) (Object) this; if (message.contains("<structure>") && message.contains("</structure>")) { String structure = message.replaceAll(".*<structure>(.*?)</structure>.*", "$1"); BlockPos center = serverPlayer.blockPosition(); Optional<Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>>> holderPair = StructureLocator.findNearest( serverPlayer.getLevel(), center, new ResourceLocation(structure), 100, false ); AtomicReference<String> replace = new AtomicReference<>(); holderPair.ifPresentOrElse(pair -> { Component component1 = StructureLocator.formatLocateResult(structure, center, pair, "commands.locate.success"); replace.set(component1.getString()); }, () -> { replace.set(new TranslatableComponent("commands.locate.failed", structure).getString()); }); Style style = component.getStyle(); mutableComponent = new TextComponent(message.replaceAll("<structure>(.*?)</structure>", "§a%s§r".formatted(replace.get()))).withStyle(style); } return mutableComponent; } } 这段mixin则是注入ServerPlayer的sendMessage方法,修改new ClientboundChatPacket(message, type, sender)的message参数,||因为我偷懒,所以没用MixinExtra||,用正则表达式进行匹配到对应的结构格式文字,然后修改原文字中的内容。 这差不多都就是本次代码的全部内容了。
  • [原创][Mod]基于opengl取色的hsv色盘屏幕

    妙妙工具 渲染
    5
    0 赞同
    5 帖子
    113 浏览
    不是客服M
    没有教程的话,哇达西?