Package org.mctourney.autoreferee

Source Code of org.mctourney.autoreferee.AutoReferee

package org.mctourney.autoreferee;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.messaging.Messenger;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Scoreboard;

import com.sk89q.worldedit.bukkit.WorldEditPlugin;

import org.mcstats.Metrics;
import org.mcstats.Metrics.Graph;

import org.mctourney.autoreferee.commands.AdminCommands;
import org.mctourney.autoreferee.commands.ConfigurationCommands;
import org.mctourney.autoreferee.commands.PlayerCommands;
import org.mctourney.autoreferee.commands.PracticeCommands;
import org.mctourney.autoreferee.commands.ScoreboardCommands;
import org.mctourney.autoreferee.commands.SpectatorCommands;
import org.mctourney.autoreferee.listeners.CombatListener;
import org.mctourney.autoreferee.listeners.ObjectiveTracker;
import org.mctourney.autoreferee.listeners.ObjectiveTracer;
import org.mctourney.autoreferee.listeners.SpectatorListener;
import org.mctourney.autoreferee.listeners.TeamListener;
import org.mctourney.autoreferee.listeners.WorldListener;
import org.mctourney.autoreferee.listeners.ZoneListener;
import org.mctourney.autoreferee.listeners.lobby.LobbyListener;
import org.mctourney.autoreferee.listeners.lobby.LobbyListener.LobbyMode;
import org.mctourney.autoreferee.util.NullChunkGenerator;
import org.mctourney.autoreferee.util.SportBukkitUtil;
import org.mctourney.autoreferee.util.commands.CommandManager;
import org.mctourney.autoreferee.util.metrics.PieChartGraph;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
* Base plugin class
*
* @author authorblues
*/
public class AutoReferee extends JavaPlugin
{
  // singleton instance
  private static AutoReferee instance = null;

  // AutoReferee internal properties
  private static Properties properties = null;

  /**
   * Gets the singleton instance of AutoReferee
   *
   * @return AutoReferee instance
   */
  public static AutoReferee getInstance()
  { return instance; }

  public static void log(String msg, Level level)
  { getInstance().getLogger().log(level, ChatColor.stripColor(msg)); }

  public static void log(String msg)
  { log(msg, Level.INFO); }

  public String getCommit()
  { return properties == null ? "??" : properties.getProperty("git-sha-1"); }

  // expected configuration version number
  private static final int PLUGIN_CFG_VERSION = 2;

  // plugin channel encoding
  public static final String PLUGIN_CHANNEL_ENC = "UTF-8";

  // plugin channel prefix - identifies all channels as belonging to AutoReferee
  private static final String PLUGIN_CHANNEL_PREFIX = "autoref:";

  // plugin channels (referee)
  public static final String REFEREE_PLUGIN_CHANNEL = PLUGIN_CHANNEL_PREFIX + "referee";
  private SpectatorListener refChannelListener = null;

  // name of the stored map configuration file
  public static final String CFG_FILENAME = "autoreferee.xml";

  // prefix for temporary worlds
  public static final String WORLD_PREFIX = "world-autoref-";

  // messages
  public static final String NO_LOGIN_MESSAGE = "You are not scheduled for a match on this server.";
  public static final String COMPLETED_KICK_MESSAGE = "Thank you for playing!";
  public static final String NO_WEBSTATS_MESSAGE = "An error has occured; no webstats will be generated.";

  // command manager
  protected CommandManager commandManager = null;

  public CommandManager getCommandManager()
  { return this.commandManager; }

  public static void callEvent(Event event)
  { Bukkit.getServer().getPluginManager().callEvent(event); }

  private World lobby = null;

  /**
   * Gets the world designated as the lobby world. When the server is in automated mode, this world
   * is where users will be teleported to when the a match is unloaded and cleaned up.
   *
   * @return lobby world
   */
  public World getLobbyWorld()
  {
    if (lobby == null)
    {
      String lname = getConfig().getString("lobby.world", null);
      if (lname != null) this.setLobbyWorld(Bukkit.getWorld(lname));
    }
    return lobby;
  }

  /**
   * Sets the world designated as the lobby world.
   *
   * @param world lobby world
   */
  public void setLobbyWorld(World world)
  {
    if (world != null && !AutoRefMatch.isCompatible(world))
    {
      // change the lobby world
      this.lobby = world;

      // reflect this change in the config file
      this.getConfig().set("lobby.world", this.lobby.getName());
      this.saveConfig();
    }
  }

  private boolean consoleLog = true;
  private boolean consoleLogInColor = true;

  protected boolean isConsoleLoggingEnabled()
  { return consoleLog; }

  protected boolean isColoredConsoleLoggingEnabled()
  { return consoleLogInColor; }

  // get the match associated with the world
  private Map<UUID, AutoRefMatch> matches = Maps.newHashMap();

  /**
   * Gets match object associated with the given world.
   *
   * @return match object if one exists, otherwise null
   */
  public AutoRefMatch getMatch(World world)
  { return world != null ? matches.get(world.getUID()) : null; }

  /**
   * Gets all existing match objects for this server.
   *
   * @return a collection of match objects
   */
  public Collection<AutoRefMatch> getMatches()
  { return matches.values(); }

  /**
   * Adds a given match to be tracked by the server.
   */
  public void addMatch(AutoRefMatch match)
  { matches.put(match.getWorld().getUID(), match); }

  /**
   * Removes a match from the server.
   */
  public void clearMatch(AutoRefMatch match)
  { matches.remove(match.getWorld().getUID()); }

  // track owner of a piece of tnt (perhaps with propagation)
  private Map<UUID, AutoRefPlayer> tntOwner = Maps.newHashMap();

  /**
   * Gets the player responsible for a primed TNT.
   * @param entity primed tnt entity
   */
  public AutoRefPlayer getTNTOwner(Entity entity)
  { return tntOwner.get(entity.getUniqueId()); }

  /**
   * Sets the player responsible for a primed TNT.
   * @param entity primed tnt entity
   * @param apl player responsible for tnt
   */
  public void setTNTOwner(Entity entity, AutoRefPlayer apl)
  {
    if (entity.getType() == EntityType.PRIMED_TNT)
      tntOwner.put(entity.getUniqueId(), apl);
  }

  /**
   * Clears out a primed TNT from the tracked list.
   * @param entity primed tnt entity
   */
  public AutoRefPlayer clearTNTOwner(Entity entity)
  { return tntOwner.remove(entity.getUniqueId()); }

  /**
   * Gets team object associated with a player. Searches all matches for this player,
   * returns team object for the team containing this player.
   *
   * @return team object if player is on team, otherwise null
   */
  public AutoRefTeam getTeam(Player player)
  {
    // go through all the matches
    for (AutoRefMatch match : matches.values())
    {
      // if the player is on a team for this match...
      AutoRefTeam team = match.getPlayerTeam(player);
      if (team != null) return team;
    }

    // this player is on no known teams
    return null;
  }

  /**
   * Gets the team the player is expected to join. Matches setup by automated match
   * configurations may designate certain players for certain teams.
   *
   * @return player's team, null if no such team
   */
  public AutoRefTeam getExpectedTeam(Player player)
  {
    AutoRefTeam actualTeam = getTeam(player);
    if (actualTeam != null) return actualTeam;

    // go through all the matches
    for (AutoRefMatch match : matches.values())
    {
      // if the player is expected for any of these teams
      for (AutoRefTeam team : match.getTeams())
        if (team.getExpectedPlayers().contains(player.getName()))
          return team;
    }

    // this player is expected on no known teams
    return null;
  }

  public void onEnable()
  {
    // store the singleton instance
    instance = this;
    updateConfigurationFile();

    // ensure we are dealing with the right type of config file
    int configVersion = getConfig().getInt("config-version", PLUGIN_CFG_VERSION);
    if (configVersion != PLUGIN_CFG_VERSION) getLogger().severe(String.format(
      "!!! Incorrect config-version (expected %d, got %d)", PLUGIN_CFG_VERSION, configVersion));

    // get properties file data
    InputStream propStream = getResource("autoreferee.properties");
    if (propStream != null) try
    {
      properties = new Properties();
      properties.load(propStream);
    }
    catch (IOException e)
    { AutoReferee.log("Failed to load properties file.", Level.SEVERE); }

    PluginManager pm = getServer().getPluginManager();
    PracticeCommands practice = new PracticeCommands(this);

    String lobbymode = getConfig().getString("lobby.mode", "manual");
    LobbyListener lobbyListener = LobbyMode.fromConfig(lobbymode).getInstance(this);

    // listener utility classes, subdivided for organization
    pm.registerEvents(new TeamListener(this), this);
    pm.registerEvents(new CombatListener(this), this);
    pm.registerEvents(new ZoneListener(this), this);
    pm.registerEvents(new WorldListener(this), this);
    pm.registerEvents(new ObjectiveTracker(this), this);
    pm.registerEvents(new ObjectiveTracer(this), this);

    // save this reference to use for setting up the referee channel later
    pm.registerEvents(refChannelListener = new SpectatorListener(this), this);

    pm.registerEvents(lobbyListener, this);
    pm.registerEvents(practice, this);

    // user interface commands in a custom command manager
    commandManager = new CommandManager();
    commandManager.registerCommands(new PlayerCommands(this), this);
    commandManager.registerCommands(new AdminCommands(this), this);
    commandManager.registerCommands(new SpectatorCommands(this), this);
    commandManager.registerCommands(new ConfigurationCommands(this), this);
    commandManager.registerCommands(new ScoreboardCommands(this), this);

    commandManager.registerCommands(lobbyListener, this);
    commandManager.registerCommands(practice, this);

    // go ahead and generate all help for the plugin
    commandManager.generateHelp(this);

    // global configuration object (can't be changed, so don't save onDisable)
    InputStream configInputStream = getResource("defaults/config.yml");
    if (configInputStream != null) getConfig().setDefaults(
      YamlConfiguration.loadConfiguration(configInputStream));
    getConfig().options().copyDefaults(true); saveConfig();

    // setup a possible alternate map repository
    String mrepo = this.getConfig().getString("map-repo", null);
    if (mrepo != null) AutoRefMatch.changeMapRepo(mrepo);

    // attempt to setup the plugin channels
    setupPluginChannels();

    // fire up the plugin metrics
    try { setupPluginMetrics(); }
    catch (IOException e) { getLogger().severe("Plugin Metrics not enabled."); }

    // wrap up, debug to follow this message
    getLogger().info(this.getName() + " (" + Bukkit.getName() + ") loaded successfully" +
      (SportBukkitUtil.hasSportBukkitApi() ? " with SportBukkit API" : "") + ".");
    getLogger().info(this.getName() + " Git: " + this.getCommit());

    // are ties allowed? (auto-mode always allows for ties)
    AutoRefMatch.setAllowTies(getConfig().getBoolean("allow-ties", false));

    // log messages to console?
    consoleLog = getConfig().getBoolean("console-log", true);
    consoleLogInColor = getConfig().getBoolean("console-colors", true);

    // setup the map library folder
    AutoRefMap.getMapLibrary();

    // process initial world(s), just in case
    for ( World w : getServer().getWorlds() )
      AutoRefMatch.setupWorld(w, false);

    // update maps automatically if auto-update is enabled
    if (getConfig().getBoolean("auto-update", true))
      AutoRefMap.getUpdates(Bukkit.getConsoleSender(), false);
  }

  public void onDisable()
  {
    for (AutoRefMatch match : getMatches())
      match.saveWorldConfiguration();
    getLogger().info(this.getName() + " disabled.");
  }

  private void setupPluginChannels()
  {
    Messenger m = getServer().getMessenger();

    // setup referee plugin channels
    m.registerOutgoingPluginChannel(this, REFEREE_PLUGIN_CHANNEL);
    m.registerIncomingPluginChannel(this, REFEREE_PLUGIN_CHANNEL, refChannelListener);
  }

  protected PieChartGraph playedMapsTracker = null;

  private void setupPluginMetrics()
    throws IOException
  {
    Metrics metrics = new Metrics(this);

    Set<String> mapNames = Sets.newHashSet();
    for (AutoRefMap map : AutoRefMap.getRemoteMaps())
      mapNames.add(map.getName());

    Graph gMaps = metrics.createGraph("Most Popular Maps");
    playedMapsTracker = new PieChartGraph(gMaps, mapNames);

    metrics.start();
  }

  public static WorldEditPlugin getWorldEdit()
  {
    Plugin x = Bukkit.getPluginManager().getPlugin("WorldEdit");
    return (x != null && x instanceof WorldEditPlugin) ? (WorldEditPlugin) x : null;
  }

  private UUID consoleWorld = null;

  /**
   * Gets the world that the console user has selected.
   *
   * @return The world selected by the console user
   */
  public World getConsoleWorld()
  {
    return consoleWorld == null || getServer().getWorld(consoleWorld) == null
      ? getServer().getWorlds().get(0) : getServer().getWorld(consoleWorld);
  }

  /**
   * Sets the world that the console user has selected.
   */
  public void setConsoleWorld(World world)
  { consoleWorld = world == null ? null : world.getUID(); }

  /**
   * Sets the world that the console user has selected.
   */
  public void setConsoleWorld(String name)
  {
    World world = getServer().getWorld(name);
    if (world == null)
    {
      Player player = getServer().getPlayer(name);
      if (player != null) world = player.getWorld();
    }

    this.setConsoleWorld(world);
  }

  /**
   * Gets the world associated with a command sender.
   */
  public World getSenderWorld(CommandSender sender)
  {
    if (sender instanceof Player)
      return ((Player) sender).getWorld();
    if (sender instanceof BlockCommandSender)
      return ((BlockCommandSender) sender).getBlock().getWorld();
    return getConsoleWorld();
  }

  public Scoreboard getWorldScoreboard(World world)
  {
    AutoRefMatch match = this.getMatch(world);
    if (match == null || match.getScoreboard() == null)
      return Bukkit.getScoreboardManager().getMainScoreboard();
    else return match.getScoreboard();
  }

  @Override
  public ChunkGenerator getDefaultWorldGenerator(String worldname, String id)
  { return new NullChunkGenerator(); }

  private SyncMessageTask messageQueue = new SyncMessageTask();

  /**
   * Force a message to be sent synchronously. Safe to use from an asynchronous task.
   *
   * @param msgs messages to be sent
   */
  public void sendMessageSync(CommandSender recipient, String ...msgs)
  {
    if (recipient != null) for (String msg : msgs)
      messageQueue.addMessage(recipient, msg);

    try { messageQueue.runTask(this); }
    catch (IllegalStateException ignored) {  }
  }

  private class SyncMessageTask extends BukkitRunnable
  {
    private class RoutedMessage
    {
      public CommandSender recipient;
      public String message;

      public RoutedMessage(CommandSender r, String m)
      { recipient = r; message = m; }
    }

    private List<RoutedMessage> msgQueue = Lists.newLinkedList();

    public SyncMessageTask addMessage(CommandSender recipient, String message)
    { msgQueue.add(new RoutedMessage(recipient, message)); return this; }

    @Override public void run()
    {
      AutoReferee.this.messageQueue = new SyncMessageTask();
      for (RoutedMessage msg : msgQueue) if (msg.recipient != null)
        msg.recipient.sendMessage(msg.message);
      msgQueue.clear();
    }
  }

  // this is a catch-all to make general upgrades to old configuration files
  private void updateConfigurationFile()
  {
    FileConfiguration config = getConfig();

    // v2.2, 2013/05/04, remove remains of server mode
    if (config.get("server-mode") != null)
      config.set("server-mode", null);

    // v2.3, 2013/05/17, update lobby info
    if (config.getString("lobby-world") != null)
    {
      // set new parameter paths
      config.set("lobby.world", config.getString("lobby-world"));
      config.set("lobby.mode", "manual");

      // remove old configuration flag
      config.set("lobby-world", null);
    }

    // v2.3, 2013/06/03, allow for lobby mode enum (not "auto" boolean)
    if (config.getString("lobby.auto") != null)
    {
      boolean autoMode = config.getBoolean("lobby.auto", false);
      config.set("lobby.mode", autoMode ? "auto" : "manual");
      config.set("lobby.auto", null);
    }
  }
}
TOP

Related Classes of org.mctourney.autoreferee.AutoReferee

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.