Пример #1
0
  private void handleFirstJoin(Player p) {
    if (!NameLayerPlugin.createGroupOnFirstJoin()) {
      return;
    }
    if (NameLayerPlugin.getDefaultGroupHandler().getDefaultGroup(p) != null) {
      // assume something went wrong, feel free to chose a random civcraft dev to blame
      return;
    }
    final UUID uuid = p.getUniqueId();
    final String name = p.getName();

    new NewfriendCreate(name, uuid).bootstrap();
  }
Пример #2
0
 private void changePlayerRank(UUID toChange, PlayerType newRank) {
   if (gm.hasAccess(g, p.getUniqueId(), getAccordingPermission(g.getCurrentRank(toChange)))) {
     if (!g.isMember(toChange)) {
       p.sendMessage(
           ChatColor.RED
               + "This player is no longer on the group and can't be "
               + demoteOrPromote(g.getCurrentRank(toChange), newRank, false)
               + "d");
       return;
     }
     if (g.isOwner(toChange)) {
       p.sendMessage(ChatColor.RED + "This player owns the group and can't be demoted");
     }
     OfflinePlayer prom = Bukkit.getOfflinePlayer(toChange);
     NameLayerPlugin.log(
         Level.INFO,
         p.getName()
             + " changed player rank for "
             + NameAPI.getCurrentName(toChange)
             + " from "
             + g.getCurrentRank(toChange).toString()
             + " to "
             + newRank.toString()
             + " for group "
             + g.getName()
             + "via gui");
     if (prom.isOnline()) {
       Player oProm = (Player) prom;
       PromotePlayerEvent event =
           new PromotePlayerEvent(oProm, g, g.getCurrentRank(toChange), newRank);
       Bukkit.getPluginManager().callEvent(event);
       if (event.isCancelled()) {
         p.sendMessage(
             ChatColor.RED + "Could not change player rank, you should complain about this");
         return;
       }
       g.removeMember(toChange);
       g.addMember(toChange, newRank);
       oProm.sendMessage(
           ChatColor.GREEN
               + "You have been promoted to "
               + getRankName(toChange)
               + " in (Group) "
               + g.getName());
     } else {
       // player is offline change their perms
       g.removeMember(toChange);
       g.addMember(toChange, newRank);
     }
     p.sendMessage(
         ChatColor.GREEN
             + NameAPI.getCurrentName(toChange)
             + " has been "
             + demoteOrPromote(g.getCurrentRank(toChange), newRank, false)
             + "d to "
             + getRankName(toChange));
   } else {
     p.sendMessage(ChatColor.RED + "You have lost permission to remove this player");
   }
 }
Пример #3
0
  @EventHandler(priority = EventPriority.LOWEST)
  public void playerJoinEvent(PlayerJoinEvent event) {
    Player p = event.getPlayer();
    UUID uuid = p.getUniqueId();

    if (!p.hasPlayedBefore()) {
      handleFirstJoin(p);
    }

    if (!notifications.containsKey(uuid) || notifications.get(uuid).isEmpty()) return;

    String x = null;

    boolean shouldAutoAccept = NameLayerPlugin.getAutoAcceptHandler().getAutoAccept(uuid);
    if (shouldAutoAccept) {
      x = "You have auto-accepted invitation from the following groups while you were away: ";
    } else {
      x =
          "You have been invited to the following groups while you were away. You can accept each invitation by using the command: /nlag [groupname].  ";
    }

    for (Group g : notifications.get(uuid)) {
      x += g.getName() + ", ";
    }
    x = x.substring(0, x.length() - 2);
    x += ".";
    p.sendMessage(ChatColor.YELLOW + x);
  }
Пример #4
0
 public void setAutoAccept(UUID player, boolean accept, boolean persistToDb) {
   if (accept && !autoAccepts.contains(player)) {
     autoAccepts.add(player);
     if (persistToDb) {
       NameLayerPlugin.getGroupManagerDao().autoAcceptGroupsAsync(player);
       Mercury.addAutoAccept(player);
     }
   } else {
     if (autoAccepts.contains(player)) {
       autoAccepts.remove(player);
       if (persistToDb) {
         NameLayerPlugin.getGroupManagerDao().removeAutoAcceptGroupAsync(player);
         Mercury.removeAutoAccept(player);
       }
     }
   }
 }
Пример #5
0
 @Override
 public void run() {
   Group g = getGroup();
   if (g.getGroupId() == -1) { // now try + num
     NameLayerPlugin.log(
         Level.WARNING,
         "Newfriend automatic group creation failed for " + g.getName() + " " + uuid);
     GroupManager gm = NameAPI.getGroupManager();
     if (inc == null) {
       inc = 0;
     } else {
       inc++;
     }
     if (inc < 20) {
       String newName = name + String.valueOf(inc);
       gm.createGroupAsync(new Group(newName, uuid, false, null, -1), this, true);
     }
   } else {
     NameLayerPlugin.log(
         Level.WARNING,
         "Newfriend automatic group creation succeeded for " + g.getName() + " " + uuid);
     g.setDefaultGroup(uuid);
   }
 }
Пример #6
0
 private void removeMember(UUID toRemove) {
   if (gm.hasAccess(g, p.getUniqueId(), getAccordingPermission(g.getCurrentRank(toRemove)))) {
     if (!g.isMember(toRemove)) {
       p.sendMessage(ChatColor.RED + "This player is no longer on the group and can't be removed");
       return;
     }
     if (g.isOwner(toRemove)) {
       p.sendMessage(ChatColor.RED + "This player owns the group and can't be removed");
     }
     NameLayerPlugin.log(
         Level.INFO,
         p.getName()
             + " kicked "
             + NameAPI.getCurrentName(toRemove)
             + " from "
             + g.getName()
             + "via gui");
     g.removeMember(toRemove);
     p.sendMessage(
         ChatColor.GREEN + NameAPI.getCurrentName(toRemove) + " has been removed from the group");
   } else {
     p.sendMessage(ChatColor.RED + "You have lost permission to remove this player");
   }
 }
Пример #7
0
  /**
   * Creates a list of all Clickables representing members, invitees and blacklisted players, if
   * they are supposed to be displayed. This is whats directly fed into the middle of the gui
   */
  private List<Clickable> constructClickables() {
    List<Clickable> clicks = new ArrayList<Clickable>();
    if (showInheritedMembers) {
      if (g.hasSuperGroup()) {
        clicks.addAll(getRecursiveInheritedMembers(g.getSuperGroup()));
      }
    }
    if (showBlacklist) {
      final BlackList black = NameLayerPlugin.getBlackList();
      for (final UUID uuid : black.getBlacklist(g)) {
        ItemStack is = new ItemStack(Material.LEATHER_CHESTPLATE);
        LeatherArmorMeta meta = (LeatherArmorMeta) is.getItemMeta();
        meta.setColor(Color.BLACK);
        meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
        is.setItemMeta(meta);
        ISUtils.setName(is, NameAPI.getCurrentName(uuid));
        Clickable c;
        if (gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("BLACKLIST"))) {
          ISUtils.addLore(
              is,
              ChatColor.GREEN + "Click to remove " + NameAPI.getCurrentName(uuid),
              ChatColor.GREEN + "from the blacklist");
          c =
              new Clickable(is) {

                @Override
                public void clicked(Player arg0) {
                  if (gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("BLACKLIST"))) {
                    NameLayerPlugin.log(
                        Level.INFO,
                        arg0.getName()
                            + " removed "
                            + NameAPI.getCurrentName(uuid)
                            + " from the blacklist of "
                            + g.getName()
                            + "via gui");
                    black.removeBlacklistMember(g, uuid, true);
                    p.sendMessage(
                        ChatColor.GREEN
                            + "You removed "
                            + NameAPI.getCurrentName(uuid)
                            + " from the blacklist");
                  } else {
                    p.sendMessage(
                        ChatColor.RED
                            + "You lost permission to remove this player from the blacklist");
                  }
                  showScreen();
                }
              };
        } else {
          ISUtils.addLore(
              is,
              ChatColor.RED + "You dont have permission to remove",
              ChatColor.RED + NameAPI.getCurrentName(uuid) + "from the blacklist");
          c = new DecorationStack(is);
        }
        clicks.add(c);
      }
    }
    if (showInvites) {
      Map<UUID, PlayerType> invites =
          NameLayerPlugin.getGroupManagerDao().getInvitesForGroup(g.getName());
      for (Entry<UUID, PlayerType> entry : invites.entrySet()) {
        ItemStack is = new ItemStack(Material.CHAINMAIL_CHESTPLATE);
        ItemMeta im = is.getItemMeta();
        im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
        is.setItemMeta(im);
        final String playerName = NameAPI.getCurrentName(entry.getKey());
        ISUtils.setName(is, ChatColor.GOLD + playerName);
        boolean canRevoke = false;
        switch (entry.getValue()) {
          case MEMBERS:
            ISUtils.addLore(is, ChatColor.AQUA + "Invited as: Member");
            if (gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("MEMBERS"))) {
              canRevoke = true;
            }
            break;
          case MODS:
            ISUtils.addLore(is, ChatColor.AQUA + "Invited as: Mod");
            if (gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("MODS"))) {
              canRevoke = true;
            }
            break;
          case ADMINS:
            ISUtils.addLore(is, ChatColor.AQUA + "Invited as: Admin");
            if (gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("ADMINS"))) {
              canRevoke = true;
            }
            break;
          case OWNER:
            ISUtils.addLore(is, ChatColor.AQUA + "Invited as: Owner");
            if (gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("OWNER"))) {
              canRevoke = true;
            }
            break;
          default:
            continue;
        }
        Clickable c = null;
        if (canRevoke) {
          ISUtils.addLore(is, ChatColor.GREEN + "Click to revoke this invite");
          c =
              new Clickable(is) {

                @Override
                public void clicked(Player arg0) {
                  UUID invitedUUID = NameAPI.getUUID(playerName);
                  PlayerType pType = g.getInvite(invitedUUID);
                  if (pType == null) {
                    p.sendMessage(
                        ChatColor.RED
                            + "Failed to revoke invite for "
                            + playerName
                            + ". This player isn't invited currently.");
                    showScreen();
                  }
                  // make sure the player still has permission to do
                  // this
                  boolean allowed = false;
                  switch (pType) {
                    case MEMBERS:
                      allowed =
                          gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("MEMBERS"));
                      break;
                    case MODS:
                      allowed =
                          gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("MODS"));
                      break;
                    case ADMINS:
                      allowed =
                          gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("ADMINS"));
                      break;
                    case OWNER:
                      allowed =
                          gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("OWNER"));
                      break;
                    default:
                      allowed = false;
                      break;
                  }
                  if (!allowed) {
                    p.sendMessage(
                        ChatColor.RED + "You don't have permission to revoke this invite");
                  } else {
                    NameLayerPlugin.log(
                        Level.INFO,
                        arg0.getName()
                            + " revoked an invite for "
                            + NameAPI.getCurrentName(invitedUUID)
                            + " for group "
                            + g.getName()
                            + "via gui");
                    g.removeInvite(invitedUUID, true);
                    PlayerListener.removeNotification(invitedUUID, g);
                    Mercury.remInvite(g.getGroupId(), invitedUUID);

                    p.sendMessage(ChatColor.GREEN + playerName + "'s invitation has been revoked.");
                  }
                  showScreen();
                }
              };
        } else {
          ISUtils.addLore(is, ChatColor.RED + "You don't have permission to revoke this invite");
          c = new DecorationStack(is);
        }
        if (c != null) {
          clicks.add(c);
        }
      }
    }
    for (UUID uuid : g.getAllMembers()) {
      Clickable c = null;
      switch (g.getPlayerType(uuid)) {
        case MEMBERS:
          if (showMembers) {
            c = constructMemberClickable(Material.LEATHER_CHESTPLATE, uuid, PlayerType.MEMBERS);
          }
          break;
        case MODS:
          if (showMods) {
            c = constructMemberClickable(Material.GOLD_CHESTPLATE, uuid, PlayerType.MODS);
          }
          break;
        case ADMINS:
          if (showAdmins) {
            c = constructMemberClickable(Material.IRON_CHESTPLATE, uuid, PlayerType.ADMINS);
          }
          break;
        case OWNER:
          if (showOwners) {
            c = constructMemberClickable(Material.DIAMOND_CHESTPLATE, uuid, PlayerType.OWNER);
          }
          break;
        default:
          // should never happen
      }
      if (c != null) {
        clicks.add(c);
      }
    }

    return clicks;
  }
 /** Creates the required mysql tables and updates the db if needed. */
 private void createTables() {
   int ver = NameLayerPlugin.getVersionNum(plugin.getName());
   long begin_time = System.currentTimeMillis();
   if (ver == 0) {
     db.execute(
         String.format(
             "update db_version set plugin_name = '%s' " + "where plugin_name is null",
             plugin.getName()));
     ver = NameLayerPlugin.getVersionNum(plugin.getName());
     if (ver == 0) {
       Citadel.Log("Creating tables from scratch, this is a new " + "instance of citadel.");
     } else {
       Citadel.Log(
           "Detected previous version of Citadel, "
               + "updating to new db.\n"
               + "You should have backed up your data, "
               + "if you havent already you have ten seconds to"
               + " shut down the server and perform a backup.");
       try {
         Thread.sleep(10000);
       } catch (InterruptedException e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
       }
       long first_time = System.currentTimeMillis();
       db.execute(
           "alter table reinforcement drop security_level, drop version, add group_id int not null;");
       /*
       Citadel.Log("Remapping from material id to material name " +
       		"in process.");
       db.execute("create table if not exists material_mapping("
       		+ "" +
       		"material varchar(40) not null," +
       		"material_id int not null);");
       db.execute("create index x on material_mapping (material_id);");
       for (Material mat: Material.values()){
       	PreparedStatement insert = db.prepareStatement
       			("insert into material_mapping(" +
       			"material, material_id) values(?,?);");
       	try {
       		insert.setString(1, mat.name());
       		insert.setInt(2, mat.getId());
       		insert.execute();
       	} catch (SQLException e) {
       		// TODO Auto-generated catch block
       		e.printStackTrace();
       	}
       }
       db.execute("alter table reinforcement add " +
       		"material varchar(10)");
       db.execute("update reinforcement r " +
       		"inner join material_mapping m on m.material_id = r.material_id " +
       		"set r.material = m.material;");
       db.execute("alter table reinforcement drop material_id;");
       db.execute("drop table material_mapping;");
       */
       db.execute(
           "insert into faction_id (group_name) values (null);"); // For natural reinforcements
       db.execute("delete from reinforcement where `name` is null;");
       db.execute(
           "update ignore reinforcement r inner join faction_id f on f.group_name = r.`name` "
               + "set r.group_id = f.group_id;");
       db.execute(
           "alter table reinforcement drop `name`, add rein_type_id int not null default 1, "
               + "add lore varchar(255);");
       db.execute("drop table citadel_account_id_map;");
       Citadel.Log(
           "The update to new format took "
               + (System.currentTimeMillis() - first_time) / 1000
               + " seconds.");
     }
   }
   if (ver == 5 || ver == 0) {
     long first_time = System.currentTimeMillis();
     Citadel.Log("Updating to Citadel Version 6.");
     db.execute(
         "create table if not exists reinforcement("
             + "x int not null,"
             + "y int not null,"
             + "z int not null,"
             + "world varchar(10) not null,"
             + "material_id int not null,"
             + "durability varchar(10) not null,"
             + "chunk_id varchar(255) not null,"
             + "insecure tinyint(1) not null,"
             + "group_id int not null,"
             + "maturation_time int not null,"
             + "rein_type_id int not null,"
             + "lore varchar(255),"
             + "primary key (x,y,z,world));");
     db.execute(
         "create table if not exists reinforcement_type("
             + "rein_type_id int not null auto_increment,"
             + "rein_type varchar(30) not null,"
             + "primary key rein_type_key (rein_type_id));");
     String[] types = {"PlayerReinforcement", "NaturalReinforcement", "MultiBlockReinforcement"};
     for (String x : types)
       db.execute(String.format("insert into reinforcement_type(rein_type)" + "values('%s');", x));
     NameLayerPlugin.insertVersionNum(5, plugin.getName());
     ver = NameLayerPlugin.getVersionNum(plugin.getName());
     Citadel.Log(
         "The update to Version 6 took "
             + (System.currentTimeMillis() - first_time) / 1000
             + " seconds.");
   }
   if (ver == 6) {
     long first_time = System.currentTimeMillis();
     Citadel.Log("Updating to version 7. No fun message for you :(");
     db.execute(
         "create table if not exists reinforcement_id("
             + "rein_id int not null auto_increment,"
             + "x int not null,"
             + "y int not null,"
             + "z int not null,"
             + "chunk_id varchar(255),"
             + "world varchar (255) not null,"
             + "primary key rein_id_key (rein_id),"
             + "unique key x_y_z_world(x,y,z,world));-- Your mother is a w***e and sleeps with banjos");
     // I like turtles mother f****r. Never program because then you get turtles.
     db.execute(
         "insert into reinforcement_id (x, y, z, chunk_id, world) select x, y, z, chunk_id, world from reinforcement;"); // populate that bitch.
     db.execute("alter table reinforcement add rein_id int not null, drop chunk_id;");
     db.execute(
         "update reinforcement r inner join reinforcement_id ri on "
             + "ri.x = r.x and ri.y = r.y and ri.z = r.z and ri.world = r.world "
             + "set r.rein_id = ri.rein_id");
     db.execute(
         "alter table reinforcement DROP PRIMARY KEY, "
             + "add primary key rein_id_key(rein_id), "
             + "drop x,"
             + "drop y,"
             + "drop z,"
             + "drop world;");
     db.execute("alter table reinforcement_id add index `chunk_id_index` (chunk_id);");
     NameLayerPlugin.insertVersionNum(ver, plugin.getName());
     ver = NameLayerPlugin.getVersionNum(plugin.getName());
     Citadel.Log(
         "The update to Version 7 took "
             + (System.currentTimeMillis() / first_time) / 1000
             + " seconds.");
   }
   Citadel.Log(
       "The total time it took Citadel to update was "
           + (System.currentTimeMillis() - begin_time) / 1000
           + " seconds.");
 }
  /**
   * Inserts a reinforcement into the Database. Should only be called from SaveManager.
   *
   * @param The Reinforcement to save.
   */
  public void insertReinforcement(Reinforcement rein) {
    reconnectAndReinitialize();

    if (rein instanceof PlayerReinforcement) {
      Location loc = rein.getLocation();
      int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
      String world = loc.getWorld().getName();
      Material mat = rein.getMaterial();
      int dur = rein.getDurability();
      int maturationTime = rein.getMaturationTime();
      boolean insecure = false;
      String group = null;
      String reinType = "";
      String lore = "";
      PlayerReinforcement pRein = (PlayerReinforcement) rein;
      insecure = pRein.isInsecure();
      ItemMeta meta = pRein.getStackRepresentation().getItemMeta();
      if (meta.hasLore()) for (String xx : meta.getLore()) lore += xx + "\n";
      else lore = null;
      group = pRein.getGroup().getName();
      reinType = "PlayerReinforcement";
      try {
        PreparedStatement insertReinID = db.prepareStatement(this.insertReinID);
        insertReinID.setInt(1, x);
        insertReinID.setInt(2, y);
        insertReinID.setInt(3, z);
        String formatChunk = formatChunk(loc);
        insertReinID.setString(4, formatChunk);
        insertReinID.setString(5, world);
        insertReinID.execute();

        int id = getLastReinId();

        PreparedStatement addRein = db.prepareStatement(this.addRein);
        addRein.setInt(1, mat.getId());
        addRein.setInt(2, dur);
        addRein.setBoolean(3, insecure);
        addRein.setInt(4, maturationTime);
        addRein.setString(5, lore);
        addRein.setInt(6, id);
        addRein.setString(7, reinType);
        addRein.setString(8, group);
        addRein.execute();
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    } else if (rein instanceof NaturalReinforcement) {
      Location loc = rein.getLocation();
      int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
      String world = loc.getWorld().getName();
      Material mat = rein.getMaterial();
      int dur = rein.getDurability();
      String chunk_id = loc.getChunk().toString();
      int maturationTime = rein.getMaturationTime();
      boolean insecure = false;
      String group = NameLayerPlugin.getSpecialAdminGroup();
      String reinType = "NaturalReinforcement";
      String lore = "";
      lore = null;
      try {
        PreparedStatement insertReinID = db.prepareStatement(this.insertReinID);
        insertReinID.setInt(1, x);
        insertReinID.setInt(2, y);
        insertReinID.setInt(3, z);
        String formatChunk = formatChunk(loc);
        insertReinID.setString(4, formatChunk);
        insertReinID.setString(5, world);
        insertReinID.execute();

        int id = getLastReinId();

        PreparedStatement addRein = db.prepareStatement(this.addRein);
        addRein.setInt(1, mat.getId());
        addRein.setInt(2, dur);
        addRein.setBoolean(3, insecure);
        addRein.setInt(4, maturationTime);
        addRein.setString(5, lore);
        addRein.setInt(6, id);
        addRein.setString(7, reinType);
        addRein.setString(8, group);
        addRein.execute();
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    } else if (rein instanceof MultiBlockReinforcement) {
      MultiBlockReinforcement mbRein = (MultiBlockReinforcement) rein;
      Location loc = mbRein.getLocation();
      try {
        PreparedStatement insertReinID = db.prepareStatement(this.insertReinID);
        // add all the locations into the db.
        for (Location lo : mbRein.getLocations()) {
          insertReinID.setInt(1, lo.getBlockX());
          insertReinID.setInt(2, lo.getBlockY());
          insertReinID.setInt(3, lo.getBlockZ());
          String formatChunk = formatChunk(lo);
          insertReinID.setString(4, formatChunk);
          insertReinID.setString(5, lo.getWorld().getName());
          insertReinID.addBatch();
        }
        insertReinID.executeBatch();

        int id = getLastReinId();

        PreparedStatement addRein = db.prepareStatement(this.addRein);
        addRein.setInt(1, -1);
        addRein.setInt(2, mbRein.getDurability());
        addRein.setBoolean(3, false);
        addRein.setInt(4, mbRein.getMaturationTime());
        addRein.setString(5, null);
        addRein.setInt(6, id);
        addRein.setString(7, "MultiBlockReinforcement");
        addRein.setString(8, mbRein.getGroup().getName());
        addRein.execute();
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
Пример #10
0
public class InvitePlayer extends PlayerCommandMiddle {

  private GroupManagerDao db = NameLayerPlugin.getGroupManagerDao();

  public InvitePlayer(String name) {
    super(name);
    setIdentifier("nlip");
    setDescription(
        "Invite a player to the PlayerType " + PlayerType.toStringName() + " of a group.");
    setUsage("/nlip <group> <player> (PlayerType- default MEMBERS)");
    setArguments(2, 3);
  }

  @Override
  public boolean execute(CommandSender sender, String[] args) {
    if (!(sender instanceof Player)) {
      sender.sendMessage(ChatColor.RED + "I'm sorry baby, please run this as a player :)");
      return true;
    }
    Player p = (Player) sender;
    Group group = gm.getGroup(args[0]);
    if (group == null) {
      p.sendMessage(ChatColor.RED + "That group does not exist.");
      return true;
    }
    if (group.isDisciplined()) {
      p.sendMessage(ChatColor.RED + "This group is disiplined.");
      return true;
    }
    UUID executor = NameAPI.getUUID(p.getName());
    PlayerType pType = PlayerType.MEMBERS;
    if (args.length == 3) pType = PlayerType.getPlayerType(args[2]);
    if (pType == null) {
      PlayerType.displayPlayerTypes(p);
      return true;
    }
    UUID uuid = NameAPI.getUUID(args[1]);
    if (uuid == null) {
      p.sendMessage(ChatColor.RED + "The player has never played before.");
      return true;
    }

    GroupPermission perm = gm.getPermissionforGroup(group);
    PlayerType t = group.getPlayerType(executor); // playertype for the player running the command.
    if (t == null) {
      p.sendMessage(ChatColor.RED + "You are not on that group.");
      return true;
    }
    boolean allowed = false;
    switch (pType) { // depending on the type the executor wants to add the player to
      case MEMBERS:
        allowed = perm.isAccessible(t, PermissionType.MEMBERS);
        break;
      case MODS:
        allowed = perm.isAccessible(t, PermissionType.MODS);
        break;
      case ADMINS:
        allowed = perm.isAccessible(t, PermissionType.ADMINS);
        break;
      case OWNER:
        allowed = perm.isAccessible(t, PermissionType.OWNER);
        break;
      default:
        allowed = false;
        break;
    }
    if (!allowed) {
      p.sendMessage(ChatColor.RED + "You do not have permissions to modify this group.");
      return true;
    }

    if (group.isMember(uuid)) { // So a player can't demote someone who is above them.
      p.sendMessage(
          ChatColor.RED + "Player is already a member." + "Use /nlpp to change their PlayerType.");
      return true;
    }

    group.addInvite(uuid, pType);
    OfflinePlayer invitee = Bukkit.getOfflinePlayer(uuid);

    boolean shouldAutoAccept = db.shouldAutoAcceptGroups(uuid);

    if (invitee.isOnline()) {
      // invitee is online make them a player
      Player oInvitee = (Player) invitee;
      if (shouldAutoAccept) {
        // player auto accepts invite
        group.addMember(uuid, pType);
        group.removeRemoveInvite(uuid);
        if (group instanceof PrivateGroup) {
          PrivateGroup priv = (PrivateGroup) group;
          List<Group> groups = priv.getSubGroups();
          for (Group g : groups) {
            g.addMember(uuid, PlayerType.SUBGROUP);
          }
        }
        p.sendMessage(
            ChatColor.GREEN
                + "The invitation has been sent."
                + "\n Use /nlri to Revoke an invite.");
        oInvitee.sendMessage(
            ChatColor.GREEN + " You have auto-accepted invite to the group: " + group.getName());
      } else {
        PlayerListener.addNotification(uuid, group);
        oInvitee.sendMessage(
            ChatColor.GREEN
                + "You have been invited to the group "
                + group.getName()
                + " by "
                + p.getName()
                + ".\n"
                + "Use the command /nlag <group> to accept.\n"
                + "If you wish to toggle invites so they always are accepted please run /nltaai");
        p.sendMessage(
            ChatColor.GREEN
                + "The invitation has been sent."
                + "\n Use /nlri to Revoke an invite.");
      }
    } else {
      // invitee is offline
      if (shouldAutoAccept) {
        group.addMember(uuid, pType);
        group.removeRemoveInvite(uuid);
        PlayerListener.addNotification(uuid, group);
        p.sendMessage(
            ChatColor.GREEN
                + "The invitation has been sent."
                + "\n Use /nlri to Revoke an invite.");
      } else {
        // Player did not auto accept
        PlayerListener.addNotification(uuid, group);
        p.sendMessage(
            ChatColor.GREEN
                + "The invitation has been sent."
                + "\n Use /nlri to Revoke an invite.");
      }
    }

    return true;
  }

  @Override
  public List<String> tabComplete(CommandSender sender, String[] args) {
    if (!(sender instanceof Player)) {
      sender.sendMessage(ChatColor.RED + "I'm sorry baby, please run this as a player :)");
      return null;
    }
    if (args.length < 2) {
      if (args.length == 0) return GroupTabCompleter.complete(null, null, (Player) sender);
      else return GroupTabCompleter.complete(args[0], null, (Player) sender);

    } else if (args.length == 2) return null;
    else if (args.length == 3) return MemberTypeCompleter.complete(args[2]);
    else return null;
  }
}