1
mirror of https://github.com/carm-outsource/TimeReward.git synced 2026-06-05 01:08:10 +08:00

1 Commits

Author SHA1 Message Date
carm 1078c7e03d feat(time): 支持在周期内循环时间发奖 2023-09-07 05:09:21 +08:00
8 changed files with 57 additions and 33 deletions
+1 -1
View File
@@ -18,7 +18,7 @@
<groupId>cc.carm.plugin</groupId>
<artifactId>timereward</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<name>TimeReward</name>
<description>在线时长自动领奖插件,通过指令发放奖励,基于EasyPlugin实现。</description>
@@ -17,6 +17,12 @@ import java.util.Map;
" [type] 奖励的类型序号",
" | “0”代表总计时间奖励,“1”代表每日在线奖励,",
" | “2”代表每周在线奖励,“3”代表每月在线奖励。",
" [time] 奖励发放要求的时间(秒)",
" [loop] 奖励是否按循环时间发放",
" | 可以填入 true 或 false",
" | 若启用,则在规定的周期内,每满足指定时间一次则发放一次奖励",
" | 如 类型为 “每周在线奖励” 时间为 “12小时” ",
" | 则 代表 代表在这周内每12小时发放一次奖励,下一周时间重新开始算",
" [name] 奖励的显示名称,可以是任意字符串",
" | 可以在 commands 中使用 %(name) 来获取该奖励的名称",
" | 也可以使用变量 %TimeReward_reward_<奖励ID>% 来获取对应奖励的名称",
@@ -60,14 +60,14 @@ public enum IntervalType {
);
private final int id;
private final @NotNull Predicate<LocalDateTime> reclaimPreficate;
private final @NotNull Predicate<LocalDateTime> periodChangePredicate;
private final @NotNull BiFunction<TimeRecord, LocalDateTime, Duration> calculator;
IntervalType(int id,
@NotNull Predicate<LocalDateTime> reclaimablePredicate,
@NotNull Predicate<LocalDateTime> periodChangePredicate,
@NotNull BiFunction<TimeRecord, LocalDateTime, Duration> calculator) {
this.id = id;
this.reclaimPreficate = reclaimablePredicate;
this.periodChangePredicate = periodChangePredicate;
this.calculator = calculator;
}
@@ -79,16 +79,16 @@ public enum IntervalType {
return calculator;
}
public @NotNull Predicate<LocalDateTime> getReclaimablePredicate() {
return reclaimPreficate;
public @NotNull Predicate<LocalDateTime> getPreiodChangePredicate() {
return periodChangePredicate;
}
public Duration calculate(@NotNull TimeRecord timeRecord, @NotNull LocalDateTime joinTime) {
return calculator.apply(timeRecord, joinTime);
}
public boolean isReclaimable(@NotNull LocalDateTime claimedDate) {
return reclaimPreficate.test(claimedDate);
public boolean isPeriodChanged(@NotNull LocalDateTime claimedDate) {
return periodChangePredicate.test(claimedDate);
}
public static IntervalType parse(String input) {
@@ -15,6 +15,7 @@ public class RewardContents {
public final @NotNull IntervalType type;
private final long time;
private final boolean loop;
private final @Nullable String name;
private final @Nullable String permission;
@@ -22,12 +23,13 @@ public class RewardContents {
private final boolean auto;
public RewardContents(@NotNull String id, @NotNull IntervalType type, long time,
public RewardContents(@NotNull String id, @NotNull IntervalType type, long time, boolean loop,
@Nullable String name, @Nullable String permission,
@NotNull List<String> commands, boolean auto) {
this.id = id;
this.type = type;
this.time = time;
this.loop = loop;
this.name = name;
this.permission = permission;
this.commands = commands;
@@ -42,6 +44,10 @@ public class RewardContents {
return type;
}
public boolean isLoop() {
return loop;
}
public long getTime() {
return time;
}
@@ -70,11 +76,11 @@ public class RewardContents {
return permission == null || player.hasPermission(permission);
}
public Map<String, Object> serialize() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("time", getTime());
map.put("type", getType().getID());
map.put("loop", isLoop());
if (getName() != null) map.put("name", getName());
if (getPermission() != null) map.put("permission", getPermission());
map.put("commands", getCommands());
@@ -96,17 +102,15 @@ public class RewardContents {
}
return new RewardContents(
id, intervalType, time,
section.getString("name"),
section.getString("permission"),
section.getStringList("commands"),
section.getBoolean("auto", false)
id, intervalType, time, section.getBoolean("loop", false),
section.getString("name"), section.getString("permission"),
section.getStringList("commands"), section.getBoolean("auto", false)
);
}
public static RewardContents defaults(String id) {
return new RewardContents(
id, IntervalType.TOTAL, 7200,
id, IntervalType.TOTAL, 7200, false,
"&f[初级奖励] &e总在线时长 2小时", "TimeReward.vip",
Collections.singletonList("say &f恭喜 &b%player_name% &f领取了奖励 &r%(name) &f"),
true
@@ -4,6 +4,7 @@ import cc.carm.lib.easyplugin.utils.MessageUtils;
import cc.carm.plugin.timereward.Main;
import cc.carm.plugin.timereward.TimeRewardAPI;
import cc.carm.plugin.timereward.conf.RewardsConfig;
import cc.carm.plugin.timereward.data.IntervalType;
import cc.carm.plugin.timereward.data.RewardContents;
import cc.carm.plugin.timereward.user.UserRewardData;
import org.bukkit.Bukkit;
@@ -13,6 +14,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@@ -67,11 +69,25 @@ public class RewardManager {
}
public boolean isClaimable(Player player, RewardContents reward) {
UserRewardData user = TimeRewardAPI.getUserManager().get(player);
if (!reward.checkPermission(player)) return false; // 满足权限
return !user.isClaimed(reward) // 未曾领取
&& user.isTimeEnough(reward)// 时间足够
&& reward.checkPermission(player); // 满足权限
UserRewardData user = TimeRewardAPI.getUserManager().get(player);
IntervalType intervalType = reward.getType();
LocalDateTime lastClaimed = user.getClaimedDate(reward);
if (reward.isLoop()) { // 循环奖励
if (lastClaimed == null || intervalType.isPeriodChanged(lastClaimed)) {
// 无上次领取记录或上次领取的时间不在一个周期内,则直接判断时间是否足够一次循环领取的时间
return user.getOnlineDuration(intervalType).getSeconds() > reward.getTime();
} else {
// 有上次领取记录,且在同一周期内,则直接判断相隔时间是否满足一个周期
return Duration.between(lastClaimed, LocalDateTime.now()).getSeconds() > reward.getTime();
}
} else { // 非循环奖励
if (lastClaimed == null || intervalType.isPeriodChanged(lastClaimed)) { // 无上次领取记录,则直接判断时间是否足够领取的时间
return user.getOnlineDuration(intervalType).getSeconds() > reward.getTime();
} else return false; // 有同一周期内的领取记录,则玩家不得重复领取了
}
}
public CompletableFuture<Boolean> claimReward(Player player, RewardContents reward, boolean check) {
@@ -91,7 +107,7 @@ public class RewardManager {
UserRewardData user = TimeRewardAPI.getUserManager().get(player);
Main.getStorage().addClaimedData(player.getUniqueId(), map);
contents.forEach(user::addClaimedReward);
contents.forEach(user::updateClaimed);
return true;
} catch (Exception ex) {
@@ -59,7 +59,6 @@ public class MySQLStorage {
public @Nullable UserRewardData loadData(@NotNull UUID uuid) throws Exception {
TimeRecord recordDate = loadTimeRecord(uuid);
System.out.println(recordDate.toString());
Map<String, LocalDateTime> claimedData = loadClaimedData(uuid);
return new UserRewardData(uuid, recordDate, claimedData);
}
@@ -85,7 +84,7 @@ public class MySQLStorage {
public Map<String, LocalDateTime> loadClaimedData(@NotNull UUID uuid) throws Exception {
return DatabaseTables.USER_CLAIMED.createQuery()
.addCondition("uuid", uuid).build()
.executeFunction((query) -> {
.executeFunction(query -> {
ResultSet rs = query.getResultSet();
Map<String, LocalDateTime> map = new LinkedHashMap<>();
@@ -30,8 +30,7 @@ public class LockedRewardData extends UserRewardData {
}
@Override
public boolean addClaimedReward(@NotNull RewardContents reward) {
return false;
public void updateClaimed(@NotNull RewardContents reward) {
}
}
@@ -5,6 +5,7 @@ import cc.carm.plugin.timereward.data.IntervalType;
import cc.carm.plugin.timereward.data.RewardContents;
import cc.carm.plugin.timereward.data.TimeRecord;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.Duration;
import java.time.LocalDateTime;
@@ -64,21 +65,20 @@ public class UserRewardData extends UserData<UUID> {
return getOnlineDuration(reward.getType()).getSeconds() >= reward.getTime();
}
public @NotNull Map<String, LocalDateTime> getClaimedRewards() {
return claimedRewards;
}
public boolean isClaimed(@NotNull RewardContents reward) {
LocalDateTime claimedDate = claimedRewards.get(reward.getRewardID());
if (claimedDate == null) return false;
return !reward.getType().isReclaimable(claimedDate);
public @Nullable LocalDateTime getClaimedDate(@NotNull RewardContents reward) {
return claimedRewards.get(reward.getRewardID());
}
public boolean addClaimedReward(@NotNull RewardContents reward) {
if (isClaimed(reward)) return false; // 已经领取过了
public boolean isClaimed(@NotNull RewardContents reward) {
return claimedRewards.containsKey(reward.getRewardID());
}
public void updateClaimed(@NotNull RewardContents reward) {
this.claimedRewards.put(reward.getRewardID(), LocalDateTime.now());
return true;
}
}