@@ -85,3 +85,66 @@ export function generateProgressPercentage(currentProgress: number, targetProgre
8585export function statusIsDownloadOrExtract ( status : DownloadStatusEnum ) : boolean {
8686 return status === DownloadStatusEnum . DOWNLOADING || status === DownloadStatusEnum . EXTRACTING || status === DownloadStatusEnum . EXTRACTED ;
8787}
88+
89+ /**
90+ * Get the path to the online state directory in the cache.
91+ * This directory contains empty files named after dependency strings
92+ * to track which mods were downloaded from online sources.
93+ */
94+ export function getOnlineStateDir ( ) : string {
95+ return path . join ( PathResolver . MOD_ROOT , 'cache' , '_state' , 'online' ) ;
96+ }
97+
98+ /**
99+ * Get the path to the online state file for a given dependency string.
100+ * @param dependencyString The dependency string (e.g., "AuthorName-ModName-1.0.0")
101+ */
102+ export function getOnlineStatePath ( dependencyString : string ) : string {
103+ return path . join ( getOnlineStateDir ( ) , dependencyString ) ;
104+ }
105+
106+ /**
107+ * Check if a mod was previously downloaded from online (state file exists).
108+ * @param combo The combo to check.
109+ * @returns True if the mod was downloaded from online, false otherwise.
110+ */
111+ export async function wasDownloadedFromOnline ( combo : ThunderstoreCombo ) : Promise < boolean > {
112+ const statePath = getOnlineStatePath ( combo . getDependencyString ( ) ) ;
113+ return FsProvider . instance . exists ( statePath ) ;
114+ }
115+
116+ /**
117+ * Mark a mod as downloaded from online by creating a state file.
118+ * Errors are silently ignored to avoid failing downloads due to state tracking issues.
119+ * @param combo The combo to mark.
120+ */
121+ export async function markAsDownloadedFromOnline ( combo : ThunderstoreCombo ) : Promise < void > {
122+ try {
123+ const fs = FsProvider . instance ;
124+ const stateDir = getOnlineStateDir ( ) ;
125+ if ( ! await fs . exists ( stateDir ) ) {
126+ await fs . mkdirs ( stateDir ) ;
127+ }
128+ const statePath = getOnlineStatePath ( combo . getDependencyString ( ) ) ;
129+ await fs . writeFile ( statePath , '' ) ;
130+ } catch ( e ) {
131+ console . warn ( `Failed to mark mod as downloaded from online: ${ combo . getDependencyString ( ) } ` , e ) ;
132+ }
133+ }
134+
135+ /**
136+ * Remove the online state file for a given mod version.
137+ * @param modName The full mod name (e.g., "AuthorName-ModName")
138+ * @param version The version string (e.g., "1.0.0")
139+ */
140+ export async function removeOnlineStateFile ( modName : string , version : string ) : Promise < void > {
141+ const fs = FsProvider . instance ;
142+ const stateFile = path . join ( getOnlineStateDir ( ) , `${ modName } -${ version } ` ) ;
143+ try {
144+ if ( await fs . exists ( stateFile ) ) {
145+ await fs . unlink ( stateFile ) ;
146+ }
147+ } catch ( e ) {
148+ // Ignore errors when removing state files
149+ }
150+ }
0 commit comments