Example #1
0
  public static class ScoreAPI {

    private static Class<?> CRAFT_SCORE = NMSUtil.getClassBukkit("scoreboard.CraftScore");
    private static Class<?> CRAFT_OBJECTIVE = NMSUtil.getClassBukkit("scoreboard.CraftObjective");
    private static Class<?> CRAFT_SCOREBOARD = NMSUtil.getClassBukkit("scoreboard.CraftScoreboard");
    private static Class<?> CRAFT_SCOREBOARD_COMPONENT =
        NMSUtil.getClassBukkit("scoreboard.CraftScoreboardComponent");
    private static Class<?> SCOREBOARD = NMSUtil.getClassNMS("Scoreboard");
    private static Class<?> SCOREBOARD_SCORE = NMSUtil.getClassNMS("ScoreboardScore");
    private static Class<?> SCOREBOARD_OBJECTIVE = NMSUtil.getClassNMS("ScoreboardObjective");

    public static boolean isSet(Score score) {
      try {
        return isSetException(score);
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }
    }

    private static boolean isSetException(Score score)
        throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException,
            InvocationTargetException {
      Object craftScore = CRAFT_SCORE.cast(score);

      Object craftObjective = CRAFT_OBJECTIVE.cast(score.getObjective());
      Method craftHandle = CRAFT_OBJECTIVE.getDeclaredMethod("getHandle");
      craftHandle.setAccessible(true);
      Object craftObjectiveHandle = craftHandle.invoke(craftObjective);

      Field objective = CRAFT_SCORE.getDeclaredField("objective");
      objective.setAccessible(true);
      Object craftScoreboard = checkState(objective.get(craftScore));

      Field craftBoard = CRAFT_SCOREBOARD.getDeclaredField("board");
      craftBoard.setAccessible(true);
      Object scoreboard = craftBoard.get(craftScoreboard);
      Method playerObjectives = SCOREBOARD.getDeclaredMethod("getPlayerObjectives", String.class);
      playerObjectives.setAccessible(true);

      Field playerField = CRAFT_SCORE.getDeclaredField("entry");
      playerField.setAccessible(true);
      String playerName = (String) playerField.get(craftScore);
      Map map = (Map) playerObjectives.invoke(scoreboard, playerName);

      // return
      // objective.checkState().board.getPlayerObjectives(playerName).containsKey(objective.getHandle());
      return map.containsKey(craftObjectiveHandle);
    }

    public static void reset(Score score) {
      try {
        resetException(score);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    private static void resetException(Score score)
        throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException,
            InvocationTargetException {
      Object craftScore = CRAFT_SCORE.cast(score);

      Object craftObjective = CRAFT_OBJECTIVE.cast(score.getObjective());
      Method craftHandle = CRAFT_OBJECTIVE.getDeclaredMethod("getHandle");
      craftHandle.setAccessible(true);
      Object craftObjectiveHandle = craftHandle.invoke(craftObjective);

      Field objective = CRAFT_SCORE.getDeclaredField("objective");
      objective.setAccessible(true);
      Object craftScoreboard = checkState(objective.get(craftScore));

      /*
      Method checkState = CRAFT_OBJECTIVE.getDeclaredMethod("checkState");
      checkState.setAccessible(true);
      craftScoreboard = checkState.invoke(CRAFT_SCORE.getDeclaredField("objective").get(craftScore));
      */

      Field scoreboardField = CRAFT_SCOREBOARD.getDeclaredField("board");
      scoreboardField.setAccessible(true);
      Object scoreboard = scoreboardField.get(craftScoreboard);
      Method playerObjectives = SCOREBOARD.getDeclaredMethod("getPlayerObjectives", String.class);
      playerObjectives.setAccessible(true);

      Field playerField = CRAFT_SCORE.getDeclaredField("playerName");
      playerField.setAccessible(true);
      String playerName = (String) playerField.get(craftScore);
      Map map = (Map) playerObjectives.invoke(scoreboard, playerName);

      if (map.remove(craftObjectiveHandle) == null) {
        // If they don't have a score to delete, don't delete it.
        return;
      }

      Method resetScores = SCOREBOARD.getDeclaredMethod("resetPlayerScores", String.class);
      resetScores.setAccessible(true);
      resetScores.invoke(scoreboard, playerName);

      for (Object key : map.keySet()) {
        Object value = map.get(key);
        Method playerScoreMethod =
            SCOREBOARD.getDeclaredMethod(
                "getPlayerScoreForObjective", String.class, SCOREBOARD_OBJECTIVE);
        playerScoreMethod.setAccessible(true);
        Object scoreboardScore = playerScoreMethod.invoke(scoreboard, playerName, key);

        Method getScore = SCOREBOARD_SCORE.getDeclaredMethod("getScore");
        getScore.setAccessible(true);
        int setScoreTo = (int) getScore.invoke(value);

        Method setScore = SCOREBOARD_SCORE.getDeclaredMethod("setScore", int.class);
        setScore.setAccessible(true);
        setScore.invoke(scoreboardScore, setScoreTo);
      }

      /*
      CraftScoreboard myBoard = objective.checkState();
      Map<ScoreboardObjective, ScoreboardScore> savedScores = myBoard.board.getPlayerObjectives(playerName);
      if(savedScores.remove(objective.getHandle()) == null) {
      	// If they don't have a score to delete, don't delete it.
      	return;
      }
      myBoard.board.resetPlayerScores(playerName);
      for(Map.Entry<ScoreboardObjective, ScoreboardScore> e : savedScores.entrySet()) {
      	myBoard.board.getPlayerScoreForObjective(playerName, e.getKey()).setScore(e.getValue().getScore());
      }
      */
    }

    public static Object checkState(Object craftObjective) {
      try {
        return checkStateException(craftObjective);
      } catch (Exception e) {
        e.printStackTrace();
      }

      return null;
    }

    public static Object checkStateException(Object craftObjective)
        throws NoSuchFieldException, IllegalAccessException {
      Object boardComponent = CRAFT_SCOREBOARD_COMPONENT.cast(craftObjective);

      Field scoreboard = CRAFT_SCOREBOARD_COMPONENT.getDeclaredField("scoreboard");
      scoreboard.setAccessible(true);
      Object craftBoard = scoreboard.get(boardComponent);

      if (craftBoard == null) {
        throw new IllegalStateException("Unregistered scoreboard component");
      }

      return craftBoard;

      /*
      CraftScoreboard scoreboard = this.scoreboard;
      if(scoreboard == null) {
      	throw new IllegalStateException("Unregistered scoreboard component");
      }
      return scoreboard;
      */
    }
  }
  @Override
  public void run() {
    if (complete) return;

    // Log.debug((NumberUtil.randomBoolean() ? "tick" : "tock"));
    Rotation rotation = Rotation.get();
    RotationSlot next = rotation.getNext();

    rotation.setRestart();
    if (!rotation.isRestarting()) {
      next.load(true);
    }

    this.next = next;
    String what = getMessage();
    ChatColor colour = ChatColor.GRAY;
    if (next != null) {
      colour = ChatColor.DARK_AQUA;
    }

    try {
      List<User> players = match.getMap().getWinner().getPlayers();
      if (players.size() > 0 && isFullSecond()) { // check for more than 1 player
        User player = players.get(NumberUtil.getRandom(0, players.size() - 1));

        Location location = player.getPlayer().getLocation();
        Firework firework =
            (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
        FireworkMeta meta = firework.getFireworkMeta();
        meta.clearEffects();
        meta.addEffect(getFirework());
        firework.setFireworkMeta(meta);

        try {
          firework.detonate();
        } catch (Exception e) {
          Log.warning(
              "Server isn't running a version of Bukkit which allows the use of Firework.detonate() - resorting to manual detonation.");
          try {
            Object craft = NMSUtil.getClassBukkit("entity.CraftFirework").cast(firework);
            Method method = craft.getClass().getMethod("getHandle");
            method.setAccessible(true);
            Object handle = method.invoke(craft);
            handle.getClass().getField("expectedLifespan").set(handle, 0);
          } catch (Exception e2) {
            e2.printStackTrace();
          }
        }
      }
    } catch (NullPointerException ignored) {

    }

    if (duration <= 0 && next == null) {
      for (User player : User.getUsers()) {
        player.getPlayer().kickPlayer(ChatColor.GREEN + "Server restarting!");
      }

      complete = true;
      Bukkit.getServer().shutdown();
      return;
    }

    if (duration <= 0) {
      broadcast(what + "!");
      match.stop();
      complete = true;
      rotation.cycle();
      return;
    }

    boolean show = false;
    if (getTicks() % 20 == 0) {
      if (getSeconds() % 30 == 0) show = true;
      else if (getSeconds() < 30 && getSeconds() % 15 == 0) show = true;
      else if (getSeconds() < 15 && getSeconds() % 5 == 0) show = true;
      else if (getSeconds() < 5) show = true;
    }

    if (show)
      broadcast(
          what
              + " in "
              + ChatColor.RED
              + getSeconds()
              + " second"
              + (getSeconds() != 1 ? "s" : "")
              + colour
              + "!");
    setTicks(getTicks() - 1);
  }