@@ -8,6 +8,12 @@ import { logger } from '../utils/logger.js';
88 * Manages Minecraft versions - downloading, caching, and metadata
99 */
1010export class VersionManager {
11+ /**
12+ * First known unobfuscated Minecraft build.
13+ * 26.1-snapshot-1 released at this timestamp and removed client obfuscation.
14+ */
15+ private static readonly UNOBFUSCATED_CUTOFF_MS = Date . parse ( '2025-12-16T12:42:29+00:00' ) ;
16+
1117 private downloader = getMojangDownloader ( ) ;
1218 private cache = getCacheManager ( ) ;
1319
@@ -148,10 +154,27 @@ export class VersionManager {
148154 * Starting with Minecraft 26.1 snapshots, Mojang stopped obfuscating the
149155 * client JAR. These versions have no `client_mappings` entry in their
150156 * version JSON because there is nothing to reverse-map.
157+ *
158+ * Important: some older obfuscated versions (e.g. early 1.14.x) also lack
159+ * `client_mappings` metadata, so missing metadata alone is not sufficient.
151160 */
152161 async isVersionUnobfuscated ( version : string ) : Promise < boolean > {
153162 const versionJson = await this . downloader . getVersionJson ( version ) ;
154- return ! versionJson . downloads . client_mappings ;
163+ if ( versionJson . downloads . client_mappings ) {
164+ return false ;
165+ }
166+
167+ // Early 1.14.x releases can be missing client_mappings metadata while still obfuscated.
168+ // Treat versions as unobfuscated only after the known 26.1 cutover and only for modern ids.
169+ const releaseTimeMs = Date . parse ( versionJson . releaseTime ) ;
170+ const isAfterUnobfuscatedCutover =
171+ Number . isFinite ( releaseTimeMs ) && releaseTimeMs >= VersionManager . UNOBFUSCATED_CUTOFF_MS ;
172+
173+ const modernVersionId = / ^ ( \d + ) \. ( \d + ) (?: \. \d + ) ? (?: - s n a p s h o t - \d + ) ? $ / . exec ( versionJson . id ) ;
174+ const modernMajor = modernVersionId ? Number . parseInt ( modernVersionId [ 1 ] , 10 ) : Number . NaN ;
175+ const isModernUnobfuscatedSeries = Number . isFinite ( modernMajor ) && modernMajor >= 26 ;
176+
177+ return isAfterUnobfuscatedCutover && isModernUnobfuscatedSeries ;
155178 }
156179
157180 /**
0 commit comments