1

这很奇怪,该类在退出游戏之前工作正常,但在重新登录时它会发送异常。

这是儿童班

    package com.rs.game.player.quests.impl;

import java.io.Serializable;

import com.rs.game.player.Player;
import com.rs.game.player.dialogues.Dialogue;
import com.rs.game.player.quests.Quest;

/**
 * Handles the cooks assistant quest.
 * 
 * @author Thomas Le Godais <thomaslegodais@live.com>
 *
 */
@SuppressWarnings("serial")
public class CooksAssistant extends Quest<CooksAssistant.Stage, CooksAssistant.Nodes> implements Serializable {

    /**
     * The current nodes of the quest.
     * 
     * @author Thomas Le Godais <thomaslegodais@live.com>
     *
     */
    public enum Nodes {
        /*
         * The chef node.
         */
        CHEF(false);


        /** The interaction value. **/
        private boolean value;

        /**
         * Constructs a new Nodes instance.
         * 
         * @param value the value.
         */
        private Nodes(boolean value) {
            this.value = value;
        }

        /**
         * Gets the value of the node.
         * 
         * @return the value.
         */
        public boolean getValue() {
            return value;
        }

        /**
         * Sets the value of the node.
         * 
         * @param newValue the new value to set.
         */
        public void setValue(boolean newValue) {
            this.value = newValue;
        }
    }

    /**
     * The different stages of the quest.
     * 
     * @author Thomas Le Godais <thomaslegodais@live.com>
     *
     */
    public enum Stage {
        /*
         * Start the quest.
         */
        START,

        /*
         * Gather the ingredients.
         */
        GATHER_INGREDIENTS, 

        /*
         * The talk to chef.
         */
        TALK_TO_CHEF, 

        /*
         * Finish the quest.
         */
        FINISH

    }


    private Player player;

    /**
     * Constructs a new CooksAssistant instance.
     */
    public CooksAssistant(Player player) {
        super("Cooks' Assistant", 1, Stage.START, Nodes.CHEF);
        this.player = player;
    }


    @Override
    public void handleQuest() {
        switch(getQuestState()) {
        case START:
            player.getPackets().sendRunScript(1207, new Object[] { 5 });    
            player.getInterfaceManager().sendInterface(275);

            for(int i = 0; i < 21; i++)
                player.getPackets().sendIComponentText(275, i, "");

            player.getPackets().sendIComponentText(275, 1, this.getName());
            player.getPackets().sendIComponentText(275, 10, "Begin by speaking with the Cook in Lumbridge Castle.");

            player.getPackets().sendIComponentText(275, 12, "Requirments:");
            player.getPackets().sendIComponentText(275, 13, "<str>None.</str>");
            break;

        case GATHER_INGREDIENTS:
            player.getPackets().sendRunScript(1207, new Object[] { 5 });    
            player.getInterfaceManager().sendInterface(275);

            for(int i = 0; i < 21; i++)
                player.getPackets().sendIComponentText(275, i, "");

            player.getPackets().sendIComponentText(275, 1, this.getName());
            player.getPackets().sendIComponentText(275, 10, "You need the following requirements");

            player.getPackets().sendIComponentText(275, 12, "Requirments:");
            player.getPackets().sendIComponentText(275, 13, "Eggs");
            player.getPackets().sendIComponentText(275, 14, "Milk");
            player.getPackets().sendIComponentText(275, 15, "Flour");
            break;

        case TALK_TO_CHEF:

            break;

        case FINISH:

            break;
        }
    }


    @Override
    public void handleDialogue(int npcId) {
        switch(npcId) {
        case 847:
            player.getDialogueManager().startDialogue(new Dialogue() {

                private int npcId;

                @Override
                public void start() {                   
                    npcId = 847;

                    if(hasInteracted(Nodes.CHEF))
                        sendNPCDialogue(npcId, 9827, "Have you gathered my ingredients?.");
                    else
                        sendNPCDialogue(npcId, 9827, "Waahh, what am I to do? I'm so done for!!");
                }

                @Override
                public void run(int interfaceId, int componentId) {
                    if (!(hasInteracted(Nodes.CHEF))) {
                        switch (stage) {
                        case -1:
                            this.sendOptionsDialogue("What would you like?", new String[] { "What's wrong, chef?", "Grow up, you big baby!", "Nevermind, I'll leave you alone." });
                            stage = 0;
                            break;
                        case 0:
                            if (componentId == OPTION_1) {
                                sendPlayerDialogue(9827, "What's wrong, chef?");
                                stage = 1;
                            } else if (componentId == OPTION_2) {
                                sendPlayerDialogue(9827, "Grow up, you big baby!");
                                stage = 15;
                            } else if (componentId == OPTION_3) {
                                sendPlayerDialogue(9827, "Nevermind, I'll leave you alone.");
                                stage = 15;
                            }
                            break;
                            /*
                             * I need some ingredients for the kings birthday cake.
                             */
                        case 1:
                            sendNPCDialogue(npcId, 9827, "I need some ingredients for the kings birthday cake, and I do not have enough time to go get them myself.");
                            stage = 2;
                            break;
                            /*
                             * What do you need?
                             */
                        case 2:
                            sendPlayerDialogue(9827, "Well maybe I could be of assistance, what do you need?");
                            stage = 3;
                            break;
                            /*
                             * I need milk, eggs, and flour.
                             */
                        case 3:
                            sendNPCDialogue(npcId, 9827, "Well I have the frosting, so I guess that just leaves milk, eggs, and flour. Do you think you could help me out, there will be a small reward.");
                            stage = 4;
                            break;
                            /*
                             * That shouldn't be too hard to get.
                             */
                        case 4:
                            sendPlayerDialogue(9827, "That shouldn't be too hard for me to gather, I'll be back in a jiffy!");
                            stage = 5;
                            break;
                            /*
                             * Oh my god, that you so much.
                             */
                        case 5:
                            sendNPCDialogue(npcId, 9827, "Thank you so much, " + player.getUsername() + ", I owe you big time!");
                            setQuestState(Stage.GATHER_INGREDIENTS);
                            for(Nodes node : Nodes.values()) {
                                if(node.equals(Nodes.CHEF)) {
                                    node.setValue(true);
                                    stage = 15;
                                }
                            }
                            break;
                            /*
                             * This is where we end the current dialogue.
                             */
                        case 15:
                            end();
                            break;
                        }
                    } else {
                        switch(stage) {
                        case -1:
                            break;
                        }
                    }
                }

                @Override
                public void finish() {                  
                }
            });
            break;
        }
    }


    @Override
    public void handleObjectClick(int objectId, boolean firstClick, boolean secondClick, boolean thirdClick) {      
        if(firstClick) {
            switch(objectId) {

            }
            return;
        } else if(secondClick) {
            switch(objectId) {

            }
            return;
        } else if(thirdClick) {
            switch(objectId) {

            }
            return;
        }
    }


    @Override
    public boolean hasDialogue() {
        return true;
    }


    @Override
    public boolean hasObjectClick() {
        return false;
    }


    @Override
    public boolean hasInteracted(Nodes node) {
        if(node.getValue() == true)
            return true;
        return false;
    }
    }

这里是家长

    package com.rs.game.player.quests;

/**
 * Represents a single quest of the Rune-Force server.
 * 
 * @author Thomas Le Godais <thomaslegodais@live.com>
 * @param T
 *      An enumeration that is used to handle quest states.
 * @param E
 *      An enumeration that is used to handle interaction.
 */
public abstract class Quest<T extends Enum<T>, E extends Enum<E>> {

    /** The name of the quest. **/
    private String name;

    /** The id of the quest **/
    private int questId;

    /** The state of the quest to handle. **/
    private T questState;

    /** The node interaction. **/
    private E nodeInteraction;

    /**
     * Constructs a new AbstractQuest instance.
     * 
     * @param name The name of the quest.
     * @param questId The id of the quest.
     * @param questState The state of the quest.
     */
    public Quest(String name, int questId, T questState, E nodeInteraction) {
        this.name = name;
        this.questId = questId;
        this.questState = questState;
        this.nodeInteraction = nodeInteraction;
    }

    /**
     * Handles an quest.
     * 
     * @param player The player to handle the quest.
     */
    public abstract void handleQuest();

    /**
     * Handles the dialogue of the quest.
     * 
     * @param player the player interacting with the npc.
     * @param npcId the npc interacting with the player.
     */
    public abstract void handleDialogue(int npcId);

    /**
     * Handles object clicks.
     * 
     * @param player the player clicking objects.
     * @param objectId the object id.
     * @param firstClick the first click.
     * @param secondClick the second click.
     * @param thirdClick the third click.
     */
    public abstract void handleObjectClick(int objectId, boolean firstClick, boolean secondClick, boolean thirdClick);

    /**
     * Does the quest contain dialogue?
     * 
     * @return True, if it does.
     */
    public abstract boolean hasDialogue();

    /**
     * Does the quest contain object click?
     * 
     * @return True, if it does.
     */
    public abstract boolean hasObjectClick();

    /**
     * Checks if a player has interacted with a node.
     * 
     * @param node the node to interact.
     * @return has interacted or not.
     */
    public abstract boolean hasInteracted(E node);

    /**
     * Gets the current state of the quest.
     * 
     * @return The current state.
     */
    public T getQuestState() {
        return questState;
    }

    /**
     * Sets the current state of the quest.
     * 
     * @param questState The state of the quest.
     */
    public void setQuestState(T questState) {
        this.questState = questState;
    }

    /**
     * Gets the id of the quest.
     * 
     * @return The quest id.
     */
    public int getQuestId() {
        return questId;
    }

    /**
     * Gets the name of the quest.
     *
     * @return The name of the quest.
     */
    public String getName() {
        return name;
    }

    /**
     * Gets the node interaction.
     * 
     * @return the interaction.
     */
    public E getNodeInteraction() {
        return nodeInteraction;
    }

    /**
     * Sets the node interaction.
     * 
     * @param nodeInteraction the interaction to set.
     */
    public void setNodeInteraction(E nodeInteraction) {
        this.nodeInteraction = nodeInteraction;
    }
}

这是例外

java.io.InvalidClassException: com.rs.game.player.quests.impl.CooksAssistant; no valid constructor
    at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(Unknown Source)
    at java.io.ObjectStreamClass.checkDeserialize(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at java.util.HashMap.readObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

有人可以帮我解决这个问题吗?

4

1 回答 1

2

阅读合同Serializable

在反序列化期间,不可序列化类的字段将使用类的公共或受保护的无参数构造函数进行初始化。可序列化的子类必须可以访问无参数构造函数。

CooksAssistant应该有一个用于序列化的无参数构造函数

public CooksAssistant() {
   super("Cooks' Assistant", 1, Stage.START, Nodes.CHEF);
}

由于播放器已经是一个字段,如果在序列化时设置它应该正确序列化

于 2013-09-08T23:56:14.803 回答