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 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(); } }