Bukkit - 为什么我的Multimap没有通过?

时间:2016-06-29 04:45:34

标签: java minecraft bukkit multimap

所以,我有一个名为HitDistanceRatios的类,它实现了CommandExecutor,它在MainClass中被调用,这是唯一一个调用JavaPlugin的类,除了ConfigGets }。我还有另一个名为HitEvent的类EventHandler,每次玩家被击中时,伤害者的UUID被添加到Multimap hitMap,其中存储命中的距离作为价值观,双重。还有一个应该知道的类是HitDistance,它实际上可以接收hitMapHitDistanceHitDistanceRatios之间的区别在于HitDistanceRatios中调用MainClass来执行命令。

基本上我遇到的问题是HitDistanceRatios没有从任何其他类中获取任何东西。我尝试了多种方法从hitMap获取HitEvent,甚至通过HitDistance尝试获取它,但我找不到一种有效的方法。

以下是HitDistanceRatios

package yt.Kaelinator.commands;

import java.text.DecimalFormat;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import yt.Kaelinator.ConfigGets;
import yt.Kaelinator.MainClass;
import yt.Kaelinator.calculations.HitDistance;

public class HitDistanceRatios implements CommandExecutor {

  public HitDistanceRatios(MainClass instance) {}

  @
  Override
  public boolean onCommand(CommandSender sender, Command command, String cmd, String[] args) {
    if (!(sender instanceof Player))
      return false;
    Player player = (Player) sender;

    if (args.length == 0) {

      DecimalFormat numberFormat = new DecimalFormat("#.00");
      HitDistance hd = new HitDistance(null);

      player.sendMessage(ConfigGets.prefix + ChatColor.BLUE + player.getName() + ": " + ChatColor.RED + numberFormat.format(hd.getFourMap(player.getUniqueId())) + ChatColor.BLUE + "% of hits are over 4 blocks, " + ChatColor.RED + numberFormat.format(hd.getThreeHalfMap(player.getUniqueId())) + ChatColor.BLUE + "% are over 3.5 blocks.");
      return true;
    } else {@
      SuppressWarnings("deprecation")
      Player target = Bukkit.getPlayer(args[0]);

      if (target == null) {
        player.sendMessage(ConfigGets.prefix + "Player " + args[0] + " couldn't be found.");
        return true;

      } else {

        DecimalFormat numberFormat = new DecimalFormat("#.00");
        HitDistance hd = new HitDistance(null);

        player.sendMessage(ConfigGets.prefix + ChatColor.BLUE + target.getName() + ": " + ChatColor.RED + numberFormat.format(hd.getFourMap(target.getUniqueId())) + ChatColor.BLUE + "% of hits are over 4 blocks, " + ChatColor.RED + numberFormat.format(hd.getThreeHalfMap(target.getUniqueId())) + ChatColor.BLUE + "% are over 3.5 blocks.");
      }
      return true;
    }
  }
}
在这里,课程正在考虑HitDistance并尝试从那里获得一对HashMaps,但如果我在HitEvent类中使用getter,我会得到相同的结果。

以下是HitEvent

package yt.Kaelinator.events;

import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

import yt.Kaelinator.ConfigGets;
import yt.Kaelinator.MainClass;
import yt.Kaelinator.calculations.HitDistance;
import yt.Kaelinator.calculations.Lag;

public class HitEvent implements Listener {

  Multimap < UUID, Double > hitMap = ArrayListMultimap.create();

  public HitEvent(MainClass instance) {}

  @
  EventHandler
  public void onPlayerHit(EntityDamageByEntityEvent event) {

    // make sure they are all players
    if (!(event.getEntity() instanceof Player) | !(event.getDamager() instanceof Player))
      return;

    // get the event's players
    Player damaged = (Player) event.getEntity();
    Player damager = (Player) event.getDamager();

    // get the locations
    Location damagedLocation = damaged.getLocation();
    Location damagerLocation = damager.getLocation();

    // calculate the distance
    double distance = damagedLocation.distance(damagerLocation);

    // broadcast it to everyone
    ClickEvent ce = new ClickEvent();
    boolean displayHits = ConfigGets.DisplayDistances;
    if (displayHits) {
      for (Player p: Bukkit.getOnlinePlayers()) {
        p.sendMessage(ChatColor.translateAlternateColorCodes('&',
          ConfigGets.prefix +
          "&f" + damager.getDisplayName() + "&3 damaged &f" + damaged.getDisplayName() + "&3 Distance: &4" + distance + " &7&l" + ce.checkForLag(damager.getUniqueId()) + " " + ce.checkForLag(damaged.getUniqueId()) + " " + Math.ceil(Lag.getTPS())));
      }
    }

    if (!ce.checkForLag(damager.getUniqueId()) & !ce.checkForLag(damaged.getUniqueId()) & !(Math.ceil(Lag.getTPS()) < 20)) {
      hitMap.put(damager.getUniqueId(), distance);
    }

    UUID playerUUID = damager.getUniqueId();
    int hitAmount = hitMap.get(playerUUID).size();

    if ((hitAmount % 5 == 0) & hitAmount >= 20) {

      HitDistance hd = new HitDistance(null);
      hd.hasReach(hitMap.get(playerUUID), playerUUID);
    }
  }

  public Multimap < UUID, Double > getHitMap() {
    return hitMap;
  }
}

正如你所看到的,我有一个我将使用的getter,这个getter曾经是一个Collection,并且会返回给定UUID的命中距离集合。从另一个类进入HitDistanceRatio的任何内容都会返回null,从而导致错误。

这是HitDistance

package yt.Kaelinator.calculations;

import java.util.Collection;
import java.util.HashMap;
import java.util.UUID;

import org.bukkit.Bukkit;

import yt.Kaelinator.ConfigGets;
import yt.Kaelinator.MainClass;
import yt.Kaelinator.events.HitEvent;

public class HitDistance {

  public HitDistance(MainClass instance) {}

  public HashMap < UUID, Double > mapFourOverTotal = new HashMap < UUID, Double > ();
  public HashMap < UUID, Double > mapThreeHalfOverTotal = new HashMap < UUID, Double > ();

  HitEvent he = new HitEvent(null);

  public void hasReach(Collection < Double > collection, UUID uuid) {

    int length = collection.size();

    Double[] distances = collection.toArray(new Double[length]);

    int overThreeHalf = 0;
    int overFour = 0;
    int rep = 0;
    for (int i = 0; i < distances.length; i++) {
      if (distances[i] > 4.0) {
        overFour++;
        if (i >= 5) {
          if (distances[i - 1] > 4.0)
            rep++;
          if (distances[i - 2] > 4.05)
            rep += 2;
          if (distances[i - 3] > 4.1)
            rep += 3;
        }
      } else if (distances[i] > 3.5) {
        overThreeHalf++;
        if (i >= 5) {
          if (distances[i - 1] > 3.6)
            rep++;
          if (distances[i - 2] > 3.7)
            rep += 2;
          if (distances[i - 3] > 3.8)
            rep += 3;
        }
      }
    }

    double fourOverTotal = overFour / distances.length;
    double threeHalfOverTotal = overThreeHalf / distances.length;

    mapFourOverTotal.put(uuid, fourOverTotal);
    mapThreeHalfOverTotal.put(uuid, threeHalfOverTotal);

    if (fourOverTotal >= 1 / 3) {
      rep += 10;
    }

    if (threeHalfOverTotal / distances.length >= 2 / 5) {
      rep += 10;
    }



    if (rep >= 30) {
      Bukkit.getPlayer(uuid).kickPlayer(ConfigGets.prefix +
        ConfigGets.kickForReach);
    }
  }

  public double getFourMap(UUID uuid) {
    return mapFourOverTotal.get(uuid);
  }

  public double getThreeHalfMap(UUID uuid) {
    return mapThreeHalfOverTotal.get(uuid);
  }
}

再次,正如您所看到的,我有几个getter从给定UUID的hashmap获取值。但是,为了没有惊喜,一切都返回null。这对我来说非常混乱,因为HitDistance可以访问hitMap,但HitDistanceRatios无法访问任何内容。我觉得这与他们在MainClass

中的互动方式有关

package yt.Kaelinator;

import org.bukkit.Bukkit;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

import yt.Kaelinator.calculations.Lag;
import yt.Kaelinator.commands.HitDistanceRatios;
import yt.Kaelinator.events.ClickEvent;
import yt.Kaelinator.events.HitEvent;

public class MainClass extends JavaPlugin {

  public static MainClass instance = null;

  public void onEnable() {
    registerEvents();
    registerConfig();
    registerCommands();
    Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Lag(), 100L, 1L);
  }

  public void registerEvents() {
    PluginManager pm = getServer().getPluginManager();
    pm.registerEvents(new HitEvent(null), this);
    pm.registerEvents(new ClickEvent(), this);
  }

  private void registerConfig() {
    getConfig().options().copyDefaults(true);
    saveConfig();
  }

  private void registerCommands() {
    getCommand("hitdistanceratio").setExecutor(new HitDistanceRatios(this));
  }

}
有什么建议吗?

1 个答案:

答案 0 :(得分:0)

这是一个复杂的问题。从一点点阅读,我看到如果你没有指定访问修饰符,默认情况下,它是一个&#34;私有包&#34;。我不完全知道这意味着什么,但我认为如果你将HitEvent中的行更改为:

public Multimap < UUID, Double > hitMap = ArrayListMultimap.create();

如果是这样的话应该有效。原因是,访问修饰符&#34;私有包&#34;只允许该特定包中的类访问它。如果尝试访问它的类不在其包中,则它无法访问。