Initial commit: CraftDock as of 2026-11-01
The previous GitHub history was lost with the account (the local .git was missing its refs and most objects), so this repository starts from the existing code. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
640e52c0c9
99 files changed
+12115
No files matched your search
@@ -0,0 +1,62 @@
|
||||
import fsp from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
// Persistent bridge between a Bedrock player's identity (numeric XUID + gamertag,
|
||||
// known only from the log directory) and their LevelDB record (keyed by a
|
||||
// self-signed UUID that never references the XUID). Learned while a player is
|
||||
// online by matching the live entity `uniqueId` (from querytarget) to a LevelDB
|
||||
// player's `UniqueID`; persisted so offline reads work forever afterwards.
|
||||
//
|
||||
// File: <dataRoot>/craftdock_bedrock_ids.json
|
||||
// { "<xuid>": { name, leveldbUuid, uniqueId, boundAt } }
|
||||
|
||||
const FILE = 'craftdock_bedrock_ids.json';
|
||||
|
||||
export function createBedrockIdentityBridge({ dataRoot, fileAdapter }) {
|
||||
const filePath = path.join(dataRoot, FILE);
|
||||
|
||||
async function readMap() {
|
||||
try {
|
||||
const data = JSON.parse(await fsp.readFile(filePath, 'utf8'));
|
||||
return data && typeof data === 'object' && !Array.isArray(data) ? data : {};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function writeMap(map) {
|
||||
try {
|
||||
await fsp.writeFile(filePath, JSON.stringify(map, null, 2), 'utf8');
|
||||
} catch { /* best-effort */ }
|
||||
}
|
||||
|
||||
// Bind xuid → LevelDB uuid using the live uniqueId or fallbackUuid.
|
||||
async function learn({ xuid, name, uniqueId, fallbackUuid }) {
|
||||
if (!xuid) return null;
|
||||
let targetUuid = fallbackUuid;
|
||||
if (!targetUuid && uniqueId != null) {
|
||||
const hit = await fileAdapter.findByUniqueId(String(uniqueId));
|
||||
if (hit) targetUuid = hit.uuid;
|
||||
}
|
||||
if (!targetUuid) return null;
|
||||
|
||||
const map = await readMap();
|
||||
const binding = {
|
||||
name: name ?? map[xuid]?.name ?? null,
|
||||
leveldbUuid: targetUuid,
|
||||
uniqueId: uniqueId ? String(uniqueId) : (map[xuid]?.uniqueId || null),
|
||||
boundAt: new Date().toISOString(),
|
||||
};
|
||||
map[xuid] = binding;
|
||||
await writeMap(map);
|
||||
return binding;
|
||||
}
|
||||
|
||||
|
||||
async function resolveLeveldbUuid(xuid) {
|
||||
const map = await readMap();
|
||||
return map[xuid]?.leveldbUuid || null;
|
||||
}
|
||||
|
||||
return { learn, resolveLeveldbUuid };
|
||||
}
|
||||
Reference in new issue
Block a user