@minecraft-docker/mcctl 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/dist/application/index.d.ts +2 -0
  2. package/dist/application/index.d.ts.map +1 -0
  3. package/dist/application/index.js +5 -0
  4. package/dist/application/index.js.map +1 -0
  5. package/dist/commands/backup.d.ts +16 -0
  6. package/dist/commands/backup.d.ts.map +1 -0
  7. package/dist/commands/backup.js +182 -0
  8. package/dist/commands/backup.js.map +1 -0
  9. package/dist/commands/ban.d.ts +14 -0
  10. package/dist/commands/ban.d.ts.map +1 -0
  11. package/dist/commands/ban.js +418 -0
  12. package/dist/commands/ban.js.map +1 -0
  13. package/dist/commands/config.d.ts +18 -0
  14. package/dist/commands/config.d.ts.map +1 -0
  15. package/dist/commands/config.js +106 -0
  16. package/dist/commands/config.js.map +1 -0
  17. package/dist/commands/create.d.ts +22 -0
  18. package/dist/commands/create.d.ts.map +1 -0
  19. package/dist/commands/create.js +83 -0
  20. package/dist/commands/create.js.map +1 -0
  21. package/dist/commands/delete.d.ts +17 -0
  22. package/dist/commands/delete.d.ts.map +1 -0
  23. package/dist/commands/delete.js +71 -0
  24. package/dist/commands/delete.js.map +1 -0
  25. package/dist/commands/exec.d.ts +10 -0
  26. package/dist/commands/exec.d.ts.map +1 -0
  27. package/dist/commands/exec.js +29 -0
  28. package/dist/commands/exec.js.map +1 -0
  29. package/dist/commands/index.d.ts +18 -0
  30. package/dist/commands/index.d.ts.map +1 -0
  31. package/dist/commands/index.js +18 -0
  32. package/dist/commands/index.js.map +1 -0
  33. package/dist/commands/init.d.ts +9 -0
  34. package/dist/commands/init.d.ts.map +1 -0
  35. package/dist/commands/init.js +186 -0
  36. package/dist/commands/init.js.map +1 -0
  37. package/dist/commands/kick.d.ts +12 -0
  38. package/dist/commands/kick.d.ts.map +1 -0
  39. package/dist/commands/kick.js +71 -0
  40. package/dist/commands/kick.js.map +1 -0
  41. package/dist/commands/migrate.d.ts +18 -0
  42. package/dist/commands/migrate.d.ts.map +1 -0
  43. package/dist/commands/migrate.js +470 -0
  44. package/dist/commands/migrate.js.map +1 -0
  45. package/dist/commands/op.d.ts +12 -0
  46. package/dist/commands/op.d.ts.map +1 -0
  47. package/dist/commands/op.js +220 -0
  48. package/dist/commands/op.js.map +1 -0
  49. package/dist/commands/player-online.d.ts +11 -0
  50. package/dist/commands/player-online.d.ts.map +1 -0
  51. package/dist/commands/player-online.js +151 -0
  52. package/dist/commands/player-online.js.map +1 -0
  53. package/dist/commands/player.d.ts +18 -0
  54. package/dist/commands/player.d.ts.map +1 -0
  55. package/dist/commands/player.js +352 -0
  56. package/dist/commands/player.js.map +1 -0
  57. package/dist/commands/server-backup.d.ts +36 -0
  58. package/dist/commands/server-backup.d.ts.map +1 -0
  59. package/dist/commands/server-backup.js +320 -0
  60. package/dist/commands/server-backup.js.map +1 -0
  61. package/dist/commands/server-restore.d.ts +13 -0
  62. package/dist/commands/server-restore.d.ts.map +1 -0
  63. package/dist/commands/server-restore.js +294 -0
  64. package/dist/commands/server-restore.js.map +1 -0
  65. package/dist/commands/status.d.ts +13 -0
  66. package/dist/commands/status.d.ts.map +1 -0
  67. package/dist/commands/status.js +325 -0
  68. package/dist/commands/status.js.map +1 -0
  69. package/dist/commands/whitelist.d.ts +12 -0
  70. package/dist/commands/whitelist.d.ts.map +1 -0
  71. package/dist/commands/whitelist.js +316 -0
  72. package/dist/commands/whitelist.js.map +1 -0
  73. package/dist/commands/world.d.ts +16 -0
  74. package/dist/commands/world.d.ts.map +1 -0
  75. package/dist/commands/world.js +135 -0
  76. package/dist/commands/world.js.map +1 -0
  77. package/dist/domain/index.d.ts +2 -0
  78. package/dist/domain/index.d.ts.map +1 -0
  79. package/dist/domain/index.js +7 -0
  80. package/dist/domain/index.js.map +1 -0
  81. package/dist/index.d.ts +3 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +609 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/infrastructure/adapters/ClackPromptAdapter.d.ts +29 -0
  86. package/dist/infrastructure/adapters/ClackPromptAdapter.d.ts.map +1 -0
  87. package/dist/infrastructure/adapters/ClackPromptAdapter.js +419 -0
  88. package/dist/infrastructure/adapters/ClackPromptAdapter.js.map +1 -0
  89. package/dist/infrastructure/adapters/index.d.ts +3 -0
  90. package/dist/infrastructure/adapters/index.d.ts.map +1 -0
  91. package/dist/infrastructure/adapters/index.js +5 -0
  92. package/dist/infrastructure/adapters/index.js.map +1 -0
  93. package/dist/infrastructure/di/container.d.ts +47 -0
  94. package/dist/infrastructure/di/container.d.ts.map +1 -0
  95. package/dist/infrastructure/di/container.js +140 -0
  96. package/dist/infrastructure/di/container.js.map +1 -0
  97. package/dist/infrastructure/di/index.d.ts +2 -0
  98. package/dist/infrastructure/di/index.d.ts.map +1 -0
  99. package/dist/infrastructure/di/index.js +2 -0
  100. package/dist/infrastructure/di/index.js.map +1 -0
  101. package/dist/infrastructure/index.d.ts +4 -0
  102. package/dist/infrastructure/index.d.ts.map +1 -0
  103. package/dist/infrastructure/index.js +7 -0
  104. package/dist/infrastructure/index.js.map +1 -0
  105. package/dist/lib/mojang-api.d.ts +51 -0
  106. package/dist/lib/mojang-api.d.ts.map +1 -0
  107. package/dist/lib/mojang-api.js +136 -0
  108. package/dist/lib/mojang-api.js.map +1 -0
  109. package/dist/lib/player-cache.d.ts +79 -0
  110. package/dist/lib/player-cache.d.ts.map +1 -0
  111. package/dist/lib/player-cache.js +302 -0
  112. package/dist/lib/player-cache.js.map +1 -0
  113. package/dist/lib/player-json.d.ts +69 -0
  114. package/dist/lib/player-json.d.ts.map +1 -0
  115. package/dist/lib/player-json.js +96 -0
  116. package/dist/lib/player-json.js.map +1 -0
  117. package/dist/lib/prompts/action-select.d.ts +23 -0
  118. package/dist/lib/prompts/action-select.d.ts.map +1 -0
  119. package/dist/lib/prompts/action-select.js +124 -0
  120. package/dist/lib/prompts/action-select.js.map +1 -0
  121. package/dist/lib/prompts/index.d.ts +7 -0
  122. package/dist/lib/prompts/index.d.ts.map +1 -0
  123. package/dist/lib/prompts/index.js +7 -0
  124. package/dist/lib/prompts/index.js.map +1 -0
  125. package/dist/lib/prompts/player-select.d.ts +25 -0
  126. package/dist/lib/prompts/player-select.d.ts.map +1 -0
  127. package/dist/lib/prompts/player-select.js +122 -0
  128. package/dist/lib/prompts/player-select.js.map +1 -0
  129. package/dist/lib/prompts/server-select.d.ts +26 -0
  130. package/dist/lib/prompts/server-select.d.ts.map +1 -0
  131. package/dist/lib/prompts/server-select.js +99 -0
  132. package/dist/lib/prompts/server-select.js.map +1 -0
  133. package/dist/lib/rcon.d.ts +53 -0
  134. package/dist/lib/rcon.d.ts.map +1 -0
  135. package/dist/lib/rcon.js +131 -0
  136. package/dist/lib/rcon.js.map +1 -0
  137. package/dist/lib/shell.d.ts +109 -0
  138. package/dist/lib/shell.d.ts.map +1 -0
  139. package/dist/lib/shell.js +318 -0
  140. package/dist/lib/shell.js.map +1 -0
  141. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ export { Container, getContainer, resetContainer } from './container.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/di/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAyB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { ClackPromptAdapter } from './adapters/ClackPromptAdapter.js';
2
+ export { ShellAdapter, ServerRepository, WorldRepository, DocsAdapter, } from '@minecraft-docker/shared';
3
+ export { Container, getContainer, resetContainer } from './di/index.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/infrastructure/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAGtE,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,7 @@
1
+ // CLI-specific adapter
2
+ export { ClackPromptAdapter } from './adapters/ClackPromptAdapter.js';
3
+ // Re-export shared adapters for backward compatibility
4
+ export { ShellAdapter, ServerRepository, WorldRepository, DocsAdapter, } from '@minecraft-docker/shared';
5
+ // DI Container (CLI-specific)
6
+ export { Container, getContainer, resetContainer } from './di/index.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/infrastructure/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAEtE,uDAAuD;AACvD,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,8BAA8B;AAC9B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Mojang API Client
3
+ * Provides player lookup functionality via Mojang API
4
+ */
5
+ export interface MojangProfile {
6
+ id: string;
7
+ name: string;
8
+ }
9
+ export interface PlayerInfo {
10
+ name: string;
11
+ uuid: string;
12
+ uuidNoDashes: string;
13
+ skinUrl?: string;
14
+ isOnline?: boolean;
15
+ server?: string;
16
+ source: 'mojang' | 'offline' | 'cache';
17
+ }
18
+ /**
19
+ * Mojang API client for player lookup
20
+ */
21
+ export declare class MojangApiClient {
22
+ private static readonly API_BASE;
23
+ private static readonly SESSION_BASE;
24
+ /**
25
+ * Look up a player by username via Mojang API
26
+ * Returns null if player not found
27
+ */
28
+ lookupByUsername(username: string): Promise<PlayerInfo | null>;
29
+ /**
30
+ * Get detailed profile including skin URL
31
+ * Requires UUID (with or without dashes)
32
+ */
33
+ getProfile(uuid: string): Promise<PlayerInfo | null>;
34
+ }
35
+ /**
36
+ * Format UUID with dashes
37
+ * Input: 8667ba71b85a4004af54457a9734eed7
38
+ * Output: 8667ba71-b85a-4004-af54-457a9734eed7
39
+ */
40
+ export declare function formatUuid(uuid: string): string;
41
+ /**
42
+ * Calculate offline UUID from username
43
+ * Offline servers use a different UUID format based on "OfflinePlayer:" + username
44
+ */
45
+ export declare function calculateOfflineUuid(username: string): string;
46
+ /**
47
+ * Get player info for offline mode
48
+ */
49
+ export declare function getOfflinePlayerInfo(username: string): PlayerInfo;
50
+ export declare function getMojangApiClient(): MojangApiClient;
51
+ //# sourceMappingURL=mojang-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mojang-api.d.ts","sourceRoot":"","sources":["../../src/lib/mojang-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;CACxC;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAsC;IAE1E;;;OAGG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA+BpE;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAkD3D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAQjE;AAKD,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Mojang API Client
3
+ * Provides player lookup functionality via Mojang API
4
+ */
5
+ import { createHash } from 'node:crypto';
6
+ /**
7
+ * Mojang API client for player lookup
8
+ */
9
+ export class MojangApiClient {
10
+ static API_BASE = 'https://api.mojang.com';
11
+ static SESSION_BASE = 'https://sessionserver.mojang.com';
12
+ /**
13
+ * Look up a player by username via Mojang API
14
+ * Returns null if player not found
15
+ */
16
+ async lookupByUsername(username) {
17
+ try {
18
+ const response = await fetch(`${MojangApiClient.API_BASE}/users/profiles/minecraft/${encodeURIComponent(username)}`);
19
+ if (response.status === 404) {
20
+ return null;
21
+ }
22
+ if (!response.ok) {
23
+ throw new Error(`Mojang API error: ${response.status} ${response.statusText}`);
24
+ }
25
+ const profile = await response.json();
26
+ const uuid = formatUuid(profile.id);
27
+ return {
28
+ name: profile.name,
29
+ uuid,
30
+ uuidNoDashes: profile.id,
31
+ source: 'mojang',
32
+ };
33
+ }
34
+ catch (error) {
35
+ if (error instanceof Error && error.message.includes('fetch')) {
36
+ throw new Error(`Failed to connect to Mojang API: ${error.message}`);
37
+ }
38
+ throw error;
39
+ }
40
+ }
41
+ /**
42
+ * Get detailed profile including skin URL
43
+ * Requires UUID (with or without dashes)
44
+ */
45
+ async getProfile(uuid) {
46
+ try {
47
+ const uuidNoDashes = uuid.replace(/-/g, '');
48
+ const response = await fetch(`${MojangApiClient.SESSION_BASE}/session/minecraft/profile/${uuidNoDashes}`);
49
+ if (response.status === 404) {
50
+ return null;
51
+ }
52
+ if (!response.ok) {
53
+ throw new Error(`Mojang Session API error: ${response.status} ${response.statusText}`);
54
+ }
55
+ const data = await response.json();
56
+ const formattedUuid = formatUuid(data.id);
57
+ // Extract skin URL from properties
58
+ let skinUrl;
59
+ if (data.properties) {
60
+ const texturesProp = data.properties.find((p) => p.name === 'textures');
61
+ if (texturesProp) {
62
+ try {
63
+ const textures = JSON.parse(Buffer.from(texturesProp.value, 'base64').toString('utf-8'));
64
+ skinUrl = textures.textures?.SKIN?.url;
65
+ }
66
+ catch {
67
+ // Ignore texture parsing errors
68
+ }
69
+ }
70
+ }
71
+ return {
72
+ name: data.name,
73
+ uuid: formattedUuid,
74
+ uuidNoDashes: data.id,
75
+ skinUrl,
76
+ source: 'mojang',
77
+ };
78
+ }
79
+ catch (error) {
80
+ if (error instanceof Error && error.message.includes('fetch')) {
81
+ throw new Error(`Failed to connect to Mojang Session API: ${error.message}`);
82
+ }
83
+ throw error;
84
+ }
85
+ }
86
+ }
87
+ /**
88
+ * Format UUID with dashes
89
+ * Input: 8667ba71b85a4004af54457a9734eed7
90
+ * Output: 8667ba71-b85a-4004-af54-457a9734eed7
91
+ */
92
+ export function formatUuid(uuid) {
93
+ const clean = uuid.replace(/-/g, '');
94
+ if (clean.length !== 32) {
95
+ return uuid; // Return as-is if not a valid UUID
96
+ }
97
+ return `${clean.slice(0, 8)}-${clean.slice(8, 12)}-${clean.slice(12, 16)}-${clean.slice(16, 20)}-${clean.slice(20)}`;
98
+ }
99
+ /**
100
+ * Calculate offline UUID from username
101
+ * Offline servers use a different UUID format based on "OfflinePlayer:" + username
102
+ */
103
+ export function calculateOfflineUuid(username) {
104
+ const hash = createHash('md5').update(`OfflinePlayer:${username}`).digest();
105
+ // Set version to 3 (name-based MD5)
106
+ const byte6 = hash[6];
107
+ const byte8 = hash[8];
108
+ if (byte6 !== undefined && byte8 !== undefined) {
109
+ hash[6] = (byte6 & 0x0f) | 0x30;
110
+ // Set variant to RFC 4122
111
+ hash[8] = (byte8 & 0x3f) | 0x80;
112
+ }
113
+ const hex = hash.toString('hex');
114
+ return formatUuid(hex);
115
+ }
116
+ /**
117
+ * Get player info for offline mode
118
+ */
119
+ export function getOfflinePlayerInfo(username) {
120
+ const uuid = calculateOfflineUuid(username);
121
+ return {
122
+ name: username,
123
+ uuid,
124
+ uuidNoDashes: uuid.replace(/-/g, ''),
125
+ source: 'offline',
126
+ };
127
+ }
128
+ // Singleton instance
129
+ let mojangApiClient = null;
130
+ export function getMojangApiClient() {
131
+ if (!mojangApiClient) {
132
+ mojangApiClient = new MojangApiClient();
133
+ }
134
+ return mojangApiClient;
135
+ }
136
+ //# sourceMappingURL=mojang-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mojang-api.js","sourceRoot":"","sources":["../../src/lib/mojang-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Player Cache System
3
+ * Encrypted local cache for Mojang API responses to minimize rate limiting
4
+ */
5
+ import { type PlayerInfo } from './mojang-api.js';
6
+ /**
7
+ * Player cache with AES-256-GCM encryption
8
+ */
9
+ export declare class PlayerCache {
10
+ private readonly cachePath;
11
+ private cache;
12
+ private encryptionKey;
13
+ constructor(cacheDir?: string);
14
+ /**
15
+ * Look up a player by username
16
+ * First checks cache, then Mojang API
17
+ */
18
+ lookup(username: string, options?: {
19
+ forceRefresh?: boolean;
20
+ offline?: boolean;
21
+ }): Promise<PlayerInfo | null>;
22
+ /**
23
+ * Look up a player with full profile (including skin URL)
24
+ */
25
+ lookupWithProfile(username: string, options?: {
26
+ forceRefresh?: boolean;
27
+ }): Promise<PlayerInfo | null>;
28
+ /**
29
+ * Get player from cache if valid
30
+ */
31
+ private getFromCache;
32
+ /**
33
+ * Save player info to cache
34
+ */
35
+ private saveToCache;
36
+ /**
37
+ * Update skin URL in cache
38
+ */
39
+ private updateSkinInCache;
40
+ /**
41
+ * Load cache from encrypted file
42
+ */
43
+ private loadCache;
44
+ /**
45
+ * Persist cache to encrypted file
46
+ */
47
+ private persistCache;
48
+ /**
49
+ * Get or derive encryption key
50
+ */
51
+ private getEncryptionKey;
52
+ /**
53
+ * Get machine-specific identifier for key derivation
54
+ */
55
+ private getMachineIdentifier;
56
+ /**
57
+ * Encrypt data using AES-256-GCM
58
+ */
59
+ private encrypt;
60
+ /**
61
+ * Decrypt data using AES-256-GCM
62
+ */
63
+ private decrypt;
64
+ /**
65
+ * Clear all cached data
66
+ */
67
+ clear(): Promise<void>;
68
+ /**
69
+ * Get cache statistics
70
+ */
71
+ getStats(): Promise<{
72
+ playerCount: number;
73
+ oldestEntry: number | null;
74
+ newestEntry: number | null;
75
+ cacheSize: number;
76
+ }>;
77
+ }
78
+ export declare function getPlayerCache(cacheDir?: string): PlayerCache;
79
+ //# sourceMappingURL=player-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player-cache.d.ts","sourceRoot":"","sources":["../../src/lib/player-cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAoCzB;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,aAAa,CAAuB;gBAEhC,QAAQ,CAAC,EAAE,MAAM;IAK7B;;;OAGG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAkCvH;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAqC/G;;OAEG;YACW,YAAY;IAsB1B;;OAEG;YACW,WAAW;IAuBzB;;OAEG;YACW,iBAAiB;IAY/B;;OAEG;YACW,SAAS;IAyBvB;;OAEG;YACW,YAAY;IAwB1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;OAEG;YACW,OAAO;IAoBrB;;OAEG;YACW,OAAO;IAkBrB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CAsBH;AAKD,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAK7D"}
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Player Cache System
3
+ * Encrypted local cache for Mojang API responses to minimize rate limiting
4
+ */
5
+ import { createCipheriv, createDecipheriv, randomBytes, createHash, pbkdf2Sync } from 'node:crypto';
6
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync, statSync } from 'node:fs';
7
+ import { join, dirname } from 'node:path';
8
+ import { homedir, hostname, platform, userInfo } from 'node:os';
9
+ import { getMojangApiClient, getOfflinePlayerInfo, } from './mojang-api.js';
10
+ const CACHE_VERSION = 1;
11
+ const CACHE_FILENAME = '.player-cache';
12
+ const ENCRYPTION_ALGORITHM = 'aes-256-gcm';
13
+ // Cache duration constants (in milliseconds)
14
+ const CACHE_DURATION = {
15
+ UUID: Infinity, // UUID never changes
16
+ USERNAME: 30 * 24 * 60 * 60 * 1000, // 30 days (name changes allowed)
17
+ SKIN: 24 * 60 * 60 * 1000, // 1 day (changes frequently)
18
+ };
19
+ /**
20
+ * Player cache with AES-256-GCM encryption
21
+ */
22
+ export class PlayerCache {
23
+ cachePath;
24
+ cache = null;
25
+ encryptionKey = null;
26
+ constructor(cacheDir) {
27
+ const baseDir = cacheDir ?? join(homedir(), '.mcctl');
28
+ this.cachePath = join(baseDir, CACHE_FILENAME);
29
+ }
30
+ /**
31
+ * Look up a player by username
32
+ * First checks cache, then Mojang API
33
+ */
34
+ async lookup(username, options = {}) {
35
+ // Offline mode uses calculated UUID
36
+ if (options.offline) {
37
+ return getOfflinePlayerInfo(username);
38
+ }
39
+ const lowerUsername = username.toLowerCase();
40
+ // Check cache first (unless force refresh)
41
+ if (!options.forceRefresh) {
42
+ const cached = await this.getFromCache(lowerUsername);
43
+ if (cached) {
44
+ return {
45
+ name: cached.name,
46
+ uuid: cached.uuid,
47
+ uuidNoDashes: cached.uuidNoDashes,
48
+ skinUrl: cached.skinUrl,
49
+ source: 'cache',
50
+ };
51
+ }
52
+ }
53
+ // Fetch from Mojang API
54
+ const client = getMojangApiClient();
55
+ const info = await client.lookupByUsername(username);
56
+ if (info) {
57
+ // Save to cache
58
+ await this.saveToCache(info);
59
+ }
60
+ return info;
61
+ }
62
+ /**
63
+ * Look up a player with full profile (including skin URL)
64
+ */
65
+ async lookupWithProfile(username, options = {}) {
66
+ const basic = await this.lookup(username, options);
67
+ if (!basic) {
68
+ return null;
69
+ }
70
+ // Check if we need to fetch skin URL
71
+ const lowerUsername = username.toLowerCase();
72
+ const cached = await this.getFromCache(lowerUsername);
73
+ // Check if skin cache is still valid
74
+ const skinValid = cached?.skinUpdatedAt &&
75
+ (Date.now() - cached.skinUpdatedAt) < CACHE_DURATION.SKIN;
76
+ if (!options.forceRefresh && skinValid && cached?.skinUrl) {
77
+ return {
78
+ ...basic,
79
+ skinUrl: cached.skinUrl,
80
+ };
81
+ }
82
+ // Fetch full profile from Mojang
83
+ const client = getMojangApiClient();
84
+ const profile = await client.getProfile(basic.uuid);
85
+ if (profile?.skinUrl) {
86
+ // Update cache with skin URL
87
+ await this.updateSkinInCache(lowerUsername, profile.skinUrl);
88
+ return {
89
+ ...basic,
90
+ skinUrl: profile.skinUrl,
91
+ };
92
+ }
93
+ return basic;
94
+ }
95
+ /**
96
+ * Get player from cache if valid
97
+ */
98
+ async getFromCache(lowerUsername) {
99
+ await this.loadCache();
100
+ if (!this.cache) {
101
+ return null;
102
+ }
103
+ const cached = this.cache.players[lowerUsername];
104
+ if (!cached) {
105
+ return null;
106
+ }
107
+ // Check if name cache is still valid
108
+ const nameAge = Date.now() - cached.nameUpdatedAt;
109
+ if (nameAge > CACHE_DURATION.USERNAME) {
110
+ // Name cache expired, but UUID is still valid
111
+ // Return null to trigger API call, but UUID will be updated in place
112
+ return null;
113
+ }
114
+ return cached;
115
+ }
116
+ /**
117
+ * Save player info to cache
118
+ */
119
+ async saveToCache(info) {
120
+ await this.loadCache();
121
+ if (!this.cache) {
122
+ this.cache = { version: CACHE_VERSION, players: {} };
123
+ }
124
+ const lowerUsername = info.name.toLowerCase();
125
+ const now = Date.now();
126
+ this.cache.players[lowerUsername] = {
127
+ name: info.name,
128
+ uuid: info.uuid,
129
+ uuidNoDashes: info.uuidNoDashes,
130
+ skinUrl: info.skinUrl,
131
+ source: info.source === 'cache' ? 'mojang' : info.source,
132
+ cachedAt: now,
133
+ nameUpdatedAt: now,
134
+ skinUpdatedAt: info.skinUrl ? now : undefined,
135
+ };
136
+ await this.persistCache();
137
+ }
138
+ /**
139
+ * Update skin URL in cache
140
+ */
141
+ async updateSkinInCache(lowerUsername, skinUrl) {
142
+ await this.loadCache();
143
+ if (!this.cache || !this.cache.players[lowerUsername]) {
144
+ return;
145
+ }
146
+ this.cache.players[lowerUsername].skinUrl = skinUrl;
147
+ this.cache.players[lowerUsername].skinUpdatedAt = Date.now();
148
+ await this.persistCache();
149
+ }
150
+ /**
151
+ * Load cache from encrypted file
152
+ */
153
+ async loadCache() {
154
+ if (this.cache !== null) {
155
+ return; // Already loaded
156
+ }
157
+ if (!existsSync(this.cachePath)) {
158
+ this.cache = { version: CACHE_VERSION, players: {} };
159
+ return;
160
+ }
161
+ try {
162
+ const encrypted = JSON.parse(readFileSync(this.cachePath, 'utf-8'));
163
+ const decrypted = await this.decrypt(encrypted);
164
+ this.cache = JSON.parse(decrypted);
165
+ // Migrate old cache versions if needed
166
+ if (this.cache.version !== CACHE_VERSION) {
167
+ this.cache = { version: CACHE_VERSION, players: {} };
168
+ }
169
+ }
170
+ catch {
171
+ // If decryption fails, start fresh
172
+ this.cache = { version: CACHE_VERSION, players: {} };
173
+ }
174
+ }
175
+ /**
176
+ * Persist cache to encrypted file
177
+ */
178
+ async persistCache() {
179
+ if (!this.cache) {
180
+ return;
181
+ }
182
+ // Ensure directory exists
183
+ const dir = dirname(this.cachePath);
184
+ if (!existsSync(dir)) {
185
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
186
+ }
187
+ const data = JSON.stringify(this.cache);
188
+ const encrypted = await this.encrypt(data);
189
+ writeFileSync(this.cachePath, JSON.stringify(encrypted), { mode: 0o600 });
190
+ // Ensure file permissions are correct (owner read/write only)
191
+ try {
192
+ chmodSync(this.cachePath, 0o600);
193
+ }
194
+ catch {
195
+ // Ignore permission errors on some systems
196
+ }
197
+ }
198
+ /**
199
+ * Get or derive encryption key
200
+ */
201
+ getEncryptionKey(salt) {
202
+ if (this.encryptionKey) {
203
+ return this.encryptionKey;
204
+ }
205
+ // Derive key from machine-specific identifiers
206
+ const machineId = this.getMachineIdentifier();
207
+ this.encryptionKey = pbkdf2Sync(machineId, salt, 100000, 32, 'sha256');
208
+ return this.encryptionKey;
209
+ }
210
+ /**
211
+ * Get machine-specific identifier for key derivation
212
+ */
213
+ getMachineIdentifier() {
214
+ // Combine multiple machine-specific values
215
+ const parts = [
216
+ hostname(),
217
+ platform(),
218
+ userInfo().username,
219
+ homedir(),
220
+ // Add more entropy from environment
221
+ process.env.USER || process.env.USERNAME || '',
222
+ ];
223
+ // Hash for consistent length
224
+ return createHash('sha256').update(parts.join('|')).digest('hex');
225
+ }
226
+ /**
227
+ * Encrypt data using AES-256-GCM
228
+ */
229
+ async encrypt(data) {
230
+ const salt = randomBytes(16);
231
+ const key = this.getEncryptionKey(salt);
232
+ const iv = randomBytes(12);
233
+ const cipher = createCipheriv(ENCRYPTION_ALGORITHM, key, iv);
234
+ const encrypted = Buffer.concat([
235
+ cipher.update(data, 'utf-8'),
236
+ cipher.final(),
237
+ ]);
238
+ const tag = cipher.getAuthTag();
239
+ return {
240
+ iv: iv.toString('base64'),
241
+ tag: tag.toString('base64'),
242
+ data: encrypted.toString('base64'),
243
+ salt: salt.toString('base64'),
244
+ };
245
+ }
246
+ /**
247
+ * Decrypt data using AES-256-GCM
248
+ */
249
+ async decrypt(encrypted) {
250
+ const salt = Buffer.from(encrypted.salt, 'base64');
251
+ const key = this.getEncryptionKey(salt);
252
+ const iv = Buffer.from(encrypted.iv, 'base64');
253
+ const tag = Buffer.from(encrypted.tag, 'base64');
254
+ const data = Buffer.from(encrypted.data, 'base64');
255
+ const decipher = createDecipheriv(ENCRYPTION_ALGORITHM, key, iv);
256
+ decipher.setAuthTag(tag);
257
+ const decrypted = Buffer.concat([
258
+ decipher.update(data),
259
+ decipher.final(),
260
+ ]);
261
+ return decrypted.toString('utf-8');
262
+ }
263
+ /**
264
+ * Clear all cached data
265
+ */
266
+ async clear() {
267
+ this.cache = { version: CACHE_VERSION, players: {} };
268
+ await this.persistCache();
269
+ }
270
+ /**
271
+ * Get cache statistics
272
+ */
273
+ async getStats() {
274
+ await this.loadCache();
275
+ const players = Object.values(this.cache?.players ?? {});
276
+ const timestamps = players.map(p => p.cachedAt);
277
+ let cacheSize = 0;
278
+ try {
279
+ if (existsSync(this.cachePath)) {
280
+ cacheSize = statSync(this.cachePath).size;
281
+ }
282
+ }
283
+ catch {
284
+ // Ignore stat errors
285
+ }
286
+ return {
287
+ playerCount: players.length,
288
+ oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : null,
289
+ newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : null,
290
+ cacheSize,
291
+ };
292
+ }
293
+ }
294
+ // Singleton instance
295
+ let playerCache = null;
296
+ export function getPlayerCache(cacheDir) {
297
+ if (!playerCache) {
298
+ playerCache = new PlayerCache(cacheDir);
299
+ }
300
+ return playerCache;
301
+ }
302
+ //# sourceMappingURL=player-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player-cache.js","sourceRoot":"","sources":["../../src/lib/player-cache.ts"],"names":[],"mappings":"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"}