Skip to content

Commit ecec1a5

Browse files
feat: leaderboards
1 parent 1c862c5 commit ecec1a5

26 files changed

Lines changed: 1807 additions & 3 deletions
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package net.swofty.commons.bedwars;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
import java.time.DayOfWeek;
7+
import java.time.ZoneOffset;
8+
import java.time.ZonedDateTime;
9+
import java.time.temporal.TemporalAdjusters;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
13+
@Getter
14+
public class BedWarsModeStats {
15+
private final Map<String, Long> wins;
16+
private final Map<String, Long> finalKills;
17+
private final Map<String, Long> bedsBroken;
18+
19+
@Setter private long dailyResetTimestamp;
20+
@Setter private long weeklyResetTimestamp;
21+
@Setter private long monthlyResetTimestamp;
22+
23+
public BedWarsModeStats() {
24+
this.wins = new HashMap<>();
25+
this.finalKills = new HashMap<>();
26+
this.bedsBroken = new HashMap<>();
27+
initializeResetTimestamps();
28+
}
29+
30+
public BedWarsModeStats(Map<String, Long> wins, Map<String, Long> finalKills, Map<String, Long> bedsBroken) {
31+
this.wins = new HashMap<>(wins);
32+
this.finalKills = new HashMap<>(finalKills);
33+
this.bedsBroken = new HashMap<>(bedsBroken);
34+
initializeResetTimestamps();
35+
}
36+
37+
public BedWarsModeStats(Map<String, Long> wins, Map<String, Long> finalKills, Map<String, Long> bedsBroken,
38+
long dailyResetTimestamp, long weeklyResetTimestamp, long monthlyResetTimestamp) {
39+
this.wins = new HashMap<>(wins);
40+
this.finalKills = new HashMap<>(finalKills);
41+
this.bedsBroken = new HashMap<>(bedsBroken);
42+
this.dailyResetTimestamp = dailyResetTimestamp;
43+
this.weeklyResetTimestamp = weeklyResetTimestamp;
44+
this.monthlyResetTimestamp = monthlyResetTimestamp;
45+
}
46+
47+
private void initializeResetTimestamps() {
48+
this.dailyResetTimestamp = computeNextDailyReset();
49+
this.weeklyResetTimestamp = computeNextWeeklyReset();
50+
this.monthlyResetTimestamp = computeNextMonthlyReset();
51+
}
52+
53+
public static BedWarsModeStats empty() {
54+
return new BedWarsModeStats();
55+
}
56+
57+
public void checkAndResetExpiredPeriods() {
58+
long now = System.currentTimeMillis();
59+
60+
if (now >= dailyResetTimestamp) {
61+
resetPeriod(BedwarsLeaderboardPeriod.DAILY);
62+
dailyResetTimestamp = computeNextDailyReset();
63+
}
64+
65+
if (now >= weeklyResetTimestamp) {
66+
resetPeriod(BedwarsLeaderboardPeriod.WEEKLY);
67+
weeklyResetTimestamp = computeNextWeeklyReset();
68+
}
69+
70+
if (now >= monthlyResetTimestamp) {
71+
resetPeriod(BedwarsLeaderboardPeriod.MONTHLY);
72+
monthlyResetTimestamp = computeNextMonthlyReset();
73+
}
74+
}
75+
76+
private static long computeNextDailyReset() {
77+
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
78+
ZonedDateTime nextReset = now.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
79+
return nextReset.toInstant().toEpochMilli();
80+
}
81+
82+
private static long computeNextWeeklyReset() {
83+
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
84+
ZonedDateTime nextReset = now.with(TemporalAdjusters.next(DayOfWeek.MONDAY))
85+
.withHour(0).withMinute(0).withSecond(0).withNano(0);
86+
return nextReset.toInstant().toEpochMilli();
87+
}
88+
89+
private static long computeNextMonthlyReset() {
90+
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
91+
ZonedDateTime nextReset = now.with(TemporalAdjusters.firstDayOfNextMonth())
92+
.withHour(0).withMinute(0).withSecond(0).withNano(0);
93+
return nextReset.toInstant().toEpochMilli();
94+
}
95+
96+
private String key(BedwarsLeaderboardMode mode, BedwarsLeaderboardPeriod period) {
97+
return mode.getKey() + ":" + period.getKey();
98+
}
99+
100+
public long getWins(BedwarsLeaderboardMode mode, BedwarsLeaderboardPeriod period) {
101+
return wins.getOrDefault(key(mode, period), 0L);
102+
}
103+
104+
public long getFinalKills(BedwarsLeaderboardMode mode, BedwarsLeaderboardPeriod period) {
105+
return finalKills.getOrDefault(key(mode, period), 0L);
106+
}
107+
108+
public long getBedsBroken(BedwarsLeaderboardMode mode, BedwarsLeaderboardPeriod period) {
109+
return bedsBroken.getOrDefault(key(mode, period), 0L);
110+
}
111+
112+
public void addWin(BedwarsLeaderboardMode mode, BedwarsLeaderboardPeriod period) {
113+
wins.merge(key(mode, period), 1L, Long::sum);
114+
}
115+
116+
public void addFinalKill(BedwarsLeaderboardMode mode, BedwarsLeaderboardPeriod period) {
117+
finalKills.merge(key(mode, period), 1L, Long::sum);
118+
}
119+
120+
public void addBedBroken(BedwarsLeaderboardMode mode, BedwarsLeaderboardPeriod period) {
121+
bedsBroken.merge(key(mode, period), 1L, Long::sum);
122+
}
123+
124+
public void recordWin(BedwarsLeaderboardMode mode) {
125+
for (BedwarsLeaderboardPeriod period : BedwarsLeaderboardPeriod.values()) {
126+
addWin(mode, period);
127+
}
128+
}
129+
130+
public void recordFinalKill(BedwarsLeaderboardMode mode) {
131+
for (BedwarsLeaderboardPeriod period : BedwarsLeaderboardPeriod.values()) {
132+
addFinalKill(mode, period);
133+
}
134+
}
135+
136+
public void recordBedBroken(BedwarsLeaderboardMode mode) {
137+
for (BedwarsLeaderboardPeriod period : BedwarsLeaderboardPeriod.values()) {
138+
addBedBroken(mode, period);
139+
}
140+
}
141+
142+
public void resetPeriod(BedwarsLeaderboardPeriod period) {
143+
for (BedwarsLeaderboardMode mode : BedwarsLeaderboardMode.values()) {
144+
String k = key(mode, period);
145+
wins.remove(k);
146+
finalKills.remove(k);
147+
bedsBroken.remove(k);
148+
}
149+
}
150+
151+
public BedWarsModeStats copy() {
152+
return new BedWarsModeStats(wins, finalKills, bedsBroken,
153+
dailyResetTimestamp, weeklyResetTimestamp, monthlyResetTimestamp);
154+
}
155+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package net.swofty.commons.bedwars;
2+
3+
import lombok.Getter;
4+
5+
import java.util.Arrays;
6+
import java.util.List;
7+
8+
@Getter
9+
public enum BedwarsLeaderboardMode {
10+
ALL("all", "All Modes"),
11+
CORE("core", "Core Modes"),
12+
SOLO("solo", "Solo"),
13+
DOUBLES("doubles", "Doubles"),
14+
THREE_THREE("3v3v3v3", "3v3v3v3"),
15+
FOUR_FOUR_FOUR("4v4v4v4", "4v4v4v4"),
16+
FOUR_FOUR("4v4", "4v4");
17+
18+
private final String key;
19+
private final String displayName;
20+
21+
BedwarsLeaderboardMode(String key, String displayName) {
22+
this.key = key;
23+
this.displayName = displayName;
24+
}
25+
26+
private static final List<BedwarsGameType> CORE_MODES = Arrays.asList(
27+
BedwarsGameType.SOLO,
28+
BedwarsGameType.DOUBLES,
29+
BedwarsGameType.THREE_THREE_THREE_THREE,
30+
BedwarsGameType.FOUR_FOUR_FOUR_FOUR
31+
);
32+
33+
public boolean includes(BedwarsGameType gameType) {
34+
return switch (this) {
35+
case ALL -> true;
36+
case CORE -> CORE_MODES.contains(gameType);
37+
case SOLO -> gameType == BedwarsGameType.SOLO;
38+
case DOUBLES -> gameType == BedwarsGameType.DOUBLES;
39+
case THREE_THREE -> gameType == BedwarsGameType.THREE_THREE_THREE_THREE;
40+
case FOUR_FOUR_FOUR -> gameType == BedwarsGameType.FOUR_FOUR_FOUR_FOUR;
41+
case FOUR_FOUR -> gameType == BedwarsGameType.FOUR_FOUR;
42+
};
43+
}
44+
45+
public BedwarsLeaderboardMode next() {
46+
BedwarsLeaderboardMode[] values = values();
47+
int nextOrdinal = (this.ordinal() + 1) % values.length;
48+
return values[nextOrdinal];
49+
}
50+
51+
public BedwarsLeaderboardMode previous() {
52+
BedwarsLeaderboardMode[] values = values();
53+
int prevOrdinal = (this.ordinal() - 1 + values.length) % values.length;
54+
return values[prevOrdinal];
55+
}
56+
57+
public static BedwarsLeaderboardMode fromKey(String key) {
58+
for (BedwarsLeaderboardMode mode : values()) {
59+
if (mode.key.equalsIgnoreCase(key)) {
60+
return mode;
61+
}
62+
}
63+
return ALL;
64+
}
65+
66+
public static BedwarsLeaderboardMode fromGameType(BedwarsGameType gameType) {
67+
return switch (gameType) {
68+
case SOLO -> SOLO;
69+
case DOUBLES, ULTIMATE_DOUBLES -> DOUBLES;
70+
case THREE_THREE_THREE_THREE -> THREE_THREE;
71+
case FOUR_FOUR_FOUR_FOUR, ULTIMATE_FOURS -> FOUR_FOUR_FOUR;
72+
case FOUR_FOUR -> FOUR_FOUR;
73+
};
74+
}
75+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package net.swofty.commons.bedwars;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum BedwarsLeaderboardPeriod {
7+
DAILY("daily", "Daily", 1),
8+
WEEKLY("weekly", "Weekly", 7),
9+
MONTHLY("monthly", "Monthly", 30),
10+
LIFETIME("lifetime", "Lifetime", -1);
11+
12+
private final String key;
13+
private final String displayName;
14+
private final int days;
15+
16+
BedwarsLeaderboardPeriod(String key, String displayName, int days) {
17+
this.key = key;
18+
this.displayName = displayName;
19+
this.days = days;
20+
}
21+
22+
public BedwarsLeaderboardPeriod next() {
23+
BedwarsLeaderboardPeriod[] values = values();
24+
int nextOrdinal = (this.ordinal() + 1) % values.length;
25+
return values[nextOrdinal];
26+
}
27+
28+
public BedwarsLeaderboardPeriod previous() {
29+
BedwarsLeaderboardPeriod[] values = values();
30+
int prevOrdinal = (this.ordinal() - 1 + values.length) % values.length;
31+
return values[prevOrdinal];
32+
}
33+
34+
public static BedwarsLeaderboardPeriod fromKey(String key) {
35+
for (BedwarsLeaderboardPeriod period : values()) {
36+
if (period.key.equalsIgnoreCase(key)) {
37+
return period;
38+
}
39+
}
40+
return LIFETIME;
41+
}
42+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package net.swofty.commons.bedwars;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum BedwarsLeaderboardView {
7+
TOP_10("top_10", "Top 10"),
8+
PLAYERS_AROUND_YOU("around_you", "Players Around You");
9+
10+
private final String key;
11+
private final String displayName;
12+
13+
BedwarsLeaderboardView(String key, String displayName) {
14+
this.key = key;
15+
this.displayName = displayName;
16+
}
17+
18+
public BedwarsLeaderboardView next() {
19+
BedwarsLeaderboardView[] values = values();
20+
int nextOrdinal = (this.ordinal() + 1) % values.length;
21+
return values[nextOrdinal];
22+
}
23+
24+
public BedwarsLeaderboardView previous() {
25+
BedwarsLeaderboardView[] values = values();
26+
int prevOrdinal = (this.ordinal() - 1 + values.length) % values.length;
27+
return values[prevOrdinal];
28+
}
29+
30+
public static BedwarsLeaderboardView fromKey(String key) {
31+
for (BedwarsLeaderboardView view : values()) {
32+
if (view.key.equalsIgnoreCase(key)) {
33+
return view;
34+
}
35+
}
36+
return TOP_10;
37+
}
38+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package net.swofty.commons.bedwars;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum BedwarsStatType {
7+
LEVEL("level", "Bed Wars Level", false),
8+
WINS("wins", "Wins", true),
9+
FINAL_KILLS("final_kills", "Final Kills", true),
10+
BEDS_BROKEN("beds_broken", "Beds Broken", true);
11+
12+
private final String key;
13+
private final String displayName;
14+
private final boolean timedTracking;
15+
16+
BedwarsStatType(String key, String displayName, boolean timedTracking) {
17+
this.key = key;
18+
this.displayName = displayName;
19+
this.timedTracking = timedTracking;
20+
}
21+
22+
public static BedwarsStatType fromKey(String key) {
23+
for (BedwarsStatType type : values()) {
24+
if (type.key.equalsIgnoreCase(key)) {
25+
return type;
26+
}
27+
}
28+
return null;
29+
}
30+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package net.swofty.commons.bedwars;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum BedwarsTextAlignment {
7+
CENTER("center", "Center"),
8+
BLOCK("block", "Block");
9+
10+
private final String key;
11+
private final String displayName;
12+
13+
BedwarsTextAlignment(String key, String displayName) {
14+
this.key = key;
15+
this.displayName = displayName;
16+
}
17+
18+
public BedwarsTextAlignment next() {
19+
BedwarsTextAlignment[] values = values();
20+
int nextOrdinal = (this.ordinal() + 1) % values.length;
21+
return values[nextOrdinal];
22+
}
23+
24+
public BedwarsTextAlignment previous() {
25+
BedwarsTextAlignment[] values = values();
26+
int prevOrdinal = (this.ordinal() - 1 + values.length) % values.length;
27+
return values[prevOrdinal];
28+
}
29+
30+
public static BedwarsTextAlignment fromKey(String key) {
31+
for (BedwarsTextAlignment alignment : values()) {
32+
if (alignment.key.equalsIgnoreCase(key)) {
33+
return alignment;
34+
}
35+
}
36+
return CENTER;
37+
}
38+
}

0 commit comments

Comments
 (0)