mirror of
https://github.com/carm-outsource/TimeReward.git
synced 2026-06-04 07:18:16 +08:00
fix(claim): 修复了每日奖励可能被多次重复领取的bug。
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
|
||||
<groupId>cc.carm.plugin</groupId>
|
||||
<artifactId>timereward</artifactId>
|
||||
<version>3.1.5</version>
|
||||
<version>3.1.6</version>
|
||||
|
||||
<name>TimeReward</name>
|
||||
<description>在线时长自动领奖插件,通过指令发放奖励,基于EasyPlugin实现。</description>
|
||||
|
||||
@@ -30,6 +30,11 @@ public class ClaimCommand extends SubCommand<MainCommand> {
|
||||
Player player = (Player) sender;
|
||||
RewardManager manager = TimeRewardAPI.getRewardManager();
|
||||
|
||||
if(manager.isClaiming(player.getUniqueId())){
|
||||
PluginMessages.ALREADY_CLAIMING.sendTo(sender);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable String rewardID = args.length > 0 ? args[0] : null;
|
||||
if (rewardID == null) {
|
||||
|
||||
|
||||
@@ -91,6 +91,10 @@ public interface PluginMessages extends Configuration {
|
||||
"&c&l抱歉!&f但您暂时未满足领取奖励 &e%(award) &f的条件。"
|
||||
).params("award").build();
|
||||
|
||||
ConfiguredMessage<BaseComponent[]> ALREADY_CLAIMING = list().defaults(
|
||||
"&e&l请稍候...&f您当前有正在领取的奖励任务,单次只可领取一份奖励。"
|
||||
).build();
|
||||
|
||||
ConfiguredMessage<BaseComponent[]> NO_UNCLAIMED_REWARD = list().defaults(
|
||||
"&f您暂时没有未领取的奖励。"
|
||||
).build();
|
||||
|
||||
@@ -17,7 +17,7 @@ public enum IntervalType {
|
||||
),
|
||||
|
||||
DAILY(
|
||||
1, Duration.ofDays(1), time -> DateTimeUtils.sameDay(time.toLocalDate()),
|
||||
1, Duration.ofDays(1), time -> !DateTimeUtils.sameDay(time.toLocalDate()),
|
||||
(timeRecord, join) -> {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (!now.toLocalDate().isEqual(join.toLocalDate())) {
|
||||
|
||||
@@ -18,12 +18,15 @@ import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RewardManager {
|
||||
|
||||
protected BukkitRunnable runnable;
|
||||
|
||||
protected Map<UUID, CompletableFuture<Boolean>> claiming = new ConcurrentHashMap<>();
|
||||
|
||||
public RewardManager(Main main) {
|
||||
this.runnable = new BukkitRunnable() {
|
||||
@Override
|
||||
@@ -31,6 +34,8 @@ public class RewardManager {
|
||||
if (Bukkit.getOnlinePlayers().isEmpty()) return;
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (isClaiming(player.getUniqueId())) continue; // 如果正在领取奖励,则跳过
|
||||
|
||||
List<RewardContents> rewards = getUnclaimedRewards(player).stream()
|
||||
.filter(RewardContents::isAutoClaimed)
|
||||
.collect(Collectors.toList());
|
||||
@@ -61,6 +66,14 @@ public class RewardManager {
|
||||
return Collections.unmodifiableMap(RewardsConfig.getContents());
|
||||
}
|
||||
|
||||
public boolean isClaiming(@NotNull UUID uuid) {
|
||||
return claiming.containsKey(uuid) && !claiming.get(uuid).isDone();
|
||||
}
|
||||
|
||||
public CompletableFuture<Boolean> getClaiming(@NotNull UUID uuid) {
|
||||
return claiming.get(uuid);
|
||||
}
|
||||
|
||||
@Unmodifiable
|
||||
public @NotNull List<RewardContents> getUnclaimedRewards(@NotNull Player player) {
|
||||
return listRewards().values().stream()
|
||||
@@ -97,22 +110,27 @@ public class RewardManager {
|
||||
}
|
||||
|
||||
public CompletableFuture<Boolean> claimRewards(Player player, Collection<RewardContents> rewards, boolean check) {
|
||||
CompletableFuture<Boolean> exists = claiming.get(player.getUniqueId());
|
||||
if (exists != null) return CompletableFuture.completedFuture(false); // 如果玩家正在领取奖励,则直接返回false
|
||||
|
||||
Set<RewardContents> contents = rewards.stream()
|
||||
.filter(r -> !check || isClaimable(player, r))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (contents.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(true); // 没有可领取的奖励,直接返回true。
|
||||
}
|
||||
|
||||
Map<String, LocalDateTime> map = new LinkedHashMap<>();
|
||||
contents.forEach(reward -> map.put(reward.getRewardID(), LocalDateTime.now()));
|
||||
|
||||
return Main.getInstance().supplyAsync(() -> {
|
||||
try {
|
||||
|
||||
UserRewardData user = TimeRewardAPI.getUserManager().get(player);
|
||||
if (user == null) return false; // 玩家数据加载中
|
||||
if (user == null) return CompletableFuture.completedFuture(false); // 玩家数据加载中
|
||||
|
||||
CompletableFuture<Boolean> task = Main.getInstance().supplyAsync(() -> {
|
||||
try {
|
||||
Main.getStorage().addClaimedData(player.getUniqueId(), map);
|
||||
contents.forEach(user::updateClaimed);
|
||||
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Main.severe("为玩家 " + player.getName() + " 领取奖励时发生错误。");
|
||||
@@ -129,6 +147,12 @@ public class RewardManager {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
});
|
||||
|
||||
claiming.put(player.getUniqueId(), task);
|
||||
|
||||
return task.whenComplete((b, t) -> {
|
||||
claiming.remove(player.getUniqueId());
|
||||
});
|
||||
}
|
||||
|
||||
public void executeCommand(Player player, RewardContents reward) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cc.carm.plugin.timereward.user;
|
||||
|
||||
import cc.carm.lib.easyplugin.user.UserData;
|
||||
import cc.carm.lib.easyplugin.user.AbstractUserData;
|
||||
import cc.carm.plugin.timereward.data.IntervalType;
|
||||
import cc.carm.plugin.timereward.data.RewardContents;
|
||||
import cc.carm.plugin.timereward.data.TimeRecord;
|
||||
@@ -15,7 +15,7 @@ import java.util.UUID;
|
||||
/**
|
||||
* 用户奖励数据,用于存储用户的奖励的领取情况。
|
||||
*/
|
||||
public class UserRewardData extends UserData<UUID> {
|
||||
public class UserRewardData extends AbstractUserData<UUID> {
|
||||
|
||||
private final @NotNull Map<String, LocalDateTime> claimedRewards; // 记录已领取的奖励ID
|
||||
|
||||
@@ -35,7 +35,7 @@ public class UserRewardData extends UserData<UUID> {
|
||||
}
|
||||
|
||||
public @NotNull UUID getUserUUID() {
|
||||
return getKey();
|
||||
return key();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user