更改另一个java文件中定义的最终变量

时间:2015-04-08 19:43:42

标签: java minecraft

我正在编程mod。

以下是代码:

package net.minecraft.client.gui;

import java.io.IOException;

import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;

public class GuiButton extends Gui {
    public static final ResourceLocation buttonTextures = new ResourceLocation("textures/gui/widgets.png");

如您所见,变量buttonTextures及其资源位置为“textures / gui / widgets.png”。我还有第二个,我想要做的是在执行时用第二个Java文件更改buttonTextures
我只需要将buttonTextures的资源位置更改为我自己的路径,但需要更改其他Java文件。也许可以通过用第二个脚本重写代码来完成,我真的不知道。

我在做什么: 一个PAYDAY 2 Mod for Minecraft。当然,我从菜单开始。所以我有两个主菜单。要切换到我的菜单,您需要按一个按钮。当你这样做时,它会改变它的纹理。但问题是,它无法将按钮纹理更改为 textures / gui / PAYDAY2widgets.png ,因为该变量为final

如您所见,第一个文件名为GuiButton。 我制作了该文件的副本,称为GuiPAYDAY2Button.java,并设置路径到纹理的路径( textures / gui / PAYDAY2widgets.png )。
现在,如果我将其添加到| (我将变量从GuiButton更改为GuiPAYDAY2Button,但在切换到 PAYDAY2 菜单后游戏崩溃了GuiPAYDAY2MainMenu.java文件(GuiMainMenu.java文件的副本)。 我还将GuiButton更改为GuiPAYDAY2Button(在GuiPAYDAY2MainMenu.java文件中),因此它会定向到该文件。 当我在谈论崩溃时,这是崩溃报告:

---- Minecraft Crash Report ---- // I feel sad now :(

Time: 8.4.15 21:58 Description: Rendering screen

java.lang.ClassCastException: net.minecraft.client.gui.GuiPAYDAY2Button cannot be cast to net.minecraft.client.gui.GuiButton
    at net.minecraft.client.gui.GuiScreen.drawScreen(GuiScreen.java:99)
    at net.minecraft.client.gui.GuiPAYDAY2MainMenu.drawScreen(GuiPAYDAY2MainMenu.java:453)
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1167)
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1127)
    at net.minecraft.client.Minecraft.run(Minecraft.java:410)
    at net.minecraft.client.main.Main.main(Main.java:114)
    at Start.main(Start.java:11)

错误,代码路径和所有已知详细信息的详细演练如下:

-- Head --
Stacktrace:
    at net.minecraft.client.gui.GuiScreen.drawScreen(GuiScreen.java:99)
    at net.minecraft.client.gui.GuiPAYDAY2MainMenu.drawScreen(GuiPAYDAY2MainMenu.java:453)

-- Screen render details --
Details:
    Screen name: net.minecraft.client.gui.GuiPAYDAY2MainMenu
    Mouse location: Scaled: (202, 11). Absolute: (405, 456)
    Screen size: Scaled: (427, 240). Absolute: (854, 480). Scale factor of 2
    Stacktrace:
        at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1167)
        at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1127)
        at net.minecraft.client.Minecraft.run(Minecraft.java:410)
        at net.minecraft.client.main.Main.main(Main.java:114)
        at Start.main(Start.java:11)

-- System Details --
Details:
    Minecraft Version: 1.8
    Operating System: Windows 7 (amd64) version 6.1
    Java Version: 1.8.0_31, Oracle Corporation
    Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
    Memory: 707532608 bytes (674 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
    JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
    IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
    Launched Version: mcp
    LWJGL: 2.9.1
    OpenGL: GeForce GTX 460 v2/PCIe/SSE2 GL version 4.5.0 NVIDIA 347.25, NVIDIA Corporation
    GL Caps: Using GL 1.3 multitexturing. Using GL 1.3 texture combiners. Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported. Shaders are available because OpenGL 2.1 is supported. VBOs are available because OpenGL 1.5 is supported.
    Using VBOs: No
    Is Modded: Very likely; Jar signature invalidated
    Type: Client (map_client.txt)
    Resource Packs: []
    Current Language: English (US)
    Profiler Position: N/A (disabled)

更新

我几个小时前制作了一个视频,这是对这个mod的展示。也许你会明白我想要的......:https://www.youtube.com/watch?v=ocHT7LdNBYY

好的,我使扩展脚本看起来像这样:

package net.minecraft.client.gui; 
import net.minecraft.util.ResourceLocation; 

public class GuiButtonTexureChange extends GuiButton { 
    public static ResourceLocation buttonTextures = new ResourceLocation("textures/gui/PAYDAY2widgets.png");

    // Now this part is needed to be here (otherwise it throws errors):
    public GuiButtonTexureChange(int buttonId, int x, int y, int widthIn, int heightIn, String buttonText) { 
        super(buttonId, x, y, widthIn, heightIn, buttonText); // TODO Auto-generated constructor stub
    } 
}

2 个答案:

答案 0 :(得分:0)

如果您无法修改某些Java代码(例如它是库的一部分),您仍然可以覆盖您喜欢的任何Java类。

创建另一个源文件夹(在这里以Eclipse的形式发言),并在其中包含您要编辑的类的确切包和文件。在你的情况下,它应该是包 net.minecraft.client.gui 和文件 GuiButton.java

现在,如果您自己的文件在classpath中排在第一位,那么您已成功覆盖了一个类。该库的所有其他代码仍然可以像以前一样工作。

在使用Eclipse时,要确保自己的代码在类路径中排在第一位: 项目属性 - > Java构建路径 - >订单和出口

将GuiButton的现有代码复制到您自己的文件中以获得相同的起点可能是明智之举,然后对代码进行修改。

答案 1 :(得分:-1)

根据您的安全管理器设置,您可以通过反射在运行时更改路径字符串。

示例:

static void setFinalStatic(final Field field, final Object instance, final Object newValue) throws Exception {
      field.setAccessible(true);

      final Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL & ~Modifier.PRIVATE);
      field.set(instance, newValue);
}

public final static void main(String[] args) throws Exception {
      String path = "initialPath";
      final char[] after = "sneakyPath".toCharArray();
      setFinalStatic(path.getClass().getDeclaredField("value"), path, after);
      setFinalStatic(path.getClass().getDeclaredField("offset"), path, 0);
      setFinalStatic(path.getClass().getDeclaredField("count"), path, after.length);

      System.out.println(path);
}