Package com.github.zathrus_writer.commandsex.helpers

Source Code of com.github.zathrus_writer.commandsex.helpers.Home

package com.github.zathrus_writer.commandsex.helpers;

import static com.github.zathrus_writer.commandsex.Language._;

import java.io.File;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import com.github.zathrus_writer.commandsex.CommandsEX;
import com.github.zathrus_writer.commandsex.SQLManager;

/***
* Contains set of commands to be executed for home setting/getting purposes.
* @author zathrus-writer
*
*/
public class Home

  public static Boolean multiHomesEnabled = CommandsEX.getConf().getBoolean("allowMultiworldHomes");
  // stores IDs of homes to be removed should a player decide to confirm the /home iclear command
  public static Map<String, List<Object>> clearHomesConfirmation = new HashMap<String, List<Object>>();

  /***
   * INIT - initialization function, called when plugin is enabled to check MyHome database conversion needs.
   * @return
   */
  public static void init(CommandsEX plugin) {
    // first of all, check if we can use any DB
    if (!CommandsEX.sqlEnabled) return;
   
    // next create homes table if it's not present yet
    SQLManager.query("CREATE TABLE IF NOT EXISTS "+ SQLManager.prefix +"homes (id_home integer " + (SQLManager.sqlType.equals("mysql") ? "unsigned " : "") +"NOT NULL" + (SQLManager.sqlType.equals("mysql") ? " AUTO_INCREMENT" : "") +", player_name varchar(32) NOT NULL" + (SQLManager.sqlType.equals("mysql") ? "" : " COLLATE 'NOCASE'") + ", world_name varchar(32) NOT NULL, x double NOT NULL, y double NOT NULL, z double NOT NULL, yaw double NOT NULL, pitch double NOT NULL, is_public BOOLEAN NOT NULL DEFAULT '0', allowed_players text NULL DEFAULT NULL, PRIMARY KEY (id_home), UNIQUE " + (SQLManager.sqlType.equals("mysql") ? "KEY player_name " : "") +"(player_name,world_name))" + (SQLManager.sqlType.equals("mysql") ? " ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='stores home locations and permissions for players' AUTO_INCREMENT=1" : ""));
   
    // upgrade to yaw and pitch-aware, if not upgraded yet
    try {
      Boolean upgradedToYaw = false;
      ResultSet res = SQLManager.query_res((SQLManager.sqlType.equals("mysql") ? "DESCRIBE "+ SQLManager.prefix +"homes" : "PRAGMA table_info("+ SQLManager.prefix +"homes)"));
      while (res.next()) {
        if (res.getString(SQLManager.sqlType.equals("mysql") ? "Field" : "name").equals("yaw")) {
          res.close();
          upgradedToYaw = true;
          break;
        }
      }
      res.close();
     
      if (!upgradedToYaw) {
        // not upgraded yet, upgrade here
        SQLManager.query("ALTER TABLE "+ SQLManager.prefix +"homes ADD COLUMN yaw double NOT NULL DEFAULT 0");
        SQLManager.query("ALTER TABLE "+ SQLManager.prefix +"homes ADD COLUMN pitch double NOT NULL DEFAULT 0");
      }
    } catch (Throwable e) {
      LogHelper.logSevere("[CommandsEX] " + _("dbErrorModuleUnavailable", "") + "homes");
      LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
      return;
    }
   
   
    // check for homes.db file, which is a MyHome sqlite file and if found, start conversion
    File myHomes = new File(plugin.getDataFolder(), "homes.db");
    if (myHomes.exists()) {
      // determine if the table is a valid myHomes table and perform conversion
      if (SQLManager.init_alt("sqlite", "homes.db")) {
        try {
          LogHelper.logInfo("[CommandsEX] " + _("homeConversionStarted", ""));
          ResultSet res = SQLManager.query_res_alt("SELECT * FROM homeTable");
          List<Object> insertParts = new ArrayList<Object>();
          List<Object> insertValues = new ArrayList<Object>();
          // how many records we want to import at once (to prevent SQL overloading)
          Integer flushAfter = 100;
          while (res.next()) {
            insertParts.add("SELECT ? AS 'id_home', ? AS 'player_name', ? AS 'world_name', ? AS 'x', ? AS 'y', ? AS 'z', ? AS 'is_public', ? AS 'allowed_players'");
            insertValues.add(res.getInt("id"));
            insertValues.add(res.getString("name"));
            insertValues.add(res.getString("world"));
            insertValues.add(res.getDouble("x"));
            insertValues.add(res.getDouble("y"));
            insertValues.add(res.getDouble("z"));
            insertValues.add(res.getBoolean("publicAll"));
            insertValues.add(res.getString("permissions"));
           
            // flush SQL if we reached number of records
            if (insertParts.size() == flushAfter) {
              SQLManager.query("INSERT "+ (SQLManager.sqlType.equals("mysql") ? "" : "OR ") +"IGNORE INTO " + SQLManager.prefix + "homes "+ Utils.implode(insertParts, " UNION "), insertValues);
              insertParts.clear();
              insertValues.clear();
            }
          }
          res.close();
         
          // now do the actual insert :)
          if (insertParts.size() > 0) {
            SQLManager.query("INSERT "+ (SQLManager.sqlType.equals("mysql") ? "" : "OR ") +"IGNORE INTO " + SQLManager.prefix + "homes "+ Utils.implode(insertParts, " UNION "), insertValues);
          }
          SQLManager.close_alt();
        } catch (Throwable e) {
          // unable to convert, tell user
          LogHelper.logSevere("[CommandsEX] " + _("homeConversionFailed", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
          return;
        }
      }
      // rename homes.db to homes.db.done, so we don't attempt to convert again
      myHomes.renameTo(new File(plugin.getDataFolder(), "homes.db.done"));
     
      // all done, inform about successful conversion in the console
      LogHelper.logInfo("[CommandsEX] " + _("homeConversionDone", ""));
    }
  }
 
  /***
   * SETHOME - sets home location for a player provided he's played the required amount of time on the server.
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean setHome(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;

      // check if player is not spamming the command too much
      if (!Utils.checkCommandSpam(player, "sethome")) {
        String pName = player.getName();
        // check if the player has been on the server long enough
        Integer hTime = CommandsEX.getConf().getInt("homeQualifyTime");
        if (Permissions.checkPermEx(player, "cex.bypasshomequalify") || (CommandsEX.playTimes.containsKey(pName) && (CommandsEX.playTimes.get(pName) >= hTime))) {
          // all ok, let's save our home
          Location l = player.getLocation();
         
          // all done :-)
          if (setHome(pName, l)) {
            // home successfuly created
            LogHelper.showInfo("homeSetComplete#####[" + Nicknames.getNick(pName) + "!", sender);
          } else {
            // an error has occured...
            LogHelper.showWarning("internalError", sender);
          }
        } else {
          // player did not play long enough
          try {
            Class.forName("com.github.zathrus_writer.commandsex.handlers.Handler_setbedhome");
            LogHelper.showInfo("homeInsufficientPlayTime", sender);
          } catch (Throwable e) {
            LogHelper.showInfo("homeInsufficientPlayTimeNoBeds", sender);
          }
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /**
   * This method actually sets the home for the player and deletes all other homes
   * if allowMultiworldHomes are disabled
   * @param pName
   * @param l
   * @return
   */
 
  public static boolean setHome(String pName, Location l){
    // if player cannot have multiworld homes, we need to delete their home first
    if (!CommandsEX.getConf().getBoolean("allowMultiworldHomes")) {
      SQLManager.query("DELETE FROM " + SQLManager.prefix + "homes WHERE player_name = ?", pName);
    }
   
    return SQLManager.query("INSERT "+ (SQLManager.sqlType.equals("mysql") ? "" : "OR REPLACE ") +"INTO " + SQLManager.prefix + "homes (player_name, world_name, x, y, z, yaw, pitch) VALUES(?, ?, ?, ?, ?, ?, ?)" + (SQLManager.sqlType.equals("mysql") ? " ON DUPLICATE KEY UPDATE x = VALUES(x), y = VALUES(y), z = VALUES(z), yaw = VALUES(yaw), pitch = VALUES(pitch)" : ""), pName, l.getWorld().getName(), l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
  }
 
  /***
   * HOME - teleports a player to their home location or a home location of another player
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean home(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;

      // get home data from DB, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-go")) {
        String pName = player.getName();
        String homePlayerName = "";
        // determine whose home we're trying to get to
        if (args.length > 0) {
          // going to friend's home
          homePlayerName = args[0];
        } else {
          // going to our home
          homePlayerName = pName;
        }
       
        try {
          String homePlayerForSQL = homePlayerName.toLowerCase();
          String foundPlayerName = "";
          Integer numHomes = 0;
          Location l = null;
          ResultSet res;
         
          if (multiHomesEnabled) {
            // if multiple homes are enabled, we check for a home in player's current world
            res = SQLManager.query_res("SELECT * FROM " + SQLManager.prefix + "homes WHERE (player_name = ? OR player_name LIKE ?) AND world_name = ? LIMIT 2", homePlayerForSQL, homePlayerForSQL + "%", player.getWorld().getName());
          } else {
            // multiple homes disabled, we check for player's home anywhere
            res = SQLManager.query_res("SELECT * FROM " + SQLManager.prefix + "homes WHERE (player_name = ? OR player_name LIKE ?) LIMIT 2", homePlayerForSQL, homePlayerForSQL + "%");
          }

          while (res.next()) {
            numHomes++;
            foundPlayerName = res.getString("player_name");
            res.getString("allowed_players");
            Boolean noPlayers = res.wasNull();
            // check if player is allowed to go to this home
            if (!Permissions.checkPermEx(player, "cex.bypassinvite") && !res.getBoolean("is_public") && !res.getString("player_name").equals(sender.getName()) && (noPlayers || (!noPlayers && !res.getString("allowed_players").equals(pName) && !res.getString("allowed_players").contains("," + pName) && !res.getString("allowed_players").contains(pName + ",")))) {
              // player is not allowed in
              LogHelper.showWarning("homeNotAllowed" + (multiHomesEnabled ? "#####homeInCurrentWorld" : ""), sender);
              return true;
            }

            // assemble location for the home
            l = new Location(CommandsEX.plugin.getServer().getWorld(res.getString("world_name")), res.getDouble("x"), res.getDouble("y"), res.getDouble("z"), (float) res.getDouble("yaw"), (float) res.getDouble("pitch"));
            if (l.getWorld() == null){
              LogHelper.showInfo("homeWorldNotExist", sender, ChatColor.RED);
              return true;
            }
           
            // if the name matches exactly what we've been looking for, adjust numHomes and break the loop
            if (foundPlayerName.toLowerCase().equals(homePlayerForSQL)) {
              numHomes = 1;
              break;
            }
          }
          res.close();

          if (numHomes > 1) {
            // too many players match the selection
            numHomes = 0;
            foundPlayerName = homePlayerName;
          } else if (numHomes == 1) {
            // teleport player home and welcome him :-)
            Teleportation.delayedTeleport(player, l);
            LogHelper.showInfo((pName.equals(homePlayerName) ? "homeSetComplete#####[" + Nicknames.getNick(pName) + "!" : "homeWelcomeTo#####[" + Nicknames.getNick(foundPlayerName) + "#####homePlayersHome"), sender);
            return true;
          }
         
          // if player's home was not found, show message
          if (numHomes == 0) {
            if (pName.equals(homePlayerName)) {
              if (multiHomesEnabled) {
                LogHelper.showInfos(sender, new String[] {"homeNoHomeOwnerCurrentWorld1", "homeNoHomeOwnerCurrentWorld2"});
              } else {
                LogHelper.showInfos(sender, new String[] {"homeNoHomeOwner1", "homeNoHomeOwner2"});
              }
            } else {
              LogHelper.showInfo("[" + Nicknames.getNick(homePlayerName) + " #####homeNoHomeVisitor" + (multiHomesEnabled ? "#####homeInCurrentWorld" : ""), sender);
            }
          }
        } catch (Throwable e) {
          // unable to load players' home
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
          return true;
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
 
  /***
   * INVITE - invites a player to your home
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean invite(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // save invite, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-invite")) {
        String pName = player.getName();
        if (args.length == 1) {
          // no arguments, provide command help
          Commands.showCommandHelpAndUsage(sender, "cex_home", "home_invite");
          return true;
        }
       
        try {
          ResultSet res;
          if (multiHomesEnabled) {
            // if multiple homes are enabled, we check for a home in player's current world
            res = SQLManager.query_res("SELECT id_home, allowed_players FROM " + SQLManager.prefix + "homes WHERE player_name = ? AND world_name = ?", pName, player.getWorld().getName());
          } else {
            // multiple homes disabled, we check for player's home anywhere
            res = SQLManager.query_res("SELECT id_home, allowed_players FROM " + SQLManager.prefix + "homes WHERE player_name = ?", pName);
          }

          while (res.next()) {
            String allowedPlayers;
            if ((res.getString("allowed_players") != null) && !res.getString("allowed_players").equals("") && !res.wasNull()) {
              allowedPlayers = res.getString("allowed_players");
              if (!allowedPlayers.equals(args[1]) && !allowedPlayers.contains("," + args[1]) && !allowedPlayers.contains(args[1] + ",")) {
                allowedPlayers = allowedPlayers + "," + args[1];
              } else {
                // player already invited
                LogHelper.showInfos(sender, "[" + args[1] + " #####homePlayerAlreadyInvited2#####[" + pName + "#####homePlayerAlreadyInvited3");
                return true;
              }
            } else {
              allowedPlayers = args[1];
            }

            // update the DB with new allowed_players value
            SQLManager.query("UPDATE " + SQLManager.prefix + "homes SET allowed_players = ? WHERE id_home = ?", allowedPlayers, res.getInt("id_home"));
           
            // inform user that his friend was invited
            LogHelper.showInfos(sender, "[" + Nicknames.getNick(args[1]) + " #####homeInviteSuccessful");
           
            // if the actual friend is online, inform him as well
            Player p = Bukkit.getServer().getPlayer(args[1]);
            if (p != null) {
              LogHelper.showInfos(p, "homeYouHaveBeenInvited1#####[" + Nicknames.getNick(pName) + "#####homeYouHaveBeenInvited2", "homeYouHaveBeenInvited3#####[" + Nicknames.getNick(pName) + " #####homeYouHaveBeenInvited4");
            }
           
            // return here, since we can only invite to a single home
            res.close();
            return true;
          }

          // if we're here, it means no home was found for our player in current world... so we tell him
          if (multiHomesEnabled) {
            LogHelper.showInfos(sender, new String[] {"homeNoHomeOwnerCurrentWorld1", "homeNoHomeOwnerCurrentWorld2"});
          } else {
            LogHelper.showInfos(sender, new String[] {"homeNoHomeOwner1", "homeNoHomeOwner2"});
          }
        } catch (Throwable e) {
          // unable to load players' home
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
          return true;
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * UNINVITE - uninvites a player from your home
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean uninvite(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // remove the requested invite, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-uninvite")) {
        String pName = player.getName();
        if (args.length == 1) {
          // no arguments, provide command help
          Commands.showCommandHelpAndUsage(sender, "cex_home", "home_uninvite");
          return true;
        }
       
        try {
          ResultSet res;
          if (multiHomesEnabled) {
            // if multiple homes are enabled, we uninvite from home in player's current world
            res = SQLManager.query_res("SELECT id_home, allowed_players FROM " + SQLManager.prefix + "homes WHERE player_name = ? AND world_name = ?", pName, player.getWorld().getName());
          } else {
            // multiple homes disabled, we uninvite from player's home anywhere
            res = SQLManager.query_res("SELECT id_home, allowed_players FROM " + SQLManager.prefix + "homes WHERE player_name = ?", pName);
          }

          while (res.next()) {
            List<Object> newAllowedPlayers = new ArrayList<Object>();
            Boolean playerFound = false;
            if ((res.getString("allowed_players") != null) && !res.getString("allowed_players").equals("") && !res.wasNull()) {
              String[] allowedPlayers = res.getString("allowed_players").split(",");
              for (String s : allowedPlayers) {
                if (!s.equals(args[1])) {
                  newAllowedPlayers.add(s);
                } else {
                  playerFound = true;
                }
              }
             
              // the requested player is not invited to this home
              if (!playerFound) {
                LogHelper.showInfo("[" + Nicknames.getNick(args[1]) + " #####homePlayerUninviteNotFound", sender);
                return true;
              }
            } else {
              // no invited players
              LogHelper.showInfo("homeNoPlayersInvited", sender);
              return true;
            }

            // update the DB with new newAllowedPlayers value
            SQLManager.query("UPDATE " + SQLManager.prefix + "homes SET allowed_players = ? WHERE id_home = ?", Utils.implode(newAllowedPlayers, ","), res.getInt("id_home"));
           
            // inform user that the player was uninvited
            LogHelper.showInfos(sender, "[" + Nicknames.getNick(args[1]) + " #####homePlayerUninvited");
           
            // if the actual player is online, inform him as well
            Player p = Bukkit.getServer().getPlayer(args[1]);
            if (p != null) {
              LogHelper.showInfos(p, "homePlayerUninviteNotify#####[" + Nicknames.getNick(pName) + "#####homeYouHaveBeenInvited2");
            }
           
            // return here, since we can only uninvite a single player
            res.close();
            return true;
          }

          // if we're here, it means no home was found for our player in current world... so we tell him
          if (multiHomesEnabled) {
            LogHelper.showInfos(sender, new String[] {"homeNoHomeOwnerCurrentWorld1", "homeNoHomeOwnerCurrentWorld2"});
          } else {
            LogHelper.showInfos(sender, new String[] {"homeNoHomeOwner1", "homeNoHomeOwner2"});
          }
        } catch (Throwable e) {
          // unable to load players' home
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
          return true;
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * single-purpose class used to run /home list command, since we don't have index on allowed_players
   * field and it could take a while to determine to which homes a player is invited
   */
  static class ListInvitedHomes implements Runnable {
   
    private CommandSender sender;
   
    public ListInvitedHomes(CommandSender s) {
      this.sender = s;
    }
   
    @Override
    public void run() {
      Player player = (Player)this.sender;
      String pName = player.getName();
      Boolean multiHomesEnabled = Home.multiHomesEnabled;

      try {
        ResultSet res = SQLManager.query_res("SELECT player_name, world_name FROM " + SQLManager.prefix + "homes WHERE allowed_players = ? OR allowed_players LIKE ? OR allowed_players LIKE ?", pName, pName + ",%", "%," + pName);
        List<Object> homes = new ArrayList<Object>();
        while (res.next()) {
          homes.add(Nicknames.getNick(res.getString("player_name")) + (multiHomesEnabled ? " (" + res.getString("world_name") + ")" : ""));
        }
        res.close();

        if (homes.size() > 0) {
          // tell player to whose homes he's invited
          LogHelper.showInfo("homeInvitedTo#####[ " + Utils.implode(homes, ", "), sender);
        } else {
          // the player is not invited into anybody's home
          LogHelper.showInfo("homeNotInvitedToAnyHome", sender);
        }
      } catch (Throwable e) {
        // something went wrong with our SQL...
        LogHelper.showWarning("internalError", sender);
        LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
        LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
      }
    }
  }
 
  /***
   * LIST - display whose homes a player can visit
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean list(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // check to which homes is player invited, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-list")) {
        // create ExecutorService to manage threads                       
        ExecutorService threadExecutor = Executors.newFixedThreadPool(1);
        threadExecutor.execute(new ListInvitedHomes(sender)); // execute the LIST command thread
        threadExecutor.shutdown(); // shutdown worker threads
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * ILIST - display everyone invited to player's home
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean ilist(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // check who is invited to player's home, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-ilist")) {
        try {
          String pName = player.getName();
          // holds players invited to homes in nickname form
          List<String> nickPlayers = new ArrayList<String>();
          ResultSet res;
          if (multiHomesEnabled) {
            res = SQLManager.query_res("SELECT allowed_players FROM " + SQLManager.prefix + "homes WHERE player_name = ? AND world_name = ?", pName, player.getWorld().getName());
          } else {
            res = SQLManager.query_res("SELECT allowed_players FROM " + SQLManager.prefix + "homes WHERE player_name = ?", pName);
          }
         
          while (res.next()) {
            for (String s : Utils.separateCommaList(res.getString("allowed_players").replace(",", ", "))){
              nickPlayers.add(Nicknames.getNick(s));
            }
          }
          res.close();

          if (nickPlayers.size() > 0) {
            // tell player who is invited to his home
            LogHelper.showInfo("homeInvotedToYourHome" + (multiHomesEnabled ? "[ #####homeInCurrentWorld" : "") + "#####[: " + Utils.implode(nickPlayers, ", "), sender);
          } else {
            // the player is not invited into anybody's home
            LogHelper.showInfo("homeNoPlayersInvited1" + (multiHomesEnabled ? "#####homeInCurrentWorld#####[ " : "") + "#####homeNoPlayersInvited2", sender);
          }
        } catch (Throwable e) {
          // something went wrong with our SQL...
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * LISTALL - lists all homes created on the server
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean listall(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // check who is invited to player's home, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-listall")) {
        try {
          // holds the names of players with houses in nickname form
          List<Object> homes = new ArrayList<Object>();
          ResultSet res;
          res = SQLManager.query_res("SELECT player_name, world_name FROM " + SQLManager.prefix + "homes");
          while (res.next()) {
            homes.add(Nicknames.getNick(res.getString("player_name")) + (multiHomesEnabled ? " (" + res.getString("world_name") + ")" : ""));
          }
          res.close();

          if (homes.size() > 0) {
            // show all homes
            LogHelper.showInfo("homeAllHomes#####[" + Utils.implode(homes, ", "), sender);
          } else {
            // no homes on the server
            LogHelper.showInfo("homeNoPlayersInvited1" + (multiHomesEnabled ? "#####[ #####homeInCurrentWorld#####[ " : "") + "#####homeNoPlayersInvited2", sender);
          }
        } catch (Throwable e) {
          // something went wrong with our SQL...
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * PUBLIC - makes player's home public
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean make_public(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // make player's home public, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-public")) {
        try {
          String pName = player.getName();
          Boolean homeFound = false;
          ResultSet res;

          // let's see if the player has any home set
          if (multiHomesEnabled) {
            res = SQLManager.query_res("SELECT id_home FROM " + SQLManager.prefix + "homes WHERE player_name = ? AND world_name = ?", pName, player.getWorld().getName());
          } else {
            res = SQLManager.query_res("SELECT id_home FROM " + SQLManager.prefix + "homes WHERE player_name = ?", pName);
          }
         
          while (res.next()) {
            SQLManager.query("UPDATE " + SQLManager.prefix + "homes SET is_public = 1 WHERE id_home = ?", res.getInt("id_home"));
            homeFound = true;
          }
          res.close();

          if (homeFound) {
            // inform player about successful operation
            LogHelper.showInfos(sender, new String[] {"homeYourHome#####[ " + (multiHomesEnabled ? "#####homeInCurrentWorld#####[ " : "") + "#####homeMadePublic1", "homeMadePublic2#####[" + pName});
          } else {
            // if we're here, it means no home was found for our player in current world... so we tell him
            if (multiHomesEnabled) {
              LogHelper.showInfos(sender, new String[] {"homeNoHomeOwnerCurrentWorld1", "homeNoHomeOwnerCurrentWorld2"});
            } else {
              LogHelper.showInfos(sender, new String[] {"homeNoHomeOwner1", "homeNoHomeOwner2"});
            }
          }
        } catch (Throwable e) {
          // something went wrong with our SQL...
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * PRIVATE - makes player's home private
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean make_private(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // make player's home public, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-private")) {
        try {
          String pName = player.getName();
          Boolean homeFound = false;
          ResultSet res;

          // let's see if the player has any home set
          if (multiHomesEnabled) {
            res = SQLManager.query_res("SELECT id_home FROM " + SQLManager.prefix + "homes WHERE player_name = ? AND world_name = ?", pName, player.getWorld().getName());
          } else {
            res = SQLManager.query_res("SELECT id_home FROM " + SQLManager.prefix + "homes WHERE player_name = ?", pName);
          }
         
          while (res.next()) {
            SQLManager.query("UPDATE " + SQLManager.prefix + "homes SET is_public = 0 WHERE id_home = ?", res.getInt("id_home"));
            homeFound = true;
          }
          res.close();

          if (homeFound) {
            // inform player about successful operation
            LogHelper.showInfo("homeYourHome#####[ " + (multiHomesEnabled ? "#####homeInCurrentWorld#####[ " : "") + "#####homeMadePrivate", sender);
          } else {
            // if we're here, it means no home was found for our player in current world... so we tell him
            if (multiHomesEnabled) {
              LogHelper.showInfos(sender, new String[] {"homeNoHomeOwnerCurrentWorld1", "homeNoHomeOwnerCurrentWorld2"});
            } else {
              LogHelper.showInfos(sender, new String[] {"homeNoHomeOwner1", "homeNoHomeOwner2"});
            }
          }
        } catch (Throwable e) {
          // something went wrong with our SQL...
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * DELETE - removes player's home
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean delete(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // delete player's home, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-delete")) {
        try {
          // check if we're having player's name passed as a parameter, in which case that'll be our home to delete
          String pName = "";
          if (args.length > 1) {
            pName = args[1];
          } else {
            pName = player.getName();
          }
          List<Object> homeIds = new ArrayList<Object>();
          ResultSet res;

          // let's see if the player has any home set
          if (multiHomesEnabled) {
            res = SQLManager.query_res("SELECT id_home FROM " + SQLManager.prefix + "homes WHERE player_name = ? AND world_name = ?", pName, player.getWorld().getName());
          } else {
            res = SQLManager.query_res("SELECT id_home FROM " + SQLManager.prefix + "homes WHERE player_name = ?", pName);
          }
         
          // assemble list of home IDs to delete
          while (res.next()) {
            homeIds.add(res.getInt("id_home"));
          }
          res.close();
         
          // remove homes
          Integer hSize = homeIds.size();
          if (hSize > 0) {
            String[] qMarks = new String[hSize];
            Arrays.fill(qMarks, "?");
            SQLManager.query("DELETE FROM " + SQLManager.prefix + "homes WHERE id_home IN ("+ Utils.implode(qMarks, ",") +")", homeIds);
            // inform player about successful operation
            LogHelper.showInfo("home#####[ " + (multiHomesEnabled ? "#####homeInCurrentWorld#####[ " : "") + "#####homeDeleted", sender);
          } else {
            if (args.length == 1) {
              if (multiHomesEnabled) {
                LogHelper.showInfos(sender, new String[] {"homeNoHomeOwnerCurrentWorld1", "homeNoHomeOwnerCurrentWorld2"});
              } else {
                LogHelper.showInfos(sender, new String[] {"homeNoHomeOwner1", "homeNoHomeOwner2"});
              }
            } else {
              LogHelper.showInfo("[" + Nicknames.getNick(pName) + " #####homeNoHomeVisitor" + (multiHomesEnabled ? "#####homeInCurrentWorld" : ""), sender);
            }
          }
        } catch (Throwable e) {
          // something went wrong with our SQL...
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }

  /***
   * single-purpose class used to run /home iclear command, since it can take a while to compare
   * all homes against offline player records
   */
  static class ClearOldHomes implements Runnable {
   
    private Integer daysToPast;
    private CommandSender sender;
   
    public ClearOldHomes(CommandSender s, Integer d) {
      this.sender = s;
      this.daysToPast = d;
    }
   
    @Override
    public void run() {
      try {
        ResultSet res = SQLManager.query_res("SELECT id_home, player_name FROM " + SQLManager.prefix + "homes");
        List<Object> toClear = new ArrayList<Object>();
        // convert days into seconds
        Integer daysInSeconds = (this.daysToPast * 24 * 60 * 60);
        // get current Unix timestamp
        Integer stamp = Utils.getUnixTimestamp(0L);

        while (res.next()) {
          // get player's last join time
          OfflinePlayer o = CommandsEX.plugin.getServer().getOfflinePlayer(res.getString("player_name"));
          Integer lastJoinTime = Utils.getUnixTimestamp(o.getLastPlayed());
         
          // compare last join time with our requested number of days to past
          if ((stamp - lastJoinTime) >= daysInSeconds) {
            toClear.add(res.getInt("id_home"));
          }
        }
        res.close();

        if (toClear.size() > 0) {
          // we have found some homes to clean up, ask player to confirm deletion
          Home.clearHomesConfirmation.put(this.sender.getName(), toClear);
          LogHelper.showInfo("homeClearConfirm1#####[" + toClear.size() + "#####[ #####homeClearConfirm2#####[" + this.daysToPast + "#####[ #####homeClearConfirm3", sender);
        } else {
          // no homes found matching criteria
          LogHelper.showInfo("homeClearNoHomes", sender);
        }
      } catch (Throwable e) {
        // something went wrong with our SQL...
        LogHelper.showWarning("internalError", sender);
        LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
        LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
      }
    }
  }
 
  /***
   * ICLEAR - clears all homes older than given number of days from the database
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean iclear(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // select all homes to be cleared up, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-iclear")) {
        if (args.length == 1) {
          // no arguments, provide command help
          Commands.showCommandHelpAndUsage(sender, "cex_home", "home_iclear");
          return true;
        }
       
        // check if the number of days is integer value
        if (!args[1].matches(CommandsEX.intRegex)) {
          LogHelper.showInfo("homeClearDaysNotNumeric", sender);
          return true;
        }
       
        // create ExecutorService to manage threads                       
        ExecutorService threadExecutor = Executors.newFixedThreadPool(1);
        threadExecutor.execute(new ClearOldHomes(sender, Integer.parseInt(args[1]))); // execute the ICLEAR command thread
        threadExecutor.shutdown(); // shutdown worker threads
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * TCLEAR - teleports player to first home that would be cleared if /home iclear <days> would be run
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean tclear(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      Player player = (Player)sender;
     
      // teleport to first clear-up-eligible home, if we didn't spam too much :)
      if (!Utils.checkCommandSpam(player, "home-tclear")) {
        if (args.length == 1) {
          // no arguments, provide command help
          Commands.showCommandHelpAndUsage(sender, "cex_home", "home_tclear");
          return true;
        }
       
        // check if the number of days is integer value
        if (!args[1].matches(CommandsEX.intRegex)) {
          LogHelper.showInfo("homeClearDaysNotNumeric", sender);
          return true;
        }
       
        try {
          ResultSet res = SQLManager.query_res("SELECT player_name, world_name, x, y, z, yaw, pitch FROM " + SQLManager.prefix + "homes");
          // convert days into seconds
          Integer daysInSeconds = (Integer.parseInt(args[1]) * 24 * 60 * 60);
          // get current Unix timestamp
          Integer stamp = Utils.getUnixTimestamp(0L);

          while (res.next()) {
            // get player's last join time
            OfflinePlayer o = CommandsEX.plugin.getServer().getOfflinePlayer(res.getString("player_name"));
            Integer lastJoinTime = Utils.getUnixTimestamp(o.getLastPlayed());
           
            // compare last join time with our requested number of days to past
            if ((stamp - lastJoinTime) >= daysInSeconds) {
              // match found, teleport player
              Teleportation.delayedTeleport(player, new Location(CommandsEX.plugin.getServer().getWorld(res.getString("world_name")), res.getInt("x"), res.getInt("y"), res.getInt("z"), (float) res.getDouble("yaw"), (float) res.getDouble("pitch")) );
              // tell player where he is
              LogHelper.showInfo("homeWelcomeTo#####[" + Nicknames.getNick(res.getString("player_name")) + "#####homePlayersHome", sender);
              res.close();
              return true;
            }
          }
          res.close();

          // if we get here, there were no homes found matching criteria
          LogHelper.showInfo("homeClearNoHomes", sender);
        } catch (Throwable e) {
          // something went wrong with our SQL...
          LogHelper.showWarning("internalError", sender);
          LogHelper.logSevere("[CommandsEX] " + _("dbReadError", ""));
          LogHelper.logDebug("Message: " + e.getMessage() + ", cause: " + e.getCause());
        }
      }
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
 
  /***
   * HELP - displays homes usage
   * @param sender
   * @param args
   * @param command
   * @param alias
   * @return
   */
  public static Boolean help(CommandSender sender, String[] args, String command, String alias) {
    if (CommandsEX.sqlEnabled) {
      // show help
      LogHelper.showInfos(sender, "homeHelp1", "homeHelp2", "homeHelp3", "homeHelp4", "homeHelp5", "homeHelp6", "homeHelp7", "homeHelp8", "homeHelp9", "homeHelp10", "homeHelp11", "homeHelp12", "homeHelp13", "homeHelp14", "homeHelp15", "homeHelp16");
    } else {
      // no database, no homes
      LogHelper.showInfo("homeNoDatabase", sender);
    }
   
        return true;
  }
}
TOP

Related Classes of com.github.zathrus_writer.commandsex.helpers.Home

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.