public static void loadClasses(ConfigurationSection cs) {
   if (cs == null) {
     Log.info(BattleArena.getPName() + " has no classes");
     return;
   }
   StringBuilder sb = new StringBuilder();
   Set<String> keys = cs.getKeys(false);
   boolean first = true;
   for (String className : keys) {
     ArenaClass ac = parseArenaClass(cs.getConfigurationSection(className));
     if (ac == null) continue;
     if (first) first = false;
     else sb.append(", ");
     sb.append(ac.getName());
     ArenaClassController.addClass(ac);
   }
   if (first) {
     Log.info(
         BattleArena.getPName()
             + " no predefined classes found. inside of "
             + cs.getCurrentPath());
   } else {
     Log.info(BattleArena.getPName() + " registering classes: " + sb.toString());
   }
 }
Esempio n. 2
0
  @Override
  public void startEvent() {
    super.startEvent();
    Server server = Bukkit.getServer();

    int osize = teams.size();
    nrounds = getNRounds(osize);
    int nteams = (int) Math.pow(2, nrounds);
    server.broadcastMessage(
        Log.colorChat(
            eventParams.getPrefix()
                + "&e The "
                + eventParams.toPrettyString()
                + oParms.getName()
                + " tournament is starting!"));

    preliminary_round = teams.size() != nteams;
    if (preliminary_round) nrounds++;

    TreeMap<Double, Team> sortTeams = new TreeMap<Double, Team>(Collections.reverseOrder());
    BTInterface bti = new BTInterface(eventParams);
    //		System.out.println("startEvent:: bti=" + bti);
    for (Team t : teams) {
      Double elo = Defaults.DEFAULT_ELO;
      if (bti.isValid()) {
        elo = (double) bti.getElo(t);
      }
      while (sortTeams.containsKey(elo)) {
        elo += 0.0001;
      }
      sortTeams.put(elo, t);
    }
    competingTeams.addAll(teams);
    teams.clear();
    aliveTeams.clear();
    ArrayList<Team> ts = new ArrayList<Team>(sortTeams.values());
    for (Team t : ts) {
      teams.add(t);
      aliveTeams.add(t);
    }
    server.broadcastMessage(
        Log.colorChat(
            eventParams.getPrefix()
                + "&6 "
                + teams.size()
                + " &e"
                + MessageUtil.getTeamsOrPlayers(teams.size())
                + " will compete in a &6"
                + nrounds
                + "&e round tournament"));
    if (preliminary_round) {
      makePreliminaryRound();
    } else {
      makeNextRound();
    }
    startRound();
  }
  @MatchEventHandler
  public void matchCompleted(MatchCompletedEvent event) {
    Match am = event.getMatch();
    MatchResult r = am.getResult();
    Matchup m = null;
    if (r.getVictors() != null && !r.getVictors().isEmpty()) {
      m = getMatchup(r.getVictors().iterator().next(), round);
    } else if (r.getLosers() != null && !r.getLosers().isEmpty()) {
      m = getMatchup(r.getLosers().iterator().next(), round);
    } else if (r.getDrawers() != null && !r.getDrawers().isEmpty()) {
      m = getMatchup(r.getDrawers().iterator().next(), round);
    }
    if (m == null) { // / This match wasnt in our tournament
      return;
    }
    if (am.getState() == MatchState.ONCANCEL) {
      endEvent();
      return;
    }
    Team victor = null;
    if (r.isDraw()) { // / match was a draw, pick a random lucky winner
      victor = pickRandomWinner(r, r.getDrawers());
    } else if (r.hasVictor() && r.getVictors().size() != 1) {
      victor = pickRandomWinner(r, r.getVictors());
    } else if (r.hasVictor()) {
      victor = r.getVictors().iterator().next(); // / single winner
    }
    m.setResult(r);
    for (Team t : r.getLosers()) {
      super.removeTeam(t);
    }
    aliveTeams.removeAll(r.getLosers());

    if (roundFinished()) {
      TimeUtil.testClock();
      if (Defaults.DEBUG) System.out.println("ROUND FINISHED !!!!!   " + aliveTeams);

      if (round + 1 == nrounds || isFinished()) {
        Server server = Bukkit.getServer();
        Team t = aliveTeams.get(0);
        server.broadcastMessage(
            Log.colorChat(
                eventParams.getPrefix()
                    + "&e Congratulations to &6"
                    + t.getDisplayName()
                    + "&e for winning!"));
        HashSet<Team> losers = new HashSet<Team>(competingTeams);
        losers.remove(victor);
        Set<Team> victors = new HashSet<Team>(Arrays.asList(victor));
        eventVictory(victors, losers);
        PerformTransition.transition(am, MatchState.FIRSTPLACE, t, false);
        PerformTransition.transition(am, MatchState.PARTICIPANTS, losers, false);
        eventCompleted();
      } else {
        makeNextRound();
        startRound();
      }
    }
  }
 /**
  * Construct a listener to listen for the given bukkit event
  *
  * @param bukkitEvent : which event we will listen for
  * @param getPlayerMethod : a method which when not null and invoked will return a Player
  */
 public BukkitEventListener(
     final Class<? extends Event> bukkitEvent,
     org.bukkit.event.EventPriority bukkitPriority,
     Method getPlayerMethod) {
   super(bukkitEvent, bukkitPriority);
   if (Defaults.DEBUG_EVENTS)
     Log.info(
         "Registering GenericPlayerEventListener for type "
             + bukkitEvent.getSimpleName()
             + " pm="
             + (getPlayerMethod == null ? "null" : getPlayerMethod.getName()));
 }
Esempio n. 5
0
 private void logInvocationError(Exception e, MethodWrapper mwrapper, Arguments newArgs) {
   System.err.println(
       "["
           + BattleArena.getNameAndVersion()
           + " Error] "
           + mwrapper.method
           + " : "
           + mwrapper.obj
           + "  : "
           + newArgs);
   if (newArgs != null && newArgs.args != null) {
     for (Object o : newArgs.args) System.err.println("[Error] object=" + o);
   }
   System.err.println("[Error] Cause=" + e.getCause());
   if (e.getCause() != null) {
     e.getCause().printStackTrace();
     Log.printStackTrace(e.getCause());
   }
   System.err.println("[Error] Trace Continued ");
   Log.printStackTrace(e);
 }
 @Override
 public void invokeEvent(final Event event) {
   /// For each ArenaListener class that is listening
   for (RListener rl : getRegisteredListeners()) {
     try {
       rl.getMethod()
           .getMethod()
           .invoke(rl.getListener(), event); // / Invoke the listening arenalisteners method
     } catch (Exception e) {
       Log.printStackTrace(e);
     }
   }
 }
Esempio n. 7
0
 @Override
 public void broadcast(String msg) {
   if (msg == null || msg.isEmpty()) return;
   try {
     MessageUtil.broadcastMessage(MessageUtil.colorChat(msg));
   } catch (Throwable e) {
     /// getting this a lot of concurrency and null pointer errors from bukkit when stress
     // testing...
     /// so ignore errors from bukkit
     if (!Defaults.DEBUG_STRESS) {
       Log.printStackTrace(e);
     }
   }
 }
 static {
   Class<?>[] args = {};
   try {
     Version version = Util.getCraftBukkitVersion();
     if (version.compareTo("v1_6_1") >= 0) {
       final Class<?> clazz = Class.forName("mc.alk.arena.util.compat.v1_6_1.EventHelper");
       handler = (IEventHelper) clazz.getConstructor(args).newInstance((Object[]) args);
     } else {
       final Class<?> clazz = Class.forName("mc.alk.arena.util.compat.pre.EventHelper");
       handler = (IEventHelper) clazz.getConstructor(args).newInstance((Object[]) args);
     }
   } catch (Exception e) {
     Log.printStackTrace(e);
   }
 }
  private static ArenaLocation getArenaLocation(
      PlayerHolder am, ArenaTeam team, ArenaPlayer player, TransitionOptions mo, int teamIndex) {
    final MatchParams mp = am.getParams();
    final boolean randomRespawn = mo.hasOption(TransitionOption.RANDOMRESPAWN);
    Location l;
    final boolean teleportWaitRoom = mo.shouldTeleportWaitRoom();
    final boolean teleportLobby = mo.shouldTeleportLobby();
    final boolean teleportSpectate = mo.shouldTeleportSpectate();
    final LocationType type;
    final PlayerHolder ph;
    if (Defaults.DEBUG_TRACE)
      Log.info(" teamindex = " + teamIndex + "   " + am.getClass().getSimpleName() + "  " + am);

    if (teleportWaitRoom) {
      if (mo.hasOption(TransitionOption.TELEPORTMAINWAITROOM)) {
        teamIndex = Defaults.MAIN_SPAWN;
      }
      ph = (am instanceof Match) ? ((Match) am).getArena().getWaitroom() : am;
      type = LocationType.WAITROOM;
      l = jitter(ph.getSpawn(teamIndex, randomRespawn), teamIndex);
    } else if (teleportLobby) {
      if (mo.hasOption(TransitionOption.TELEPORTMAINLOBBY)) {
        teamIndex = Defaults.MAIN_SPAWN;
      }
      ph = RoomController.getLobby(mp.getType());
      type = LocationType.LOBBY;
      l = jitter(RoomController.getLobbySpawn(teamIndex, mp.getType(), randomRespawn), 0);
    } else if (teleportSpectate) {
      ph = (am instanceof Match) ? ((Match) am).getArena().getSpectatorRoom() : am;
      type = LocationType.SPECTATE;
      l = jitter(ph.getSpawn(teamIndex, randomRespawn), teamIndex);
    } else { // They should teleportIn, aka to the Arena
      final Arena arena;
      if (am instanceof Arena) {
        arena = (Arena) am;
      } else if (am instanceof Match) {
        Match m = (Match) am;
        arena = m.getArena();
      } else {
        throw new IllegalStateException("[BA Error] Instance is " + am.getClass().getSimpleName());
      }
      ph = am;
      type = LocationType.ARENA;
      l = arena.getSpawn(teamIndex, false);
    }
    return new ArenaLocation(ph, l, type);
  }
Esempio n. 10
0
 @Override
 public void addTeam(Team t) {
   super.addTeam(t);
   int size = teams.size();
   int nrounds = getNRounds(size);
   int idealteam = (int) Math.pow(2, nrounds);
   if (size > 2 && size % idealteam == 0) {
     Bukkit.broadcastMessage(
         Log.colorChat(
             eventParams.getPrefix()
                 + "&6"
                 + size
                 + " "
                 + MessageUtil.getTeamsOrPlayers(teams.size())
                 + "&e have joined, Current tournament will have &6"
                 + nrounds
                 + "&e rounds"));
   }
 }
  public static void teleport(
      PlayerHolder am, ArenaTeam team, ArenaPlayer player, TransitionOptions mo, int teamIndex) {
    player.markOldLocation();
    MatchParams mp = am.getParams();

    /// EnterWaitRoom is supposed to happen before the teleport in event, but it depends on the
    // result of a teleport
    /// Since we cant really tell the eventual result.. do our best guess
    ArenaLocation dest = getArenaLocation(am, team, player, mo, teamIndex);
    ArenaLocation src = player.getCurLocation();
    src.setLocation(player.getLocation());
    if (Defaults.DEBUG_TRACE)
      Log.info(" ########### @@ " + player.getCurLocation() + "  -->  " + am.getTeam(player));

    TeleportDirection td = calcTeleportDirection(player, src, dest);
    ArenaPlayerTeleportEvent apte =
        new ArenaPlayerTeleportEvent(mp.getType(), player, team, src, dest, td);

    movePlayer(player, apte, mp);
  }
Esempio n. 12
0
 private void announceTourneySize() {
   int size = 0;
   for (Team t : teams) {
     if (t.size() > 0) size++;
   }
   int nrounds = getNRounds(size);
   int idealteam = (int) Math.pow(eventParams.getMinTeams(), nrounds);
   if (nrounds > 1 && size % idealteam == 0) {
     Bukkit.broadcastMessage(
         Log.colorChat(
             eventParams.getPrefix()
                 + "&6"
                 + size
                 + " "
                 + MessageUtil.getTeamsOrPlayers(teams.size())
                 + "&e have joined, Current tournament will have &6"
                 + nrounds
                 + "&e rounds"));
   }
 }
Esempio n. 13
0
 private Team pickRandomWinner(MatchResult r, Collection<Team> randos) {
   Team victor;
   List<Team> ls = new ArrayList<Team>(randos);
   if (ls.isEmpty()) {
     Log.err("[BattleArena] Tournament found a match with no players, cancelling tournament");
     this.cancelEvent();
     return null;
   }
   victor = ls.get(rand.nextInt(ls.size()));
   victor.sendMessage("&2You drew your match but have been randomly selected as the winner!");
   r.setVictor(victor);
   Set<Team> losers = new HashSet<Team>(ls);
   losers.remove(victor);
   r.addLosers(losers);
   for (Team l : losers) {
     l.sendMessage(
         "&cYou drew your match but someone else has been randomly selected as the winner!");
   }
   return victor;
 }
  public static void teleportOut(
      PlayerHolder am,
      ArenaTeam team,
      ArenaPlayer player,
      TransitionOptions mo,
      int teamIndex,
      boolean insideArena,
      boolean onlyInMatch,
      boolean wipeInventory) {
    MatchParams mp = am.getParams();
    Location loc = null;
    ArenaLocation src = player.getCurLocation();
    final LocationType type;
    if (mo.hasOption(TransitionOption.TELEPORTTO)) {
      loc = mo.getTeleportToLoc();
      type = LocationType.CUSTOM;
    } else {
      type = LocationType.HOME;
      loc = player.getOldLocation();
      /// TODO
      /// This is a bit of a kludge, sometimes we are "teleporting them out"
      /// when they are already out... so need to rethink how this can happen and should it
      if (loc == null && src.getType() == LocationType.HOME) {
        loc = src.getLocation();
      }
    }
    player.clearOldLocation();
    if (loc == null) {
      Log.err(
          BattleArena.getNameAndVersion()
              + " Teleporting to a null location!  teleportTo="
              + mo.hasOption(TransitionOption.TELEPORTTO));
    }

    ArenaLocation dest = new ArenaLocation(AbstractAreaContainer.HOMECONTAINER, loc, type);
    ArenaPlayerTeleportEvent apte =
        new ArenaPlayerTeleportEvent(
            am.getParams().getType(), player, team, src, dest, TeleportDirection.OUT);
    movePlayer(player, apte, mp);
  }
Esempio n. 15
0
  public static DuelOptions parseOptions(MatchParams params, ArenaPlayer challenger, String[] args)
      throws InvalidOptionException {
    DuelOptions dop = new DuelOptions();
    dop.options.putAll(defaultOptions.options);
    Map<DuelOption, Object> ops = dop.options;

    for (int i = 0; i < args.length; i++) {
      String op = args[i];
      Player p = ServerUtil.findPlayer(op);
      if (p != null) {
        if (!p.isOnline())
          throw new InvalidOptionException(
              "&cPlayer &6" + p.getDisplayName() + "&c is not online!");
        if (challenger != null && p.getName().equals(challenger.getName()))
          throw new InvalidOptionException("&cYou can't challenge yourself!");
        if (p.hasPermission(Permissions.DUEL_EXEMPT) && !Defaults.DUEL_CHALLENGE_ADMINS) {
          throw new InvalidOptionException("&cThis player can not be challenged!");
        }
        dop.challengedPlayers.add(BattleArena.toArenaPlayer(p));
        continue;
      }
      Object obj = null;

      DuelOption to = null;
      String val;
      if (op.contains("=")) {
        String[] split = op.split("=");
        op = split[0];
        val = split[1];
      } else {
        val = i + 1 < args.length ? args[i + 1] : null;
      }
      to = parseOp(op, val);
      switch (to) {
        case RATED:
          if (!Defaults.DUEL_ALLOW_RATED)
            throw new InvalidOptionException("&cRated formingDuels are not allowed!");
          break;
        default:
          break;
      }

      if (!to.needsValue) {
        ops.put(to, null);
        continue;
      }
      i++; /// another increment to get past the value
      switch (to) {
        case MONEY:
          Double money = null;
          try {
            money = Double.valueOf(val);
          } catch (Exception e) {
            throw new InvalidOptionException("&cmoney needs to be a number! Example: &6money=100");
          }
          if (!MoneyController.hasEconomy()) {
            if (challenger != null)
              MessageUtil.sendMessage(
                  challenger, "&cignoring duel option money as there is no economy!");
            Log.warn("[BA Error] ignoring duel option money as there is no economy!");
            continue;
          }
          obj = money;
          break;
        case ARENA:
          Arena a = BattleArena.getBAController().getArena(val);
          if (a == null) {
            throw new InvalidOptionException("&cCouldnt find the arena &6" + val);
          }
          if (params != null && !a.getArenaType().matches(params.getType())) {
            throw new InvalidOptionException("&cThe arena is used for a different type!");
          }
          obj = a;
        default:
          break;
      }
      ops.put(to, obj);
    }
    if (challenger != null && dop.challengedPlayers.isEmpty()) {
      throw new InvalidOptionException("&cYou need to challenge at least one player!");
    }
    return dop;
  }
Esempio n. 16
0
  @ArenaEventHandler(bukkitPriority = org.bukkit.event.EventPriority.MONITOR)
  public void onPlayerDeath(ArenaPlayerDeathEvent event) {
    final ArenaPlayer target = event.getPlayer();
    if (state == MatchState.ONCANCEL || state == MatchState.ONCOMPLETE) {
      return;
    }
    final ArenaTeam t = event.getTeam();

    Integer nDeaths = t.addDeath(target);
    boolean exiting = event.isExiting() || !respawns || nDeaths >= nLivesPerPlayer;
    event.setExiting(exiting);
    final boolean trueDeath = event.getPlayerDeathEvent() != null;
    if (nLivesPerPlayer != ArenaSize.MAX) {
      int curLives = nLivesPerPlayer - nDeaths;
      SEntry e = scoreboard.getEntry(target.getPlayer());
      if (e != null) scoreboard.setEntryNameSuffix(e, curLives <= 1 ? "" : "&4(" + curLives + ")");
    }
    if (trueDeath) {
      PlayerDeathEvent pde = event.getPlayerDeathEvent();
      if (cancelExpLoss) pde.setKeepLevel(true);

      /// Handle Drops from bukkitEvent
      if (clearsInventoryOnDeath || keepsInventory) { // / clear the drops
        try {
          pde.getDrops().clear();
        } catch (Exception e) {
          if (!Defaults.DEBUG_VIRTUAL) Log.printStackTrace(e);
        }
      } else if (woolTeams) { /// Get rid of the wool from teams so it doesnt drop
        final int index = t.getIndex();
        ItemStack teamHead = TeamUtil.getTeamHead(index);
        List<ItemStack> items = pde.getDrops();
        for (ItemStack is : items) {
          if (is.getType() == teamHead.getType()
              && is.getDurability() == teamHead.getDurability()) {
            final int amt = is.getAmount();
            if (amt > 1) is.setAmount(amt - 1);
            else is.setType(Material.AIR);
            break;
          }
        }
      }
      /// If keepInventory is specified, but not restoreAll, then we have a case
      /// where we need to give them back the current Inventory they have on them
      /// even if they log out
      if (keepsInventory) {
        boolean restores =
            getParams().hasOptionAt(MatchState.ONLEAVE, TransitionOption.RESTOREITEMS);
        /// Restores and exiting, means clear their match inventory so they won't
        /// get their match and their already stored inventory
        if (restores && exiting) {
          psc.clearMatchItems(target);
        } else { /// keep their current inv
          psc.storeMatchItems(target);
        }
      }
      /// We can't let them just sit on the respawn screen... schedule them to lose
      /// We will cancel this onRespawn
      final ArenaMatch am = this;
      Integer timer = deathTimer.get(target.getName());
      if (timer != null) {
        Bukkit.getScheduler().cancelTask(timer);
      }
      timer =
          Bukkit.getScheduler()
              .scheduleSyncDelayedTask(
                  BattleArena.getSelf(),
                  new Runnable() {
                    @Override
                    public void run() {
                      PerformTransition.transition(am, MatchState.ONCOMPLETE, target, t, true);
                      checkAndHandleIfTeamDead(t);
                    }
                  },
                  15 * 20L);
      deathTimer.put(target.getName(), timer);
    }
    if (exiting) {
      PerformTransition.transition(this, MatchState.ONCOMPLETE, target, t, true);
      checkAndHandleIfTeamDead(t);
    }
  }
Esempio n. 17
0
  @EventHandler
  public void matchCompleted(MatchCompletedEvent event) {
    if (!isRunning()) return;
    Match am = event.getMatch();
    Team victor = am.getVictor();
    Matchup m;
    if (victor == null) m = getMatchup(am.getResult().getLosers().iterator().next(), round);
    else m = getMatchup(victor, round);
    //		System.out.println("victor ===" + victor + "  am= " +am + " losers=" + am.getLosers() +"   m
    // = " + m +"   am.result="+am.getResult());
    if (m == null) { // / This match wasnt in our tournament
      return;
    }
    if (am.getState() == MatchState.ONCANCEL) {
      endEvent();
      return;
    }
    MatchResult r = am.getResult();
    if (victor == null) { // / match was a draw, pick a random lucky winner
      List<Team> ls = new ArrayList<Team>(am.getResult().getLosers());
      if (ls.isEmpty()) {
        Log.err("[BattleArena] Tournament found a match with no players, cancelling tournament");
        this.cancelEvent();
        return;
      }
      victor = ls.get(rand.nextInt(ls.size()));
      victor.sendMessage("&2You drew your match but have been randomly selected as the winner!");
      r.setVictor(victor);
      Set<Team> losers = new HashSet<Team>(ls);
      losers.remove(victor);
      r.setLosers(losers);
      for (Team l : losers) {
        l.sendMessage(
            "&cYou drew your match but someone else has been randomly selected as the winner!");
      }
    }
    m.setResult(r);
    for (Team t : r.getLosers()) {
      super.removeTeam(t);
    }
    aliveTeams.removeAll(r.getLosers());

    if (roundFinished()) {
      TimeUtil.testClock();
      if (Defaults.DEBUG) System.out.println("ROUND FINISHED !!!!!   " + aliveTeams);

      if (round + 1 == nrounds || isFinished()) {
        Server server = Bukkit.getServer();
        Team t = aliveTeams.get(0);
        server.broadcastMessage(
            Log.colorChat(
                eventParams.getPrefix()
                    + "&e Congratulations to &6"
                    + t.getDisplayName()
                    + "&e for winning!"));
        HashSet<Team> losers = new HashSet<Team>(competingTeams);
        losers.remove(victor);
        eventVictory(victor, losers);
        PerformTransition.transition(am, MatchState.FIRSTPLACE, t, false);
        PerformTransition.transition(am, MatchState.PARTICIPANTS, losers, false);
        eventCompleted();
      } else {
        makeNextRound();
        startRound();
      }
    }
  }
  private static void movePlayer(
      ArenaPlayer player, ArenaPlayerTeleportEvent apte, MatchParams mp) {
    PlayerHolder src = apte.getSrcLocation().getPlayerHolder();
    PlayerHolder dest = apte.getDestLocation().getPlayerHolder();
    TeleportDirection td = apte.getDirection();
    if (Defaults.DEBUG_TRACE)
      Log.info(" ###########  " + player.getCurLocation() + "  -->  " + dest.getLocationType());
    if (Defaults.DEBUG_TRACE)
      Log.info(
          " ---- << -- " + player.getName() + "   src=" + src + "   dest=" + dest + "    td=" + td);

    switch (td) {
      case RESPAWN:
        break;
      case FIRSTIN:
        mp.getGameManager().onPreJoin(player, apte);
        dest.onPreJoin(player, apte);
      case IN:
        src.onPreLeave(player, apte);
        dest.onPreEnter(player, apte);
        break;
      case OUT:
        mp.getGameManager().onPreQuit(player, apte);
        src.onPreQuit(player, apte);
        dest.onPreJoin(player, apte);
        break;
      default:
        break;
    }
    dest.callEvent(apte);
    if (!TeleportController.teleport(player.getPlayer(), apte.getDestLocation().getLocation(), true)
        && player.isOnline()
        && !player.isDead()) {
      Log.err(
          "[BA Warning] couldn't teleport "
              + player.getName()
              + " srcLoc="
              + apte.getSrcLocation()
              + " destLoc="
              + apte.getDestLocation());
    }
    player.setCurLocation(apte.getDestLocation());
    switch (td) {
      case RESPAWN:
        break;
      case FIRSTIN:
        mp.getGameManager().onPostJoin(player, apte);
        dest.onPostJoin(player, apte);
      case IN:
        src.onPostLeave(player, apte);
        dest.onPostEnter(player, apte);
        break;
      case OUT:
        mp.getGameManager().onPostQuit(player, apte);
        src.onPostQuit(player, apte);
        dest.onPostJoin(player, apte);
        break;
      default:
        break;
    }
  }
Esempio n. 19
0
  protected Arguments verifyArgs(
      MethodWrapper mwrapper,
      MCCommand cmd,
      CommandSender sender,
      Command command,
      String label,
      String[] args,
      int startIndex)
      throws IllegalArgumentException {
    if (DEBUG) {
      Log.info(
          " method="
              + mwrapper.method.getName()
              + " verifyArgs "
              + cmd
              + " sender="
              + sender
              + ", label="
              + label
              + " args="
              + args);
      for (String arg : args) {
        Log.info(" -- arg=" + arg);
      }
      for (Class<?> t : mwrapper.method.getParameterTypes()) {
        Log.info(" -- type=" + t);
      }
    }
    final int paramLength = mwrapper.method.getParameterTypes().length;

    /// Check our permissions
    if (!cmd.perm().isEmpty()
        && !sender.hasPermission(cmd.perm())
        && !(cmd.admin() && hasAdminPerms(sender)))
      throw new IllegalArgumentException("You don't have permission to use this command");

    /// Verify min number of arguments
    if (args.length < cmd.min()) {
      throw new IllegalArgumentException("You need at least " + cmd.min() + " arguments");
    }
    /// Verfiy max number of arguments
    if (args.length > cmd.max()) {
      throw new IllegalArgumentException("You need less than " + cmd.max() + " arguments");
    }
    /// Verfiy max number of arguments
    if (cmd.exact() != -1 && args.length != cmd.exact()) {
      throw new IllegalArgumentException("You need exactly " + cmd.exact() + " arguments");
    }
    final boolean isPlayer = sender instanceof Player;
    final boolean isOp =
        (isPlayer && sender.isOp()) || sender == null || sender instanceof ConsoleCommandSender;

    if (cmd.op() && !isOp)
      throw new IllegalArgumentException("You need to be op to use this command");

    if (cmd.admin() && !isOp && (isPlayer && !hasAdminPerms(sender)))
      throw new IllegalArgumentException("You need to be an Admin to use this command");

    Class<?> types[] = mwrapper.method.getParameterTypes();

    //		/// In game check
    if (types[0] == Player.class && !isPlayer) {
      throw new IllegalArgumentException(ONLY_INGAME);
    }
    int strIndex = startIndex /*skip the label*/, objIndex = 1;

    Arguments newArgs = new Arguments(); // / Our return value
    Object[] objs = new Object[paramLength]; // / Our new array of castable arguments

    newArgs.args = objs; // / Set our return object with the new castable arguments
    objs[0] = verifySender(sender, types[0]);
    AtomicBoolean usedString = new AtomicBoolean();
    for (int i = 1; i < types.length; i++) {
      Class<?> clazz = types[i];
      usedString.set(false);
      try {
        if (CommandSender.class == clazz) {
          objs[objIndex] = sender;
        } else if (String[].class == clazz) {
          objs[objIndex] = args;
        } else if (Object[].class == clazz) {
          objs[objIndex] = args;
        } else {
          String str = strIndex < args.length ? args[strIndex] : null;
          objs[objIndex] = verifyArg(clazz, command, str, usedString);
          if (objs[objIndex] == null) {
            throw new IllegalArgumentException("Argument " + args[strIndex] + " can not be null");
          }
        }
        if (DEBUG)
          Log.info(
              "   "
                  + objIndex
                  + " : "
                  + strIndex
                  + "  "
                  + (args.length > strIndex ? args[strIndex] : null)
                  + " <-> "
                  + objs[objIndex]
                  + " !!!!!!!!!!!!!!!!!!!!!!!!!!! Cs = "
                  + clazz.getCanonicalName());
        if (usedString.get()) {
          strIndex++;
        }
      } catch (ArrayIndexOutOfBoundsException e) {
        throw new IllegalArgumentException("You didnt supply enough arguments for this method");
      }
      objIndex++;
    }

    /// Verify alphanumeric
    if (cmd.alphanum().length > 0) {
      for (int index : cmd.alphanum()) {
        if (index >= args.length) throw new IllegalArgumentException("String Index out of range. ");
        if (!args[index].matches("[a-zA-Z0-9_]*")) {
          throw new IllegalArgumentException(
              "argument '" + args[index] + "' can only be alphanumeric with underscores");
        }
      }
    }
    return newArgs; /// Success
  }