Package games.stendhal.server.actions.admin

Source Code of games.stendhal.server.actions.admin.AlterAction

/* $Id: AlterAction.java,v 1.21 2011/04/02 15:44:19 kymara Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   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 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.server.actions.admin;

import static games.stendhal.common.constants.Actions.ADD;
import static games.stendhal.common.constants.Actions.ADMINLEVEL;
import static games.stendhal.common.constants.Actions.ALTER;
import static games.stendhal.common.constants.Actions.ATTR_HP;
import static games.stendhal.common.constants.Actions.MODE;
import static games.stendhal.common.constants.Actions.SET;
import static games.stendhal.common.constants.Actions.STAT;
import static games.stendhal.common.constants.Actions.SUB;
import static games.stendhal.common.constants.Actions.TARGET;
import static games.stendhal.common.constants.Actions.TITLE;
import static games.stendhal.common.constants.Actions.UNSET;
import static games.stendhal.common.constants.Actions.VALUE;
import games.stendhal.common.grammar.Grammar;
import games.stendhal.server.actions.CommandCenter;
import games.stendhal.server.core.engine.GameEvent;
import games.stendhal.server.entity.Entity;
import games.stendhal.server.entity.player.Player;
import marauroa.common.game.Definition;
import marauroa.common.game.RPAction;
import marauroa.common.game.RPClass;
import marauroa.common.game.Definition.DefinitionClass;
import marauroa.common.game.Definition.Type;

public class AlterAction extends AdministrationAction {
 
  public static void register() {
    CommandCenter.register(ALTER, new AlterAction(), 900);
  }

  @Override
  public void perform(final Player player, final RPAction action) {
    if (hasNeededAttributes(action)) {
      final Entity changed = getTargetAnyZone(player, action);

      if (changed == null) {
        logger.debug("Entity not found");
        player.sendPrivateText("Entity not found");
        return;
      }

      final String stat = action.get(STAT);

      if ("name".equals(stat) && (changed instanceof Player)) {
        logger.error("DENIED: Admin " + player.getName() + " trying to change player " + action.get(TARGET)
            + "'s name");
        player.sendPrivateText("Sorry, name cannot be changed.");
        return;
      }

      if (ADMINLEVEL.equals(stat)) {
        player.sendPrivateText("Use #/adminlevel #<playername> #[<newlevel>] to display or change adminlevel.");
        return;
      }

      if (TITLE.equals(stat) && (changed instanceof Player)) {
        player.sendPrivateText("The title attribute may not be changed directly.");
        return;
      }

      final RPClass clazz = changed.getRPClass();


      final Definition type = clazz.getDefinition(DefinitionClass.ATTRIBUTE, stat);
      if (type == null) {
        player.sendPrivateText("Attribute you are altering is not defined in RPClass("
            + changed.getRPClass().getName() + ")");
        return;
      } else {
        final String value = action.get(VALUE);
        final String mode = action.get(MODE);

        if ((mode.length() > 0) && !mode.equalsIgnoreCase(ADD)
            && !mode.equalsIgnoreCase(SUB) && !mode.equalsIgnoreCase(SET) && !mode.equalsIgnoreCase(UNSET)) {
          player.sendPrivateText("Please issue one of the modes 'add', 'sub', 'set' or 'unset'.");
          return;
        }

        if (isParsableByInteger(type)) {
          int numberValue;

          try {
            numberValue = Integer.parseInt(value);
          } catch (final NumberFormatException e) {
            player.sendPrivateText("Please issue a numeric value instead of '" + value + "'");
            return;
          }

          if (mode.equalsIgnoreCase(ADD)) {
            numberValue = changed.getInt(stat) + numberValue;
          }

          if (mode.equalsIgnoreCase(SUB)) {
            numberValue = changed.getInt(stat) - numberValue;
          }

          if (ATTR_HP.equals(stat) && (changed.getInt("base_hp") < numberValue)) {
            logger.info("Admin " + player.getName() + " trying to set entity "
                + Grammar.suffix_s(action.get(TARGET)) + " HP over its Base HP, "
                + "we instead restored entity " + action.get(TARGET) + " to full health.");
            numberValue = changed.getInt("base_hp");
          }

          if (ATTR_HP.equals(stat) && (numberValue <= 0)) {
            logger.error("DENIED: Admin " + player.getName() + " trying to set entity "
                + Grammar.suffix_s(action.get(TARGET)) + " HP to 0, making it so unkillable.");
            return;
          }

          switch (type.getType()) {
          case BYTE:
            if ((numberValue > Byte.MAX_VALUE)
                || (numberValue < Byte.MIN_VALUE)) {
              return;
            }
            break;
          case SHORT:
            if ((numberValue > Short.MAX_VALUE)
                || (numberValue < Short.MIN_VALUE)) {
              return;
            }
            break;
          case INT:
            /*
             * as numberValue is currently of type integer, this is
             * pointless: if ((numberValue > Integer.MAX_VALUE) ||
             * (numberValue < Integer.MIN_VALUE)) { return; }
             */
            break;
          default:
              // we switch over an enum
              break;
          }
         
          new GameEvent(player.getName(), ALTER, action.get(TARGET), stat, Integer.toString(numberValue)).raise();
          changed.put(stat, numberValue);
        } else {
          // If value is not a number, only SET and UNSET can be used
          if (mode.equalsIgnoreCase(SET)) {
            new GameEvent(player.getName(), ALTER, action.get(TARGET), stat, action.get(VALUE)).raise();
            changed.put(stat, action.get(VALUE));

          } else if (mode.equalsIgnoreCase(UNSET)) {
            if (type.getType() != Type.FLAG) {
              player.sendPrivateText("Attribute to be unset is not of type 'flag'.");
              return;
            }
            new GameEvent(player.getName(), ALTER, action.get(TARGET), stat, "unset").raise();
            changed.remove(stat);
          }
        }

        changed.update();
        changed.notifyWorldAboutChanges();
      }
    }
  }

  protected boolean isParsableByInteger(final Definition type) {
    if ((type.getType() == Type.BYTE) || (type.getType() == Type.SHORT)
        || (type.getType() == Type.INT)) {
      return true;
    }
    return false;
  }

  protected boolean hasNeededAttributes(final RPAction action) {
    return action.has(TARGET) && action.has(STAT) && action.has(MODE)
        && action.has(VALUE);
  }

}
TOP

Related Classes of games.stendhal.server.actions.admin.AlterAction

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.