Package

Source Code of CraftBookListener

// $Id$
/*
* CraftBook
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import com.sk89q.craftbook.BlockType;
import com.sk89q.craftbook.CraftBookDelegateListener;
import com.sk89q.craftbook.InsufficientArgumentsException;
import com.sk89q.craftbook.access.BaseEntityInterface;
import com.sk89q.craftbook.access.MinecartInterface;
import com.sk89q.craftbook.access.PlayerInterface;
import com.sk89q.craftbook.access.SignInterface;
import com.sk89q.craftbook.util.BlockVector;
import com.sk89q.craftbook.util.Vector;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
* This is CraftBook's main event listener for Hey0's server mod. "Delegate"
* listeners are also used for different features and this listener acts
* as a proxy for some custom hooks and events.
*
* @author sk89q
*/
public class CraftBookListener extends PluginListener
        implements Runnable,
        SignPatch.ExtensionListener {

    /**
     * Logger instance.
     */
    static final Logger logger = Logger.getLogger("Minecraft.CraftBook");

    /**
     * Stores an instance of the plugin. This is used to register delegate
     * listeners and access some global features.
     */
    private CraftBook main;

    private HmodWorldImpl w;

    /**
     * Construct the object.
     *
     * @param craftBook
     */
    public CraftBookListener(CraftBook craftBook) {

        main = craftBook;
        w = main.getWorld();
    }

    public void run() {

        for (CraftBookDelegateListener l : main.tickListeners) { l.onTick(w); }
    }

    public void onSignAdded(int x, int y, int z) {

        for (CraftBookDelegateListener l : main.signCreateListeners) { l.onSignCreate(w, x, y, z); }
    }

    public boolean onSignChange(Player p, Sign sp) {

        PlayerInterface player = new HmodPlayerImpl(p, w);
        BlockVector signPosition = new BlockVector(sp.getX(), sp.getY(), sp.getZ());
        SignInterface s = new HmodSignImpl(w, signPosition, sp);
        for (CraftBookDelegateListener l : main.signChangeListeners) {
            if (l.onSignChange(player, w, signPosition, s)) return true;
        }
        return false;
    }

    /**
     * Called on command.
     *
     * @param player
     * @param split
     *
     * @return whether the command was processed
     */
    @Override
    public boolean onCommand(Player player, String[] split) {

        try {
            if (split[0].equalsIgnoreCase("/reload")
                    && player.canUseCommand("/reload")
                    && split.length > 1
                    && (split[1].equalsIgnoreCase("CraftBook")
                    || split[1].equals("*"))) {

                // Redirect log messages to the player's chat.
                LoggerToChatHandler handler = new LoggerToChatHandler(player);
                handler.setLevel(Level.ALL);
                Logger minecraftLogger = Logger.getLogger("Minecraft");
                minecraftLogger.addHandler(handler);

                try {
                    main.loadConfiguration();
                    player.sendMessage("CraftBook configuration reloaded.");
                } catch (Throwable t) {
                    player.sendMessage("Error while reloading: "
                            + t.getMessage());
                } finally {
                    minecraftLogger.removeHandler(handler);
                }

                return !split[1].equals("*");
            }

            PlayerInterface myPlayer = new HmodPlayerImpl(player, w);

            for (CraftBookDelegateListener listener : main.commandListeners) {
                if (listener.onCommand(myPlayer, split)) return true;
            }

            return false;
        } catch (InsufficientArgumentsException e) {
            player.sendMessage(Colors.Rose + e.getMessage());
            return true;
        }
    }

    public boolean onConsoleCommand(String[] split) {

        for (CraftBookDelegateListener listener : main.consoleCommandListeners) {
            if (listener.onConsoleCommand(split)) return true;
        }

        return false;
    }

    /**
     * Called on redstone change.
     *
     * @param block
     * @param oldLevel
     * @param newLevel
     */
    public int onRedstoneChange(Block block, int oldLevel, int newLevel) {

        BlockVector v = new BlockVector(block.getX(), block.getY(), block.getZ());

        // Give the method a BlockVector instead of a Block
        boolean wasOn = oldLevel >= 1;
        boolean isOn = newLevel >= 1;
        boolean wasChange = wasOn != isOn;

        // For efficiency reasons, we're only going to consider changes between
        // off and on state, and ignore simple current changes (i.e. 15->13)
        if (!wasChange) {
            return newLevel;
        }

        int x = v.getBlockX();
        int y = v.getBlockY();
        int z = v.getBlockZ();

        int type = w.getId(x, y, z);

        // When this hook has been called, the level in the world has not
        // yet been updated, so we're going to do this very ugly thing of
        // faking the value with the new one whenever the data value of this
        // block is requested -- it is quite ugly
        try {
            if (type == BlockType.LEVER) {
                // Fake data
                w.fakeData(x, y, z,
                        newLevel > 0
                        ? w.getData(x, y, z) | 0x8
                        : w.getData(x, y, z) & 0x7);
            } else if (type == BlockType.STONE_PRESSURE_PLATE) {
                // Fake data
                w.fakeData(x, y, z,
                        newLevel > 0
                        ? w.getData(x, y, z) | 0x1
                        : w.getData(x, y, z) & 0x14);
            } else if (type == BlockType.WOODEN_PRESSURE_PLATE) {
                // Fake data
                w.fakeData(x, y, z,
                        newLevel > 0
                        ? w.getData(x, y, z) | 0x1
                        : w.getData(x, y, z) & 0x14);
            } else if (type == BlockType.STONE_BUTTON) {
                // Fake data
                w.fakeData(x, y, z,
                        newLevel > 0
                        ? w.getData(x, y, z) | 0x8
                        : w.getData(x, y, z) & 0x7);
            } else if (type == BlockType.REDSTONE_WIRE) {
                // Fake data
                w.fakeData(x, y, z, newLevel);

                int westSide = w.getId(x, y, z + 1);
                int westSideAbove = w.getId(x, y + 1, z + 1);
                int westSideBelow = w.getId(x, y - 1, z + 1);
                int eastSide = w.getId(x, y, z - 1);
                int eastSideAbove = w.getId(x, y + 1, z - 1);
                int eastSideBelow = w.getId(x, y - 1, z - 1);

                int northSide = w.getId(x - 1, y, z);
                int northSideAbove = w.getId(x - 1, y + 1, z);
                int northSideBelow = w.getId(x - 1, y - 1, z);
                int southSide = w.getId(x + 1, y, z);
                int southSideAbove = w.getId(x + 1, y + 1, z);
                int southSideBelow = w.getId(x + 1, y - 1, z);

                // Make sure that the wire points to only this block
                if (!BlockType.isRedstoneBlock(westSide)
                        && !BlockType.isRedstoneBlock(eastSide)
                        && (!BlockType.isRedstoneBlock(westSideAbove) || westSide == 0)
                        && (!BlockType.isRedstoneBlock(eastSideAbove) || eastSide == 0)
                        && (!BlockType.isRedstoneBlock(westSideBelow) || westSide != 0)
                        && (!BlockType.isRedstoneBlock(eastSideBelow) || eastSide != 0)) {
                    // Possible blocks north / south
                    handleDirectWireInput(new Vector(x - 1, y, z), isOn, v);
                    handleDirectWireInput(new Vector(x + 1, y, z), isOn, v);
                    handleDirectWireInput(new Vector(x - 1, y - 1, z), isOn, v);
                    handleDirectWireInput(new Vector(x + 1, y - 1, z), isOn, v);
                }

                if (!BlockType.isRedstoneBlock(northSide)
                        && !BlockType.isRedstoneBlock(southSide)
                        && (!BlockType.isRedstoneBlock(northSideAbove) || northSide == 0)
                        && (!BlockType.isRedstoneBlock(southSideAbove) || southSide == 0)
                        && (!BlockType.isRedstoneBlock(northSideBelow) || northSide != 0)
                        && (!BlockType.isRedstoneBlock(southSideBelow) || southSide != 0)) {
                    // Possible blocks west / east
                    handleDirectWireInput(new Vector(x, y, z - 1), isOn, v);
                    handleDirectWireInput(new Vector(x, y, z + 1), isOn, v);
                    handleDirectWireInput(new Vector(x, y - 1, z - 1), isOn, v);
                    handleDirectWireInput(new Vector(x, y - 1, z + 1), isOn, v);
                }

                // Can be triggered from below
                handleDirectWireInput(new Vector(x, y + 1, z), isOn, v);

                return newLevel;
            }

            // For redstone wires, the code already exited this method
            // Non-wire blocks proceed

            handleDirectWireInput(new Vector(x - 1, y, z), isOn, v);
            handleDirectWireInput(new Vector(x + 1, y, z), isOn, v);
            handleDirectWireInput(new Vector(x - 1, y - 1, z), isOn, v);
            handleDirectWireInput(new Vector(x + 1, y - 1, z), isOn, v);
            handleDirectWireInput(new Vector(x, y, z - 1), isOn, v);
            handleDirectWireInput(new Vector(x, y, z + 1), isOn, v);
            handleDirectWireInput(new Vector(x, y - 1, z - 1), isOn, v);
            handleDirectWireInput(new Vector(x, y - 1, z + 1), isOn, v);

            // Can be triggered from below
            handleDirectWireInput(new Vector(x, y + 1, z), isOn, v);

            return newLevel;
        } finally {
            w.destroyFake();
        }
    }

    /**
     * Handles direct redstone input. This method merely passes the call
     * onto the delegates for further processing. If a delegate throws an
     * exception, it will not be caught here.
     *
     * @param inputVec
     * @param isOn
     * @param changed
     *
     * @see CraftBookDelegateListener#onDirectWireInput(Vector, boolean, Vector)
     */
    public void handleDirectWireInput(Vector pt, boolean isOn, Vector changed) {
        // Call the direct wire input hook of delegates
        for (CraftBookDelegateListener listener : main.wireInputListeners) {
            listener.onWireInput(w, pt, isOn, changed);
        }
    }

    public void onDisconnect(Player p) {

        PlayerInterface player = new HmodPlayerImpl(p, w);
        for (CraftBookDelegateListener listener : main.disconnectListeners) { listener.onDisconnect(player); }
    }

    public boolean onBlockPlace(Player p, Block pp, Block cp, Item itemInHand) {

        PlayerInterface player = new HmodPlayerImpl(p, w);
        BlockVector pv = new BlockVector(pp.getX(), pp.getY(), pp.getZ());
        BlockVector cv = new BlockVector(cp.getX(), cp.getY(), cp.getZ());
        for (CraftBookDelegateListener listener : main.blockPlaceListeners) {
            if (listener.onBlockPlace(w, player, pv, cv, itemInHand.getItemId()))
                return true;
        }
        return false;
    }

    public void onBlockRightClicked(Player p, Block cp, Item itemInHand) {

        PlayerInterface player = new HmodPlayerImpl(p, w);
        BlockVector cv = new BlockVector(cp.getX(), cp.getY(), cp.getZ());
        for (CraftBookDelegateListener listener : main.blockRightClickListeners) {
            listener.onBlockRightClicked(w, player, cv, itemInHand.getItemId());
        }
    }

    public boolean onBlockDestroy(Player p, Block dp) {

        PlayerInterface player = new HmodPlayerImpl(p, w);
        BlockVector dv = new BlockVector(dp.getX(), dp.getY(), dp.getZ());
        for (CraftBookDelegateListener listener : main.blockDestroyedListeners) {
            if (listener.onBlockDestroy(w, player, dv, dp.getStatus()))
                return true;
        }
        return false;
    }

    public boolean onVehicleDamage(BaseVehicle vehicle, BaseEntity entity, int damage) {

        if (!(vehicle instanceof Minecart)) return false;
        MinecartInterface m = getMinecart((Minecart) vehicle);
        BaseEntityInterface e = new HmodBaseEntityImpl(entity, w);
        for (CraftBookDelegateListener listener : main.minecartDamageListeners) {
            if (listener.onMinecartDamage(w, m, e, damage))
                return true;
        }
        return false;
    }

    public void onVehicleUpdate(BaseVehicle vehicle) {

        if (!(vehicle instanceof Minecart)) return;
        MinecartInterface m = getMinecart((Minecart) vehicle);
        for (CraftBookDelegateListener listener : main.minecartVelocityChangeListeners) {
            listener.onMinecartVelocityChange(w, m);
        }
    }

    public void onVehiclePositionChange(BaseVehicle vehicle, int x, int y, int z) {

        if (!(vehicle instanceof Minecart)) return;
        MinecartInterface m = getMinecart((Minecart) vehicle);
        for (CraftBookDelegateListener listener : main.minecartPositionChangeListeners) {
            listener.onMinecartPositionChange(w, m, x, y, z);
        }
    }

    public void onVehicleEnter(BaseVehicle vehicle, HumanEntity entity) {

        if (!(vehicle instanceof Minecart)) return;
        MinecartInterface m = getMinecart((Minecart) vehicle);
        BaseEntityInterface e = new HmodBaseEntityImpl(entity, w);
        boolean entering = vehicle.getPassenger() == null;
        for (CraftBookDelegateListener listener : main.minecartEnterListeners) {
            listener.onMinecartEnter(w, m, e, entering);
        }
    }

    public void onVehicleDestroyed(BaseVehicle vehicle) {

        if (!(vehicle instanceof Minecart)) return;
        MinecartInterface m = getMinecart((Minecart) vehicle);
        for (CraftBookDelegateListener listener : main.minecartDestroyListeners) { listener.onMinecartDestroyed(w, m); }
    }

    private MinecartInterface getMinecart(Minecart m) {

        if (m.getStorage() == null)
            return new HmodMinecartImpl(m, w);
        else
            return new HmodStorageMinecartImpl(m, w);
    }
}
TOP

Related Classes of CraftBookListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.