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

fix(time): 尝试修复在线时间计算错误的问题

This commit is contained in:
2025-07-10 19:17:07 +08:00
parent cc451cd1f4
commit 8a8c23bd7e
5 changed files with 76 additions and 30 deletions
@@ -1,9 +1,11 @@
package cc.carm.plugin.timereward.data;
import cc.carm.plugin.timereward.Main;
import cc.carm.plugin.timereward.util.DateTimeUtils;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.function.BiFunction;
@@ -18,16 +20,25 @@ public enum IntervalType {
DAILY(
1, Duration.ofDays(1), time -> !DateTimeUtils.sameDay(time.toLocalDate()),
(timeRecord, join) -> {
(record, join) -> {
LocalDateTime now = LocalDateTime.now();
if (!now.toLocalDate().isEqual(join.toLocalDate())) {
// 加入的时间和现在的时间不在同一天
return Duration.between(DateTimeUtils.todayStartTime(), now);
LocalDate today = LocalDate.now();
if (DateTimeUtils.sameDay(join.toLocalDate(), today)) {
// 如果加入的时间和今天的日期相同
if (DateTimeUtils.sameDay(record.getDate(), today)) {
// 如果上一次记录的日期和今天的日期相同
// 则从加入的时间开始计算到现在的时间,并加上当天的游玩时间
return Duration.between(join, now).plus(record.getDailyTime());
} else {
// 如果上一次记录的日期和今天的日期不同
// 则从加入的时间开始计算到现在的时间
return Duration.between(join, now);
}
} else {
// 如果加入的时间和今天的日期不同
// 则从今天的0点开始计算到现在的时间
return Duration.between(today.atTime(0, 0, 0), now);
}
if (now.toLocalDate().isEqual(timeRecord.getDate())) { // 和记录还在同一天
return Duration.between(join, now).plus(timeRecord.getDailyTime());
}
return Duration.between(join, now); // 加入的时间和现在的时间在同一天
}
),
WEEKLY(
@@ -35,13 +46,15 @@ public enum IntervalType {
time -> !DateTimeUtils.sameWeek(time),
(r, join) -> {
LocalDateTime now = LocalDateTime.now();
if (!DateTimeUtils.sameWeek(join, now)) {
if (DateTimeUtils.sameWeek(join.toLocalDate(), now)) {
if (DateTimeUtils.sameWeek(r.getDate(), now.toLocalDate())) {
return Duration.between(join, now).plus(r.getWeeklyTime());
} else {
return Duration.between(join, now);
}
} else {
return Duration.between(DateTimeUtils.currentWeekStartTime(), now);
}
if (DateTimeUtils.sameWeek(r.getDate(), now)) {
return Duration.between(join, now).plus(r.getWeeklyTime());
}
return Duration.between(join, now);
}
),
@@ -50,13 +63,15 @@ public enum IntervalType {
time -> !DateTimeUtils.sameMonth(time.toLocalDate()),
(r, join) -> {
LocalDateTime now = LocalDateTime.now();
if (!DateTimeUtils.sameMonth(join.toLocalDate(), now.toLocalDate())) {
if (DateTimeUtils.sameMonth(join.toLocalDate(), now.toLocalDate())) {
if (DateTimeUtils.sameMonth(r.getDate(), now.toLocalDate())) {
return Duration.between(join, now).plus(r.getMonthlyTime());
} else {
return Duration.between(join, now);
}
} else {
return Duration.between(DateTimeUtils.currentMonthStartTime(), now);
}
if (DateTimeUtils.sameMonth(r.getDate(), now.toLocalDate())) {
return Duration.between(join, now).plus(r.getMonthlyTime());
}
return Duration.between(join, now);
}
);
@@ -82,22 +97,19 @@ public enum IntervalType {
return maxDuration;
}
public @NotNull BiFunction<TimeRecord, LocalDateTime, Duration> calculator() {
return calculator;
}
public @NotNull Predicate<LocalDateTime> changePredicator() {
return periodChangePredicate;
}
public Duration calculate(@NotNull TimeRecord timeRecord, @NotNull LocalDateTime joinTime) {
Duration result = calculator.apply(timeRecord, joinTime);
// 如果超过最大值,则返回最大值
return result.compareTo(maxDuration) > 0 ? maxDuration : result;
if (result.compareTo(maxDuration) > 0) {
Main.debugging("在线时间超过最大值,类型: " + this.name() + ", 计算结果: " + result + " 加入时间 " + joinTime + " 时间记录" + timeRecord);
return maxDuration;
}
return result;
}
public boolean isPeriodChanged(@NotNull LocalDateTime claimedDate) {
return changePredicator().test(claimedDate);
return periodChangePredicate.test(claimedDate);
}
public static IntervalType parse(String input) {
@@ -38,15 +38,18 @@ public class UserManager extends UserDataManager<UUID, UserRewardData> {
MySQLStorage storage = Main.getStorage();
@Nullable UserRewardData current = loadData(data.getUserUUID()); // 考虑读取时间差,优先利用数据库的当前数据计算
TimeRecord oldRecord = current == null ? data.getTimeRecord() : current.getTimeRecord();
// 考虑读取时间差,优先利用数据库的当前数据计算
@Nullable TimeRecord inDatabase = storage.loadTimeRecord(data.getUserUUID());
TimeRecord oldRecord = inDatabase == null ? data.getTimeRecord() : inDatabase;
Main.debugging("用户 " + data.getUserUUID() + " 的旧记录: " + oldRecord);
// 只需要保存游玩时间数据,领取数据已经实时保存了
Duration daily = IntervalType.DAILY.calculate(oldRecord, data.getJoinTime());
Duration weekly = IntervalType.WEEKLY.calculate(oldRecord, data.getJoinTime());
Duration monthly = IntervalType.MONTHLY.calculate(oldRecord, data.getJoinTime());
Duration total = IntervalType.TOTAL.calculate(oldRecord, data.getJoinTime());
TimeRecord newRecord = new TimeRecord(LocalDate.now(), daily, weekly, monthly, total);
Main.debugging("用户 " + data.getUserUUID() + " 的新记录: " + newRecord);
storage.savePlayTime(data.getUserUUID(), newRecord);
}
@@ -76,6 +76,13 @@ public class MySQLStorage {
long monthly = rs.getLong("monthly_time");
long total = rs.getLong("total_time");
Main.debugging("成功从数据库中加载用户在线时间记录: " + uuid + " -> {",
" - DAILY = " + daily,
" - WEEKLY = " + weekly,
" - MONTHLY = " + monthly,
" - TOTAL = " + total,
"}");
return new TimeRecord(date, daily, weekly, monthly, total);
}, TimeRecord.empty());
}
@@ -18,7 +18,9 @@ public class DateTimeUtils {
}
public static boolean sameDay(LocalDate a, LocalDate b) {
return a.getDayOfYear() == b.getDayOfYear() && a.getYear() == b.getYear();
return a.getYear() == b.getYear() &&
a.getMonth() == b.getMonth() &&
a.getDayOfMonth() == b.getDayOfMonth();
}
public static boolean sameWeek(Temporal a) {