Add optional web jukebox: vote for arena music tracks via a small HTTP API
Build / build (push) Successful in 1m19s
Build / build (push) Successful in 1m19s
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package us.tss3.blockparty.jukebox;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Issues short-lived, easy-to-type numeric codes that link a web voting session back to a
|
||||
* specific logged-in player, without requiring any real account/password auth on the web
|
||||
* page. A code is only ever handed out via the in-game {@code /blockparty musicvote}
|
||||
* command, so possessing one proves you're the player who ran it (or someone they showed it
|
||||
* to) for as long as it's valid.
|
||||
*/
|
||||
public class VoteCodeManager {
|
||||
|
||||
private record CodeEntry(UUID playerId, long expiresAtMs) {
|
||||
}
|
||||
|
||||
private final Map<String, CodeEntry> codes = new ConcurrentHashMap<>();
|
||||
private final SecureRandom random = new SecureRandom();
|
||||
|
||||
public String issueCode(UUID playerId, int ttlMinutes) {
|
||||
codes.values().removeIf(e -> e.playerId().equals(playerId));
|
||||
String code;
|
||||
do {
|
||||
code = String.valueOf(100000 + random.nextInt(900000));
|
||||
} while (codes.containsKey(code));
|
||||
codes.put(code, new CodeEntry(playerId, System.currentTimeMillis() + ttlMinutes * 60_000L));
|
||||
return code;
|
||||
}
|
||||
|
||||
/** Resolves a code to the player who issued it, or null if unknown/expired. */
|
||||
public UUID resolve(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
CodeEntry entry = codes.get(code);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
if (System.currentTimeMillis() > entry.expiresAtMs()) {
|
||||
codes.remove(code);
|
||||
return null;
|
||||
}
|
||||
return entry.playerId();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user