mirror of
https://github.com/carm-outsource/TimeReward.git
synced 2026-06-04 15:28:16 +08:00
fix(time): 尝试修复在线时间计算错误的问题
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cc.carm.plugin.tests;
|
||||
|
||||
import cc.carm.plugin.timereward.data.IntervalType;
|
||||
import cc.carm.plugin.timereward.data.TimeRecord;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class IntervalTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
System.out.println(IntervalType.DAILY.calculate(
|
||||
new TimeRecord(LocalDate.now(), 100, 200, 300, 400),
|
||||
LocalDateTime.now()
|
||||
).getSeconds());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user