54 lines
1.5 KiB
Dart
54 lines
1.5 KiB
Dart
final class LauncherGameTicket {
|
|
static final RegExp _accountPattern = RegExp(r'^[!-<>-~]{1,17}$');
|
|
static final RegExp _ticketPattern = RegExp(r'^[A-Z0-9]{16}$');
|
|
|
|
final String account;
|
|
final String ticket;
|
|
final DateTime expiresAt;
|
|
|
|
const LauncherGameTicket({
|
|
required this.account,
|
|
required this.ticket,
|
|
required this.expiresAt,
|
|
});
|
|
|
|
factory LauncherGameTicket.fromJson(Map<String, dynamic> json) {
|
|
final rawAccount = json['account'];
|
|
final rawTicket = json['ticket'];
|
|
final rawExpiresAt = json['expires_at'];
|
|
if (rawAccount is! String ||
|
|
rawTicket is! String ||
|
|
rawExpiresAt is! String) {
|
|
throw const FormatException('Invalid game ticket payload types.');
|
|
}
|
|
|
|
final account = rawAccount;
|
|
final ticket = rawTicket;
|
|
final expiresAt = DateTime.tryParse(rawExpiresAt);
|
|
|
|
if (!_accountPattern.hasMatch(account)) {
|
|
throw const FormatException('Invalid game ticket account.');
|
|
}
|
|
if (!_ticketPattern.hasMatch(ticket)) {
|
|
throw const FormatException('Invalid game ticket value.');
|
|
}
|
|
if (expiresAt == null) {
|
|
throw const FormatException('Invalid game ticket expiration.');
|
|
}
|
|
|
|
return LauncherGameTicket(
|
|
account: account,
|
|
ticket: ticket,
|
|
expiresAt: expiresAt.toUtc(),
|
|
);
|
|
}
|
|
|
|
bool isUsable({
|
|
DateTime? now,
|
|
Duration minimumValidity = const Duration(seconds: 5),
|
|
}) {
|
|
final currentTime = (now ?? DateTime.now()).toUtc();
|
|
return expiresAt.isAfter(currentTime.add(minimumValidity));
|
|
}
|
|
}
|