3

问题是什么? 我是一名 Minecraft 服务器管理员/服务器主机/插件开发人员,但发现在核心游戏的每个新版本上都必须更新我自己的个人插件是一件绝对的烦恼。并非总是这样,过去我已经让插件跨 20 个版本工作而没有中断。可以想象,每个月必须坐下来更新 40 个插件是我生活中不必要的烦恼,因为我过去从未这样做过。

是什么导致了这个问题? 在每个新版本中,它们都要求您在编译的 jar 文件中使用不同的导入,从而强制破坏任何过时(但可能仍在工作)的 jar 文件。相信我。我可以阅读错误日志并知道何时需要实际下载新更新。我现在不需要保护自己。这只是一个游戏,我没有太多的兴趣。

那么我想怎么做呢? 为此,我想制作一个简单的程序来自动更新我所有的插件。(插件以打包的 .jar 文件的形式出现。)它需要执行以下操作:

  1. 获取 X_Folder 中所有 jar 文件的列表
  2. 对于每个 jar 文件,将所有类都封装起来。
  3. 对于每个类文件,搜索 Y_STRING 的任何实例并将其替换为 Z_STRING。
  4. 确保所有内容都正确放回 jar 文件中。
  5. 完毕。

问题? 我将如何编写类文件编辑方法?我什至不知道如何开始。

免责声明 很抱歉听起来我还没有开始研究这个。我只是,没有任何字节码操作的经验。我看过一些例子,但还没有看到任何关于重命名导入的内容。希望这里有人可以帮助我。谢谢!

4

2 回答 2

3
  1. 获取 X_Folder 中所有 jar 文件的列表
  2. 对于每个 jar 文件,将所有类都封装起来。
  3. 对于每个类文件,搜索 Y_STRING 的任何实例并将其替换为 Z_STRING。
  4. 确保所有内容都正确放回 jar 文件中。
  5. 完毕。

1)这是基本的文件操作。查看java.io.File#listFiles()或其重载。

2) JAR 文件是具有特定内容的 ZIP 文件。查看java.util.jar.JarFilejava.util.zip.ZipInputStream;遍历其条目 ( JarFile#entries()) 并解压缩 ( ) 中的每个类文件JarFile#getInputStream(ZipEntry)

3) 类文件是二进制格式,但它的文档非常好。一般布局记录在维基百科上:http ://en.wikipedia.org/wiki/Java_class_file#General_layout

特别感兴趣的是常量池,它从类文件的第 10 个字节开始,枚举类文件中引用的所有常量。它再次记录在 Wikipedia 上:http ://en.wikipedia.org/wiki/Java_class_file#The_constant_pool 。它的条目数存储在字节 8 和 9(大端)中。

常量池中特别感兴趣的是字符串和类引用。

字符串由第一个字节标识1。接下来的两个字节是字符串的字节长度,剩下的字节是 UTF-8(几乎)。与 UTF-8 不同,更高的平面存储为代理对(6 个字节而不是 4 个),并且代码点 0 被非规范化存储。

类引用只不过是指向常量池的指针,指向类的完全限定名。完全限定名称使用正斜杠而不是点来存储,以分隔完全限定名称 ( java/lang/Object)。它被标记为类型 7。

常量池中的其他条目:类型 3,4,9-12 是四字节,类型 7 和 8 是两字节。类型 5 和 6 是 8 字节,但它们也占用常量池中的两个插槽。

如果常量池的字节长度发生变化,类文件的其余部分似乎并不介意。在常量池末尾添加条目似乎也很安全(确保更新常量池长度)。

4) 由于 jar 文件只是一个 zip 文件,因此您只需将原始文件与更新后的内容重新打包即可。我不希望这可以就地实现,因此您可能需要一些文件改组。研究java.util.zip.ZipOutputStream实施。

于 2012-12-30T20:48:06.390 回答
1

我可以反编译他们的插件,将它们加载到 IDE 中并手动更新它们,但我希望有一个更全局的解决方案,你知道吗?此外,这是学习 Java 新技能的好机会。

我认为你应该学习的技能是:

  • 构建工具(例如 Ant 或 Maven),允许您从源代码重新构建,将代码加载到 IDE 中,以及

  • 如何使用流编辑器(例如 sed 或 awk)来更新您的源代码或使用宏预处理器(例如 cpp 或 m4)来生成源代码。

但是,鉴于 Minecraft 平台的性质,我不建议将其作为学习 Java/Java 技能的好地方。当然,破解/调整/按摩字节码文件是大多数专业 Java 开发人员通常不需要或使用的技能。

于 2012-12-30T20:15:29.430 回答