Java 特定 class 的热代码替换失败

Java hot code replace failed for specific class

我正在为我的 mod 开发 GUI,但是当我保存它时,eclipse 会显示一个对话框,上面写着 ... Reason: Hot code replace failed - Scheme change not implemented.

发生了几件奇怪的事情:

package com.thecodewarrior.guides.gui;

import java.nio.DoubleBuffer;
import java.util.Stack;

import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiLabel;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;

import org.apache.logging.log4j.Logger;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;

import com.thecodewarrior.guides.GuideMod;
import com.thecodewarrior.guides.Reference;
import com.thecodewarrior.guides.api.GuideGenerator;
import com.thecodewarrior.guides.api.GuideRegistry;
import com.thecodewarrior.guides.views.View;

import cpw.mods.fml.client.config.GuiButtonExt;

public class GuiBookOfRevealing extends GuiScreen {
    public static final Logger l = GuideMod.logChild("GUI");

    public static final int GUI_ID = 100;

    public static final ResourceLocation texture = new ResourceLocation(Reference.MODID, "textures/gui/book_of_revealing_gui.png");
    //public GuiContainerBookOfRevealing container;

    public static final String seperator = "\u0380";// some random unused code point with size=0 in glyph_sizes.bin

    public static final int guiWidth  = 254;
    public static final int guiHeight = 214;

    public static final int viewWidth = 250;
    public static final int viewHeight = 190;

    public static final int viewTopOffset  = 12;
    public static final int viewLeftOffset = 2;

    public Stack<View> viewHistory = new Stack<View>();

    public int top;
    public int left;
    public int viewTop;
    public int viewLeft;

    private boolean needsRefresh;

    private int mouseX;

    private int mouseY;

    private View view;

    private GuiButtonExt backButton;
    private GuiButtonExt reloadButton;

    private GuideGenerator guideGen;

    private int viewIndex;

    public GuiBookOfRevealing(EntityPlayer player, World w, int x, int y, int z) {
        super();
        this.init();
        this.refreshGuide(w,x,y,z);
        this.refreshView();
    }

    public GuiBookOfRevealing(EntityPlayer player, ItemStack stack) {
        super();
        this.init();
        this.refreshGuide(stack);
    }

    public GuiBookOfRevealing(EntityPlayer player) {
        super();
        this.init();
        this.refreshView();
    }

    protected void init() {

        this.refreshGuide(GuideRegistry.NULL_GUIDE);
    }

    public void refreshTopLeft() {
        left = (width - guiWidth)  / 2;
        top  = (height - guiHeight) / 2;
        viewTop  = top  + viewTopOffset;
        viewLeft = left + viewLeftOffset;
    }

    public void back() {
        this.view = this.viewHistory.pop();
        if(this.viewHistory.size() == 0) {
            this.backButton.enabled = false;
        }
    }

    public void refreshView() {
        if(this.needsRefresh) {
            if(this.view != null) {
                this.viewHistory.add(this.view);
                this.backButton.enabled = true;
            }
            this.view = this.guideGen.generate(viewWidth, viewHeight, this);
            this.needsRefresh = false;
        }
    }

    public void handleMouseInput() {
        super.handleMouseInput();

        int wheel = Mouse.getDWheel();

        if(this.view != null) {
            this.view.scroll(wheel);
        }
    }

    protected void mouseClicked(int x, int y, int button)
    {
        super.mouseClicked(x,y,button);
        refreshTopLeft();

        if(this.view == null) { return; }
        this.view.onClick(x-(left+5), y-(top+5), button);

        /* minecraft button code */
        if (button == 0)
        {
            for (int l = 0; l < this.view.buttonList.size(); ++l)
            {
                GuiButton guibutton = (GuiButton)this.view.buttonList.get(l);

                if (guibutton.mousePressed(this.mc, x-viewLeft, y-viewTop))
                {
                    this.view.selectedButton = guibutton;
                    guibutton.func_146113_a(this.mc.getSoundHandler());
                    this.view.actionPerformed(guibutton);
                }
            }
        }
    }

    protected void mouseMovedOrUp(int x, int y, int button) {
        super.mouseMovedOrUp(x, y, button);
        refreshTopLeft();

        if(this.view == null) { return; }

        if (this.view.selectedButton != null && button == 0)
        {
            this.view.selectedButton.mouseReleased(x-viewLeft, y-viewTop);
            this.view.selectedButton = null;
        }
    }

    public void refreshGuide() {
        this.needsRefresh = true;
    }

    private void refreshGuide(World w, int x, int y, int z) {
        GuideGenerator guide = GuideRegistry.findBlockGuide(w, x, y, z);
        GuideGenerator otherGuide = GuideRegistry.findGuideFor(w, x, y, z);
        refreshGuide(otherGuide);
    }

    public void refreshGuide(ItemStack stack) {
        GuideGenerator guide = null;
        if(stack == null) {
            refreshGuide(GuideRegistry.NULL_GUIDE);
            return;
        }
        guide = GuideRegistry.findGuideFor(stack);
        refreshGuide(guide);
    }

    public void refreshGuide(GuideGenerator gen) {
        this.guideGen = gen;
        refreshGuide();
    }

    public void initGui() {
        super.initGui();
        refreshTopLeft();

        this.backButton = new GuiButtonExt(1, left+215, top+124, 40, 20, "Back");
        this.backButton.enabled = false;
        //this.buttonList.add(this.backButton);

        this.reloadButton = new GuiButtonExt(1, left+215, top+144, 40, 20, "Reload");
        //this.buttonList.add(this.reloadButton);
    }


    protected void actionPerformed(GuiButton guibutton) {
        //id is the id you give your button
        switch(guibutton.id) {
        case 1:
            this.back();
        case 2:
            GuideRegistry.wipeGuideRegistry();
            GuideMod.proxy.loadGuidePacks();
        }
    }


//********************************DRAWING CODE**********************************



    protected void drawButtons(int mX, int mY) {

    }

    public void drawIcon(int x, int y, IIcon i)
    {
        drawIconWH(x, y, i, i.getIconWidth(), i.getIconHeight());
    }

    public void drawIconW(int x, int y, IIcon i, int w)
    {
        drawIconWH(x, y, i, w, i.getIconHeight());
    }
    public void drawIconH(int x, int y, IIcon i, int h)
    {
        drawIconWH(x, y, i, i.getIconWidth(), h);
    }

    // just for ease of use
    public void drawIconWH(int x, int y, IIcon i, int w, int h)
    {
        drawTexturedModelRectFromIcon(x, y, i, w, h);
    }

    static final int rollHeight = 10;
    static final int ribbonHeight = 11;

    static final BasicIconFactory f = new BasicIconFactory(256, null);

    static final BasicIcon  page                = f.create(0, 0, guiWidth, guiHeight);

    static final BasicIcon  rollTop             = f.create(0, guiHeight, guiWidth + 2, rollHeight);
    static final BasicIcon  rollBottom          = f.create(0, guiHeight + rollHeight, guiWidth + 2, rollHeight);

    static final BasicIcon  detailsButton       = f.create(0, guiHeight + (rollHeight*2), 26, ribbonHeight);
    static final BasicIcon  browseButton        = f.create(26, guiHeight + (rollHeight*2), 26, ribbonHeight);
    static final BasicIcon  settingsButton      = f.create(26 * 2, guiHeight + (rollHeight*2), 26, ribbonHeight);

    static final BasicIcon  addBookmark         = f.create(0, 0, guiWidth, guiHeight);
    static final BasicIcon  bookmarkFadeTop     = f.create(0, 0, guiWidth, guiHeight);
    static final BasicIcon  bookmarkFadeBottom  = f.create(0, 0, guiWidth, guiHeight);
    static final BasicIcon  bookmark            = f.create(0, 0, guiWidth, guiHeight);
    static final BasicIcon  bookmarkScroll      = f.create(0, 0, guiWidth, guiHeight);

    static final BasicIcon  searchLeft          = f.create(0, 0, guiWidth, guiHeight);
    static final BasicIcon  searchMiddle        = f.create(0, 0, guiWidth, guiHeight);
    static final BasicIcon  searchRight         = f.create(0, 0, guiWidth, guiHeight);

    public void drawScreen(int mX, int mY, float par3)
    {
        super.drawScreen(mX, mY, par3);
        this.drawButtons(mX, mY);

        refreshTopLeft();

        this.mouseX = mX;
        this.mouseY = mY;

        if(this.needsRefresh) {
            this.refreshView();
        }
        left = left+50;
        top  = top+30;

        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        mc.renderEngine.bindTexture(texture);


        drawIcon(left, top, page); /* main page */
        drawIcon(left, top, rollTop); /* top wrap */
        drawIcon(left-2, top+guiHeight-rollHeight, rollBottom); /* bottom wrap */

        drawLeftSideButtons();

        if(this.view != null) {
            // Draw the background

            int topClip = viewTop;
            int bottomClip = viewTop+viewHeight;

            double[] topMask = new double[4];
            topMask[1] = 1; // it's masking outside the +Y axis 
            topMask[3] = -topClip;
            DoubleBuffer buf = BufferUtils.createDoubleBuffer(4);
            buf.put(topMask);
            buf.flip();
            GL11.glClipPlane(GL11.GL_CLIP_PLANE0, buf);
            GL11.glEnable(GL11.GL_CLIP_PLANE0);

            double[] bottomMask = new double[4];
            bottomMask[1] = -1; // it's masking outside the -Y axis
            bottomMask[3] = bottomClip; // 
            buf = BufferUtils.createDoubleBuffer(4);
            buf.put(bottomMask);
            buf.flip();
            GL11.glClipPlane(GL11.GL_CLIP_PLANE1, buf);
            GL11.glEnable(GL11.GL_CLIP_PLANE1);


            GL11.glTranslated(viewLeft, viewTop, 0);
            this.view.draw(mouseX-viewLeft, mouseY-viewTop);
            GL11.glTranslated(-viewLeft, -viewTop, 0);

            // disable the clip to draw anything else.
            GL11.glDisable(GL11.GL_CLIP_PLANE0);
            GL11.glDisable(GL11.GL_CLIP_PLANE1);

        }

    }

    private void drawLeftSideButtons() {

    }

}

从我的 mods 文件夹中取出 CodeChickenCore 修复了它,我认为 CCC 正在做某种转换并在运行时更改我的 class,当我尝试更新它时新的 class 字节码没有应用转换,所以它们不匹配并且失败了。