因此,我有一个名为HitDistanceRatios的类,它实现了CommandExecutor,在MainClass中被调用,这是除JavaPlugin之外唯一调用ConfigGets的类。我还有另一个名为HitEvent的类,它是一个EventHandler,每次击中一个玩家时,将伤害者的UUID添加到Multimap中,在hitMap中,击中距离作为值存储,即Double 。还有另外一个应该知道的类是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;
  }
}





如您所见,我有一个将使用的吸气剂,该吸气剂曾经是Collection,并且会在给定UUID的情况下返回命中距离的collection。从另一个类进入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);
  }
}





再次,如您所见,我有几个吸气剂,它们从给定UUID的哈希图中获取值。但不要奇怪,一切都返回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));
  }

}




有什么建议?

最佳答案

这是一个复杂的过程。通过一点阅读,我看到如果您不指定访问修饰符,则默认情况下它是“私有包”。我不完全知道这是什么意思,但是我认为如果您将HitEvent中的行更改为此:

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


如果是这样,它应该可以工作。原因是,访问修饰符“私有包”仅允许该特定包中的类对其进行访问。如果尝试访问它的类不在其包中,则它无权访问。

07-26 00:49