Files
AstralRinth/apps/frontend/src/helpers/infer/multi-file-detectors.ts
Truman Gao 61c8cd75cd feat: manage project versions v2 (#5049)
* update add files copy and go to next step on just one file

* rename and reorder stages

* add metadata stage and update details stage

* implement files inside metadata stage

* use regular prettier instead of prettier eslint

* remove changelog stage config

* save button on details stage

* update edit buttons in versions table

* add collapse environment selector

* implement dependencies list in metadata step

* move dependencies into provider

* add suggested dependencies to metadata stage

* pnpm prepr

* fix unused var

* Revert "add collapse environment selector"

This reverts commit f90fabc7a57ff201f26e1b628eeced8e6ef75865.

* hide resource pack loader only when its the only loader

* fix no dependencies for modpack

* add breadcrumbs with hide breadcrumb option

* wider stages

* add proper horizonal scroll breadcrumbs

* fix titles

* handle save version in version page

* remove box shadow

* add notification provider to storybook

* add drop area for versions to drop file right into page

* fix mobile versions table buttons overflowing

* pnpm prepr

* fix drop file opening modal in wrong stage

* implement invalid file for dropping files

* allow horizontal scroll on breadcrumbs

* update infer.js as best as possible

* add create version button uploading version state

* add extractVersionFromFilename for resource pack and datapack

* allow jars for datapack project

* detect multiple loaders when possible

* iris means compatible with optifine too

* infer environment on loader change as well

* add tooltip

* prevent navigate forward when cannot go to next step

* larger breadcrumb click targets

* hide loaders and mc versions stage until files added

* fix max width in header

* fix add files from metadata step jumping steps

* define width in NewModal instead

* disable remove dependency in metadata stage

* switch metadata and details buttons positions

* fix remove button spacing

* do not allow duplicate suggested dependencies

* fix version detection for fabric minecraft version semvar

* better verion number detection based on filename

* show resource pack loader but uneditable

* remove vanilla shader detection

* refactor: break up large infer.js into ts and modules

* remove duplicated types

* add fill missing from file name step

* pnpm prepr

* fix neoforge loader parse failing and not adding neoforge loader

* add missing pack formats

* handle new pack format

* pnpm prepr

* add another regex where it is version in anywhere in filename

* only show resource pack or data pack options for filetype on datapack project

* add redundant zip folder check

* reject RP and DP if has redundant folder

* fix hide stage in breadcrumb

* add snapshot group key in case no release version. brings out 26.1 snapshots

* pnpm prepr

* open in group if has something selected

* fix resource pack loader uneditable if accidentally selected on different project type

* add new environment tags

* add unknown and not applicable environment tags

* pnpm prepr

* use shared constant on labels

* use ref for timeout

* remove console logs

* remove box shadow only for cm-content

* feat: xhr upload + fix wrangler prettierignore

* fix: upload content type fix

* fix dependencies version width

* fix already added dependencies logic

* add changelog minheight

* set progress percentage on button

* add legacy fabric detection logic

* lint

* small update on create version button label

---------

Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
2026-01-12 19:41:14 +00:00

132 lines
3.5 KiB
TypeScript

import type JSZip from 'jszip'
import type { GameVersion, InferredVersionInfo, Project, RawFile } from './infer'
import { extractVersionFromFilename, versionType } from './version-utils'
/**
* Creates multi-file detection functions that scan multiple files in a zip.
*/
export function createMultiFileDetectors(
project: Project,
gameVersions: GameVersion[],
rawFile: RawFile,
) {
return {
// Legacy texture pack (pre-1.6.1)
legacyTexturePack: async (zip: JSZip): Promise<InferredVersionInfo | null> => {
const packTxt = zip.file('pack.txt')
if (!packTxt) return null
// Check for legacy texture pack files/directories
const legacyIndicators = [
'font.txt',
'particles.png',
'achievement/',
'armor/',
'art/',
'environment/',
'font/',
'gui/',
'item/',
'lang/',
'misc/',
'mob/',
'textures/',
'title/',
]
const hasLegacyContent = legacyIndicators.some((indicator) => {
if (indicator.endsWith('/')) {
return zip.file(new RegExp(`^${indicator}`))?.length > 0
}
return zip.file(indicator) !== null
})
if (!hasLegacyContent) return null
// Legacy texture packs are compatible with a1.2.2 to 1.5.2
// We'll return versions from 1.0 to 1.5.2 (as older alpha/beta versions may not be in gameVersions)
const legacyVersions = gameVersions
.filter((v) => {
const version = v.version
// Match 1.0 through 1.5.2
if (version.match(/^1\.[0-4](\.\d+)?$/) || version.match(/^1\.5(\.[0-2])?$/)) {
return true
}
return false
})
.map((v) => v.version)
const versionNum = extractVersionFromFilename(rawFile.name)
return {
name: versionNum ? `${project.title} ${versionNum}` : undefined,
version_number: versionNum || undefined,
version_type: versionType(versionNum),
loaders: ['minecraft'],
game_versions: legacyVersions,
}
},
// Shader pack (OptiFine/Iris)
shaderPack: async (zip: JSZip): Promise<InferredVersionInfo | null> => {
const shadersDir = zip.file(/^shaders\//)
if (!shadersDir || shadersDir.length === 0) return null
const loaders: string[] = []
// Check for Iris-specific features in shaders.properties
const shaderProps = zip.file('shaders/shaders.properties')
if (shaderProps) {
const propsText = await shaderProps.async('text')
if (
propsText.includes('iris.features.required') ||
propsText.includes('iris.features.optional')
) {
loaders.push('iris', 'optifine')
}
}
// If no specific loader detected, it could be OptiFine or Iris
if (loaders.length === 0) {
loaders.push('optifine', 'iris')
}
const versionNum = extractVersionFromFilename(rawFile.name)
return {
name: versionNum ? `${project.title} ${versionNum}` : undefined,
version_number: versionNum || undefined,
version_type: versionType(versionNum),
loaders,
game_versions: [],
}
},
// NilLoader mod
nilLoaderMod: async (zip: JSZip): Promise<InferredVersionInfo | null> => {
const nilModFiles = zip.file(/\.nilmod\.css$/)
if (!nilModFiles || nilModFiles.length === 0) return null
return {
loaders: ['nilloader'],
game_versions: [],
}
},
// Java Agent
javaAgent: async (zip: JSZip): Promise<InferredVersionInfo | null> => {
const manifest = zip.file('META-INF/MANIFEST.MF')
if (!manifest) return null
const manifestText = await manifest.async('text')
if (!manifestText.includes('Premain-Class:')) return null
return {
loaders: ['java-agent'],
game_versions: [],
}
},
}
}