System.currentTimeMillis() 不断重置
System.currentTimeMillis() keeps resetting
我正在尝试在我的 spigot 插件中制作冷却实用程序:
package net.gettrillium.trillium.api.cooldown;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import net.gettrillium.trillium.Utils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
public class Cooldown {
private static Table<UUID, CooldownType, Long> cooldown = HashBasedTable.create();
public static void setCooldown(Player p, CooldownType type) {
cooldown.put(p.getUniqueId(), type, System.currentTimeMillis());
}
public static boolean hasCooldown(Player p, CooldownType type) {
if (cooldown.contains(p.getUniqueId(), type)) {
Bukkit.broadcastMessage("GET: " + cooldown.get(p.getUniqueId(), type));
Bukkit.broadcastMessage("CURRENT MILLIS: " + System.currentTimeMillis());
Bukkit.broadcastMessage("SUBTRACTED: " + (System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)));
Bukkit.broadcastMessage("IN SECONDS: " + (System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0);
Bukkit.broadcastMessage("> WITH: " + (type.getTimeInTicks() / 20));
Bukkit.broadcastMessage("HAS COOLDOWN: " + (((System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0) > (type.getTimeInTicks() / 20)));
if (((System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0) > (type.getTimeInTicks() / 20)) {
return true;
} else {
cooldown.remove(p.getUniqueId(), type);
return false;
}
} else {
return false;
}
}
public static String getTime(Player p, CooldownType type) {
if (hasCooldown(p, type)) {
return Utils.timeToString((int) ((System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0));
} else {
return null;
}
}
}
bukkit.broadcastMessage()
方法只是将消息发送到控制台并在游戏中作为调试。
我的问题是,每次我检查 cooldown
table,cooldown.contains(p.getUniqueId(), type)
总是一个新的 System.currentTimeMillis()
。它没有保存在 setCooldown 中注册的那个。
这个Cooldown
class是在teleport模块中使用的,你只需要注意cooldown
相关的if语句即可,其他都是teleport相关代码。
调试输出:
GET: 1433433920944
CURRENT MILLIS: 1433433928830
SUBTRACTED: 7888
IN SECONDS: 7.889
WITH: 20
HAS COOLDOWN: false
谁能解释为什么?
这是 hasCooldown()
中的一个简单逻辑错误。您可以从调试输出中看到,即使以秒为单位的时间小于冷却时间长度,它也会返回 false
以表示有冷却时间。
您可以通过在计算中使用临时变量来更轻松地了解原因。当您在您的地图中找到一个条目时,您正在执行与此等效的操作:
long startMillis = cooldown.get(p.getUniqueId(), type);
double elapsedSecs = (System.currentTimeMillis() - startMillis) / 1000.0;
long cooldownSecs = type.getTimeInTicks() / 20;
boolean hasCooldown = elapsedSecs > cooldownSecs // wrong!
倒退:如果elapsedSecs > cooldownSecs
,则冷却时间已超时。如果cooldownSecs < elapsedSecs
.
冷却时间仍然有效
所以,当elapsedSecs < cooldownSecs
时,hasCooldown()
误认为冷却时间超时,所以将其删除并returnsfalse
。我敢肯定你的代码的其他部分,发现没有冷却时间,插入一个新的,这就是你看到一个新的原因。
我正在尝试在我的 spigot 插件中制作冷却实用程序:
package net.gettrillium.trillium.api.cooldown;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import net.gettrillium.trillium.Utils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
public class Cooldown {
private static Table<UUID, CooldownType, Long> cooldown = HashBasedTable.create();
public static void setCooldown(Player p, CooldownType type) {
cooldown.put(p.getUniqueId(), type, System.currentTimeMillis());
}
public static boolean hasCooldown(Player p, CooldownType type) {
if (cooldown.contains(p.getUniqueId(), type)) {
Bukkit.broadcastMessage("GET: " + cooldown.get(p.getUniqueId(), type));
Bukkit.broadcastMessage("CURRENT MILLIS: " + System.currentTimeMillis());
Bukkit.broadcastMessage("SUBTRACTED: " + (System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)));
Bukkit.broadcastMessage("IN SECONDS: " + (System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0);
Bukkit.broadcastMessage("> WITH: " + (type.getTimeInTicks() / 20));
Bukkit.broadcastMessage("HAS COOLDOWN: " + (((System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0) > (type.getTimeInTicks() / 20)));
if (((System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0) > (type.getTimeInTicks() / 20)) {
return true;
} else {
cooldown.remove(p.getUniqueId(), type);
return false;
}
} else {
return false;
}
}
public static String getTime(Player p, CooldownType type) {
if (hasCooldown(p, type)) {
return Utils.timeToString((int) ((System.currentTimeMillis() - cooldown.get(p.getUniqueId(), type)) / 1000.0));
} else {
return null;
}
}
}
bukkit.broadcastMessage()
方法只是将消息发送到控制台并在游戏中作为调试。
我的问题是,每次我检查 cooldown
table,cooldown.contains(p.getUniqueId(), type)
总是一个新的 System.currentTimeMillis()
。它没有保存在 setCooldown 中注册的那个。
这个Cooldown
class是在teleport模块中使用的,你只需要注意cooldown
相关的if语句即可,其他都是teleport相关代码。
调试输出:
GET: 1433433920944
CURRENT MILLIS: 1433433928830
SUBTRACTED: 7888
IN SECONDS: 7.889
WITH: 20
HAS COOLDOWN: false
谁能解释为什么?
这是 hasCooldown()
中的一个简单逻辑错误。您可以从调试输出中看到,即使以秒为单位的时间小于冷却时间长度,它也会返回 false
以表示有冷却时间。
您可以通过在计算中使用临时变量来更轻松地了解原因。当您在您的地图中找到一个条目时,您正在执行与此等效的操作:
long startMillis = cooldown.get(p.getUniqueId(), type);
double elapsedSecs = (System.currentTimeMillis() - startMillis) / 1000.0;
long cooldownSecs = type.getTimeInTicks() / 20;
boolean hasCooldown = elapsedSecs > cooldownSecs // wrong!
倒退:如果elapsedSecs > cooldownSecs
,则冷却时间已超时。如果cooldownSecs < elapsedSecs
.
所以,当elapsedSecs < cooldownSecs
时,hasCooldown()
误认为冷却时间超时,所以将其删除并returnsfalse
。我敢肯定你的代码的其他部分,发现没有冷却时间,插入一个新的,这就是你看到一个新的原因。