【问题标题】:Bukkit - Why is my Multimap not being passed?Bukkit - 为什么我的 Multimap 没有通过?
【发布时间】:2016-06-29 04:45:34
【问题描述】:

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

基本上我遇到的问题是HitDistanceRatios 没有从任何其他课程中获取任何东西。我尝试了多种从HitEvent 获取hitMap 的方法,甚至通过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 并试图从那里获得几个HashMap,但如果我在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 的哈希图中获取值。但毫不奇怪,一切都返回 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));
  }

}
有什么建议么?

【问题讨论】:

  • minecraft 类型的问题通常与 StackOverflow 无关。不知道为什么标签还在这里。我们几乎不可能复制它们。
  • @redFIVE 我知道:/ 我已经尝试过去那里。我只是希望这是人们在使用 java 时遇到的问题。
  • 代码试图做什么?或者,更确切地说,您希望代码做什么?
  • 你能告诉我你到底想要完成什么吗?我也许可以提供一点帮助

标签: java minecraft bukkit multimap


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 2020-06-21
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多