Package simpleserver

Source Code of simpleserver.Player

/*
* Copyright (c) 2010 SimpleServer authors (see CONTRIBUTORS)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package simpleserver;

import static simpleserver.lang.Translations.t;
import static simpleserver.util.Util.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.xml.sax.SAXException;

import simpleserver.Coordinate.Dimension;
import simpleserver.bot.BotController.ConnectException;
import simpleserver.bot.Giver;
import simpleserver.bot.Teleporter;
import simpleserver.command.ExternalCommand;
import simpleserver.command.PlayerCommand;
import simpleserver.config.KitList.Kit;
import simpleserver.config.data.Stats.StatField;
import simpleserver.config.xml.Area;
import simpleserver.config.xml.CommandConfig;
import simpleserver.config.xml.CommandConfig.Forwarding;
import simpleserver.config.xml.Event;
import simpleserver.config.xml.Group;
import simpleserver.config.xml.Permission;
import simpleserver.message.AbstractChat;
import simpleserver.message.Chat;
import simpleserver.message.GlobalChat;
import simpleserver.message.Message;
import simpleserver.stream.Encryption;
import simpleserver.stream.Encryption.ClientEncryption;
import simpleserver.stream.Encryption.ServerEncryption;
import simpleserver.stream.StreamTunnel;

public class Player {
  private final long connected;
  private final Socket extsocket;
  private final Server server;

  private Socket intsocket;
  private StreamTunnel serverToClient;
  private StreamTunnel clientToServer;
  private Watchdog watchdog;

  public ServerEncryption serverEncryption = new Encryption.ServerEncryption();
  public ClientEncryption clientEncryption = new Encryption.ClientEncryption();

  private String name = null;
  private String renameName = null;
  private String connectionHash;
  private boolean closed = false;
  private boolean isKicked = false;
  private Action attemptedAction;
  private boolean instantDestroy = false;
  private boolean godMode = false;
  private String kickMsg = null;
  public Position position;
  private Position deathPlace;
  private float health = 0;
  private short experience = 0;
  private int group = 0;
  private int entityId = 0;
  private Group groupObject = null;
  private boolean isRobot = false;
  // player is not authenticated with minecraft.net:
  private boolean guest = false;
  private boolean usedAuthenticator = false;
  private int blocksPlaced = 0;
  private int blocksDestroyed = 0;
  private Player reply = null;
  private String lastCommand = "";

  private AbstractChat chatType;
  private Queue<String> messages = new ConcurrentLinkedQueue<String>();
  private Queue<String> forwardMessages = new ConcurrentLinkedQueue<String>();
  private Queue<PlayerVisitRequest> visitreqs = new ConcurrentLinkedQueue<PlayerVisitRequest>();

  private Coordinate chestPlaced;

  private Coordinate chestOpened;

  private String nextChestName;

  // temporary coordinate storage for /myarea command
  public Coordinate areastart;
  public Coordinate areaend;

  private long lastTeleport;
  private short experienceLevel;

  public ConcurrentHashMap<String, String> vars; // temporary player-scope
                                                 // Script variables
  private long lastEvent;
  private HashSet<Area> currentAreas = new HashSet<Area>();

  public Player(Socket inc, Server parent) {
    connected = System.currentTimeMillis();
    position = new Position();
    server = parent;
    chatType = new GlobalChat(this);
    extsocket = inc;

    vars = new ConcurrentHashMap<String, String>();

    if (server.isRobot(getIPAddress())) {
      println("Robot Heartbeat: " + getIPAddress()
          + ".");
      isRobot = true;
    } else {
      println("IP Connection from " + getIPAddress()
          + "!");
    }

    if (server.isIPBanned(getIPAddress())) {
      println("IP " + getIPAddress() + " is banned!");

      cleanup();
      return;
    }
    server.requestTracker.addRequest(getIPAddress());

    try {
      InetAddress localAddress = InetAddress.getByName(Server.addressFactory.getNextAddress());
      intsocket = new Socket(InetAddress.getByName(null),
                             server.options.getInt("internalPort"),
                             localAddress, 0);
    } catch (Exception e) {
      try {
        intsocket = new Socket(InetAddress.getByName(null), server.options.getInt("internalPort"));
      } catch (Exception E) {
        e.printStackTrace();
        if (server.config.properties.getBoolean("exitOnFailure")) {
          server.stop();
        } else {
          server.restart();
        }

        cleanup();
        return;
      }
    }

    watchdog = new Watchdog();
    try {
      serverToClient = new StreamTunnel(intsocket.getInputStream(),
                                        extsocket.getOutputStream(), true, this);
      clientToServer = new StreamTunnel(extsocket.getInputStream(),
                                        intsocket.getOutputStream(), false,
                                        this);
    } catch (IOException e) {
      e.printStackTrace();
      cleanup();
      return;
    }

    if (isRobot) {
      server.addRobotPort(intsocket.getLocalPort());
    }
    watchdog.start();
  }

  public boolean setName(String name) {
    renameName = server.data.players.getRenameName(name);

    name = name.trim();
    if (name.length() == 0 || this.name != null) {
      kick(t("Invalid Name!"));
      return false;
    }

    if (name == "Player") {
      kick(t("Too many guests in server!"));
      return false;
    }

    if (!guest && server.config.properties.getBoolean("useWhitelist")
        && !server.whitelist.isWhitelisted(name)) {
      kick(t("You are not whitelisted!"));
      return false;
    }

    if (server.playerList.findPlayerExact(name) != null) {
      kick(t("Player already in server!"));
      return false;
    }

    this.name = name;
    updateGroup();

    watchdog.setName("PlayerWatchdog-" + name);
    server.connectionLog("player", extsocket, name);

    if (server.numPlayers() == 0) {
      server.time.set();
    }

    server.playerList.addPlayer(this);
    return true;
  }

  public String getName() {
    return renameName;
  }

  public String getName(boolean original) {
    return (original) ? name : renameName;
  }

  public String getRealName() {
    return server.data.players.getRealName(name);
  }

  public void updateRealName(String name) {
    server.data.players.setRealName(name);
  }

  public String getConnectionHash() {
    if (connectionHash == null) {
      connectionHash = server.nextHash();
    }
    return connectionHash;
  }

  public String getLoginHash() throws NoSuchAlgorithmException, UnsupportedEncodingException {
    return clientEncryption.getLoginHash(getConnectionHash());
  }

  public double distanceTo(Player player) {
    return Math.sqrt(Math.pow(x() - player.x(), 2) + Math.pow(y() - player.y(), 2) + Math.pow(z() - player.z(), 2));
  }

  public long getConnectedAt() {
    return connected;
  }

  public boolean isAttemptLock() {
    return attemptedAction == Action.Lock;
  }

  public void setAttemptedAction(Action action) {
    attemptedAction = action;
  }

  public boolean instantDestroyEnabled() {
    return instantDestroy;
  }

  public void toggleInstantDestroy() {
    instantDestroy = !instantDestroy;
  }

  public Server getServer() {
    return server;
  }

  public void setChat(AbstractChat chat) {
    chatType = chat;
  }

  public String getChatRoom() {
    return chatType.toString();
  }

  public void sendMessage(String message) {
    sendMessage(chatType, message);
  }

  public void sendMessage(String message, boolean build) {
    sendMessage(chatType, message, build);
  }

  public void sendMessage(Chat messageType, String message) {
    server.getMessager().propagate(messageType, message);
  }

  public void sendMessage(Chat messageType, String message, boolean build) {
    server.getMessager().propagate(messageType, message, build);
  }

  public void forwardMessage(String message) {
    forwardMessages.add(message);
  }

  public boolean hasForwardMessages() {
    return !forwardMessages.isEmpty();
  }

  public boolean hasMessages() {
    return !messages.isEmpty();
  }

  public void addMessage(Color color, String format, Object... args) {
    addMessage(color, String.format(format, args));
  }

  public void addMessage(Color color, String message) {
    addMessage(color + message);
  }

  public void addMessage(String format, Object... args) {
    addMessage(String.format(format, args));
  }

  public void addCaptionedMessage(String caption, String format, Object... args) {
    addMessage("%s%s: %s%s", Color.GRAY, caption, Color.WHITE, String.format(format, args));
  }

  public void addMessage(String msg) {
    messages.add(new Message(msg).buildMessage(true));
  }

  public void addTMessage(Color color, String format, Object... args) {
    addMessage(color + t(format, args));
  }

  public void addTMessage(Color color, String message) {
    addMessage(color + t(message));
  }

  public void addTMessage(String msg) {
    addMessage(t(msg));
  }

  public void addTCaptionedTMessage(String caption, String format, Object... args) {
    addMessage("%s%s: %s%s", Color.GRAY, t(caption), Color.WHITE, t(format, args));
  }

  public void addTCaptionedMessage(String caption, String format, Object... args) {
    addMessage("%s%s: %s%s", Color.GRAY, t(caption),
               Color.WHITE, String.format(format, args));
  }

  public String getForwardMessage() {
    return forwardMessages.remove();
  }

  public String getMessage() {
    return messages.remove();
  }

  public void addVisitRequest(Player source) {
    visitreqs.add(new PlayerVisitRequest(source));
  }

  public void handleVisitRequests() {
    while (visitreqs.size() > 0) {
      PlayerVisitRequest req = visitreqs.remove();
      if (System.currentTimeMillis() < req.timestamp + 10000 && server.findPlayerExact(req.source.getName()) != null) {
        req.source.addTMessage(Color.GRAY, "Request accepted!");
        req.source.teleportTo(this);
      }
    }
  }

  public void kick(String reason) {
    kickMsg = reason;
    isKicked = true;

    serverToClient.stop();
    clientToServer.stop();
  }

  public boolean isKicked() {
    return isKicked;
  }

  public void setKicked(boolean b) {
    isKicked = b;
  }

  public String getKickMsg() {
    return kickMsg;
  }

  public boolean isMuted() {
    return server.mutelist.isMuted(name);
  }

  public boolean isRobot() {
    return isRobot;
  }

  public boolean godModeEnabled() {
    return godMode;
  }

  public void toggleGodMode() {
    godMode = !godMode;
  }

  public int getEntityId() {
    return entityId;
  }

  public void setEntityId(int readInt) {
    entityId = readInt;
  }

  public int getGroupId() {
    return group;
  }

  public Group getGroup() {
    return groupObject;
  }

  public void setGuest(boolean guest) {
    this.guest = guest;
  }

  public boolean isGuest() {
    return guest;
  }

  public void setUsedAuthenticator(boolean usedAuthenticator) {
    this.usedAuthenticator = usedAuthenticator;
  }

  public boolean usedAuthenticator() {
    return usedAuthenticator;
  }

  public String getIPAddress() {
    return extsocket.getInetAddress().getHostAddress();
  }

  public InetAddress getInetAddress() {
    return extsocket.getInetAddress();
  }

  public boolean ignoresChestLocks() {
    return groupObject.ignoreChestLocks;
  }

  private void setDeathPlace(Position deathPosition) {
    deathPlace = deathPosition;
  }

  public Position getDeathPlace() {
    return deathPlace;
  }

  public float getHealth() {
    return health;
  }

  public void updateHealth(float health) {
    this.health = health;
    if (health <= 0) {
      setDeathPlace(new Position(position()));
    }
  }

  public short getExperience() {
    return experience;
  }

  public short getExperienceLevel() {
    return experienceLevel;
  }

  public void updateExperience(float bar, short level, short experience) {
    experienceLevel = level;
    this.experience = experience;
  }

  public double x() {
    return position.x;
  }

  public double y() {
    return position.y;
  }

  public double z() {
    return position.z;
  }

  public Coordinate position() {
    return position.coordinate();
  }

  public float yaw() {
    return position.yaw;
  }

  public float pitch() {
    return position.pitch;
  }

  public String parseCommand(String message, boolean overridePermissions) {
    // TODO: Handle aliases of external commands

    if (closed) {
      return null;
    }

    // Repeat last command
    if (message.equals(server.getCommandParser().commandPrefix() + "!")) {
      message = lastCommand;
    } else {
      lastCommand = message;
    }

    String commandName = message.split(" ")[0].substring(1).toLowerCase();
    String args = commandName.length() + 1 >= message.length() ? "" : message.substring(commandName.length() + 2);
    CommandConfig config = server.config.commands.getTopConfig(commandName);
    String originalName = config == null ? commandName : config.originalName;

    PlayerCommand command = server.resolvePlayerCommand(originalName, groupObject);

    if (config != null && !overridePermissions) {
      Permission permission = server.config.getCommandPermission(config.name, args, position.coordinate());
      if (!permission.contains(this)) {
        addTMessage(Color.RED, "Insufficient permission.");
        return null;
      }
    }

    try {
      if (server.options.getBoolean("enableEvents") && config.event != null) {
        Event e = server.eventhost.findEvent(config.event);
        if (e != null) {
          ArrayList<String> arguments = new ArrayList<String>();
          if (!args.equals("")) {
            arguments = new ArrayList<String>(java.util.Arrays.asList(args.split("\\s+")));
          }
          server.eventhost.execute(e, this, true, arguments);
        } else {
          System.out.println("Error in player command " + originalName + ": Event " + config.event + " not found!");
        }
      }
    } catch (NullPointerException e) {
      System.out.println("Error evaluating player command: " + originalName);
    }

    if (!(command instanceof ExternalCommand) && (config == null || config.forwarding != Forwarding.ONLY)) {
      command.execute(this, message);
    }

    if (command instanceof ExternalCommand) {
      // commands with bound events have to be forwarded explicitly
      // (to prevent unknown command error by server)
      if (config.event != null && config.forwarding == Forwarding.NONE) {
        return null;
      } else {
        return "/" + originalName + " " + args;
      }
    } else if ((config != null && config.forwarding != Forwarding.NONE) || server.config.properties.getBoolean("forwardAllCommands")) {
      return message;
    } else {
      return null;
    }
  }

  public void execute(Class<? extends PlayerCommand> c) {
    execute(c, "");
  }

  public void execute(Class<? extends PlayerCommand> c, String arguments) {
    server.getCommandParser().getPlayerCommand(c).execute(this, "a " + arguments);
  }

  public void teleportTo(Player target) {
    server.runCommand("tp", getName() + " " + target.getName());
  }

  public void sendMOTD() {
    String[] lines = server.motd.getMOTD().split("\\r?\\n");
    for (String line : lines) {
      addMessage(line);
    }
  }

  public void give(int id, int amount) {
    String baseCommand = getName() + " " + id + " ";
    for (int c = 0; c < amount / 64; ++c) {
      server.runCommand("give", baseCommand + 64);
    }
    if (amount % 64 != 0) {
      server.runCommand("give", baseCommand + amount % 64);
    }
  }

  public void give(int id, short damage, int amount) throws ConnectException {
    if (damage == 0) {
      give(id, amount);
    } else {
      Giver giver = new Giver(this);
      for (int c = 0; c < amount / 64; ++c) {
        giver.add(id, 64, damage);
      }
      if (amount % 64 != 0) {
        giver.add(id, amount % 64, damage);
      }
      server.bots.connect(giver);
    }
  }

  public void give(Kit kit) throws ConnectException {
    Giver giver = new Giver(this);
    int invSize = 45;
    int slot = invSize;

    for (Kit.Entry e : kit.items) {
      if (e.damage() == 0) {
        give(e.item(), e.amount());
      } else {
        int restAmount = e.amount();
        while (restAmount > 0 && --slot >= 0) {
          giver.add(e.item(), Math.min(restAmount, 64), e.damage());
          restAmount -= 64;

          if (slot == 0) {
            slot = invSize;
            server.bots.connect(giver);
            giver = new Giver(this);
          }
        }
      }
    }

    if (slot != invSize) {
      server.bots.connect(giver);
    }
  }

  public void updateGroup() {
    try {
      groupObject = server.config.getGroup(this);
    } catch (SAXException e) {
      println("A player could not be assigned to any group. (" + e + ")");
      kick("You could not be asigned to any group.");
      return;
    }
    group = groupObject.id;
  }

  public void placedBlock() {
    blocksPlaced += 1;
  }

  public void destroyedBlock() {
    blocksDestroyed += 1;
  }

  public Integer[] stats() {
    Integer[] stats = new Integer[4];

    stats[0] = (int) (System.currentTimeMillis() - connected) / 1000 / 60;
    stats[1] = server.data.players.stats.get(this, StatField.PLAY_TIME) + stats[0];
    stats[2] = server.data.players.stats.add(this, StatField.BLOCKS_PLACED, blocksPlaced);
    stats[3] = server.data.players.stats.add(this, StatField.BLOCKS_DESTROYED, blocksDestroyed);

    blocksPlaced = 0;
    blocksDestroyed = 0;
    server.data.save();

    return stats;
  }

  public void setReply(Player answer) {
    // set Player to reply with !reply command
    reply = answer;
  }

  public Player getReply() {
    return reply;
  }

  public void close() {
    if (serverToClient != null) {
      serverToClient.stop();
    }

    if (clientToServer != null) {
      clientToServer.stop();
    }

    if (name != null) {
      server.authenticator.unbanLogin(this);
      if (usedAuthenticator) {
        if (guest) {
          server.authenticator.releaseGuestName(name);
        } else {
          server.authenticator.rememberAuthentication(name, getIPAddress());
        }
      } else if (guest) {
        if (isKicked) {
          server.authenticator.releaseGuestName(name);
        } else {
          server.authenticator.rememberGuest(name, getIPAddress());
        }
      }

      server.data.players.stats.add(this, StatField.PLAY_TIME, (int) (System.currentTimeMillis() - connected) / 1000 / 60);
      server.data.players.stats.add(this, StatField.BLOCKS_DESTROYED, blocksDestroyed);
      server.data.players.stats.add(this, StatField.BLOCKS_PLACED, blocksPlaced);
      server.data.save();

      server.playerList.removePlayer(this);
      name = renameName = null;
    }
  }

  private void cleanup() {
    if (!closed) {
      closed = true;
      entityId = 0;

      close();

      try {
        extsocket.close();
      } catch (Exception e) {
      }
      try {
        intsocket.close();
      } catch (Exception e) {
      }

      if (!isRobot) {
        println("Socket Closed: "
            + extsocket.getInetAddress().getHostAddress());
      }
    }
  }

  private class PlayerVisitRequest {
    public Player source;
    public long timestamp;

    public PlayerVisitRequest(Player source) {
      timestamp = System.currentTimeMillis();
      this.source = source;
    }
  }

  private final class Watchdog extends Thread {
    @Override
    public void run() {
      while (serverToClient.isAlive() || clientToServer.isAlive()) {
        if (!serverToClient.isActive() || !clientToServer.isActive()) {
          println("Disconnecting " + getIPAddress()
              + " due to inactivity.");
          close();
          break;
        }

        try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
      }

      cleanup();
    }
  }

  public void placingChest(Coordinate coord) {
    chestPlaced = coord;
  }

  public boolean placedChest(Coordinate coordinate) {
    return chestPlaced != null && chestPlaced.equals(coordinate);
  }

  public void openingChest(Coordinate coordinate) {
    chestOpened = coordinate;
  }

  public Coordinate openedChest() {
    return chestOpened;
  }

  public void setChestName(String name) {
    nextChestName = name;
  }

  public String nextChestName() {
    return nextChestName;
  }

  public enum Action {
    Lock, Unlock, Rename;
  }

  public boolean isAttemptingUnlock() {
    return attemptedAction == Action.Unlock;
  }

  public void setDimension(Dimension dimension) {
    position.updateDimension(dimension);
  }

  public Dimension getDimension() {
    return position.dimension();
  }

  public void teleport(Coordinate coordinate) throws ConnectException, IOException {
    teleport(new Position(coordinate));
  }

  public void teleport(Position position) throws ConnectException, IOException {
    if (position.dimension() == getDimension()) {
      server.bots.connect(new Teleporter(this, position));
    } else {
      addTMessage(Color.RED, "You're not in the same dimension as the specified warppoint.");
    }
  }

  public void teleportSelf(Coordinate coordinate) {
    teleportSelf(new Position(coordinate));
  }

  public void teleportSelf(Position position) {
    try {
      teleport(position);
    } catch (Exception e) {
      addTMessage(Color.RED, "Teleporting failed.");
      return;
    }
    lastTeleport = System.currentTimeMillis();
  }

  private int cooldownLeft() {
    int cooldown = getGroup().cooldown();
    if (lastTeleport > System.currentTimeMillis() - cooldown) {
      return (int) (cooldown - System.currentTimeMillis() + lastTeleport);
    } else {
      return 0;
    }
  }

  public synchronized void teleportWithWarmup(Coordinate coordinate) {
    teleportWithWarmup(new Position(coordinate));
  }

  public synchronized void teleportWithWarmup(Position position) {
    int cooldown = cooldownLeft();
    if (lastTeleport < 0) {
      addTMessage(Color.RED, "You are already waiting for a teleport.");
    } else if (cooldown > 0) {
      addTMessage(Color.RED, "You have to wait %d seconds before you can teleport again.", cooldown / 1000);
    } else {
      int warmup = getGroup().warmup();
      if (warmup > 0) {
        lastTeleport = -1;
        Timer timer = new Timer();
        timer.schedule(new Warmup(position), warmup);
        addTMessage(Color.GRAY, "You will be teleported in %s seconds.", warmup / 1000);
      } else {
        teleportSelf(position);
      }
    }
  }

  public void checkAreaEvents() {
    HashSet<Area> areas = new HashSet<Area>(server.config.dimensions.areas(position()));
    HashSet<Area> areasCopy = new HashSet<Area>(areas);
    HashSet<Area> oldAreas = currentAreas;

    areasCopy.removeAll(oldAreas); // -> now contains only newly entered areas
    oldAreas.removeAll(areas); // -> now contains only areas not present anymore

    for (Area a : areasCopy) { // run area onenter events
      if (a.event == null) {
        continue;
      }
      Event e = server.eventhost.findEvent(a.event);
      if (e != null) {
        ArrayList<String> args = new ArrayList<String>();
        args.add("enter");
        args.add(a.name);
        server.eventhost.execute(e, this, true, args);
      } else {
        System.out.println("Error in area " + a.name + "/event: Event " + a.event + " not found!");
      }
    }

    for (Area a : oldAreas) { // run area onleave events
      if (a.event == null) {
        continue;
      }
      Event e = server.eventhost.findEvent(a.event);
      if (e != null) {
        ArrayList<String> args = new ArrayList<String>();
        args.add("leave");
        args.add(a.name);
        server.eventhost.execute(e, this, true, args);
      } else {
        System.out.println("Error in area " + a.name + "/event: Event " + a.event + " not found!");
      }
    }

    currentAreas = areas;
  }

  public void checkLocationEvents() {
    checkAreaEvents();

    long currtime = System.currentTimeMillis();
    if (currtime < lastEvent + 500) {
      return;
    }

    Iterator<Event> it = server.eventhost.events.keySet().iterator();
    while (it.hasNext()) {
      Event ev = it.next();
      if (!ev.type.equals("plate") || ev.coordinate == null) {
        continue;
      }
      if (position.coordinate().equals(ev.coordinate)) { // matching -> execute
        server.eventhost.execute(ev, this, false, null);
        lastEvent = currtime;
      }
    }
  }

  public void checkButtonEvents(Coordinate c) {
    long currtime = System.currentTimeMillis();
    if (currtime < lastEvent + 500) {
      return;
    }

    Iterator<Event> it = server.eventhost.events.keySet().iterator();
    while (it.hasNext()) {
      Event ev = it.next();
      if (!ev.type.equals("button") || ev.coordinate == null) {
        continue;
      }
      if ((new Coordinate(c.x(), c.y(), c.z(), position.dimension())).equals(ev.coordinate)) { // matching
                                                                                               // ->
                                                                                               // execute
        server.eventhost.execute(ev, this, false, null);
        lastEvent = currtime;
      }
    }
  }

  private final class Warmup extends TimerTask {
    private final Position position;

    private Warmup(Position position) {
      super();
      this.position = position;
    }

    @Override
    public void run() {
      teleportSelf(position);
    }
  }
}
TOP

Related Classes of simpleserver.Player

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.