Skip to content

Commit

Permalink
Add local mod origin database detection
Browse files Browse the repository at this point in the history
  • Loading branch information
krypciak committed Feb 8, 2024
1 parent 5bed211 commit 7974ceb
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 37 deletions.
6 changes: 4 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"nax-ccuilib": "github:conorlawton/nax-ccuilib",
"prettier": "3.2.4",
"typescript": "^5.3.3",
"ultimate-crosscode-typedefs": "github:krypciak/ultimate-crosscode-typedefs"
"ultimate-crosscode-typedefs": "github:krypciak/ultimate-crosscode-typedefs",
"semver": "^7.6.0"
}
}
22 changes: 15 additions & 7 deletions src/gui/list-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ModEntry } from '../types'
import { FileCache } from '../cache'
import { InstallQueue } from '../install-queue'
import './list-entry-highlight'
import { InstalledMods } from '../installed-mod-manager'
import { InstalledMods } from '../local-mods'
import { MOD_MENU_TAB_INDEXES } from './list'

declare global {
Expand All @@ -23,7 +23,7 @@ declare global {
modEntryActionButtons: sc.ButtonGui.Type & { ninepatch: ig.NinePatch }
iconGui: ig.ImageGui

stripModName(this: this, name: string): string
getModName(this: this): string
onButtonPress(this: this): void
setTextGreen(this: this): void
setTextRed(this: this): void
Expand Down Expand Up @@ -133,17 +133,25 @@ sc.ModListEntry = ig.FocusGui.extend({
this.addChildGui(this.starCount)
}
},
stripModName(name) {
return name.replace(/\\c\[\d]/g, '')
getModName() {
let name = this.mod.name.replace(/\\c\[\d]/g, '')
let icon: string
if (this.mod.database == 'LOCAL') {
icon = 'lore-others'
} else {
icon = 'quest'
}
name = `\\i[${icon}]${name}`
return name
},
setTextGreen() {
this.nameText.setText(`\\c[2]${this.stripModName(this.mod.name)}\\c[0]`)
this.nameText.setText(`\\c[2]${this.getModName()}\\c[0]`)
},
setTextRed() {
this.nameText.setText(`\\c[1]${this.stripModName(this.mod.name)}\\c[0]`)
this.nameText.setText(`\\c[1]${this.getModName()}\\c[0]`)
},
setTextWhite() {
this.nameText.setText(this.stripModName(this.mod.name))
this.nameText.setText(this.getModName())
},
updateDrawables(root) {
if (this.modList.hook.currentStateName != 'HIDDEN') {
Expand Down
10 changes: 5 additions & 5 deletions src/gui/list.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ModEntry } from '../types'
import { databases } from '../moddb'
import { ModDB } from '../moddb'
import { Fliters, createFuzzyFilteredModList } from '../filters'
import { InstallQueue } from '../install-queue'
import './list-entry'
import { InstalledMods } from '../installed-mod-manager'
import { InstalledMods } from '../local-mods'

declare global {
namespace sc {
Expand Down Expand Up @@ -77,11 +77,11 @@ sc.ModMenuList = sc.ListTabbedPane.extend({
this.addTab(this.tabz[i].name, i, {})
}

for (const dbName in databases) {
const db = databases[dbName]
for (const dbName in ModDB.databases) {
const db = ModDB.databases[dbName]
if (db.active) {
this.mods[dbName] = []
db.getMods(dbName, mods => this.setMods(mods, dbName))
db.getMods(mods => this.setMods(mods, dbName))
}
}
},
Expand Down
10 changes: 8 additions & 2 deletions src/installed-mod-manager.ts → src/local-mods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Mod } from 'ultimate-crosscode-typedefs/modloader/mod'
import { FileCache } from './cache'
import ModManager from './plugin'
import { ModEntryLocal } from './types'
import { ModDB } from './moddb'

type CCL2Mod = {
baseDirectory: string
Expand All @@ -26,11 +27,16 @@ export class InstalledMods {

static getAll() {
if (this.cache) return this.cache
let all: ModEntryLocal[]
if (ModManager.mod.isCCL3) {
return [...modloader.installedMods].map(e => this.convertCCL3Mod(e[1]))
all = [...modloader.installedMods].map(e => this.convertCCL3Mod(e[1]))
} else {
return (this.cache = [...window.activeMods.map(this.convertCCL2Mod), ...window.inactiveMods.map(this.convertCCL2Mod)])
all = this.cache = [...window.activeMods.map(this.convertCCL2Mod), ...window.inactiveMods.map(this.convertCCL2Mod)]
}
for (const mod of all) {
ModDB.resolveLocalModOrigin(mod)
}
return all
}

static getActive(): ModEntryLocal[] {
Expand Down
60 changes: 42 additions & 18 deletions src/moddb.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,40 @@
const fs: typeof import('fs') = (0, eval)("require('fs')")
const path: typeof import('path') = (0, eval)("require('path')")
// const fs: typeof import('fs') = (0, eval)("require('fs')")
// const path: typeof import('path') = (0, eval)("require('path')")

import jszip from 'jszip'
import { ModEntryServer, ModID, NPDatabase } from './types'
// import jszip from 'jszip'
import semver from 'semver'
import { ModEntryLocal, ModEntryServer, ModID, NPDatabase } from './types'
import { FileCache } from './cache'

export class ModDB {
static databases: Record<string, ModDB> = {
krypek: new ModDB('krypek', 'https://raw.githubusercontent.com/krypciak/CCModDB/ccmodjson'),
}

static async resolveLocalModOrigin(mod: ModEntryLocal) {
const matches: ModEntryServer[] = []
for (const dbName in this.databases) {
const moddb = this.databases[dbName]
let modRecord = moddb.modRecord
if (!modRecord) {
await moddb.getMods(() => {})
modRecord = moddb.modRecord
}
if (!modRecord) throw new Error('wat?')

const dbMod = modRecord[mod.id]
if (dbMod) matches.push(dbMod)
}
if (matches.length == 0) return
if (matches.length > 1) {
// TODO match acual mod version not the highest
matches[0] = matches.reduce((highestVerMod, currMod) => (semver.gt(currMod.version, highestVerMod.version) ? currMod : highestVerMod))
}
mod.database = matches[0].database
}

database!: NPDatabase
modRecord!: Record<ModID, ModEntryServer>

constructor(
public name: string,
Expand All @@ -16,13 +44,13 @@ export class ModDB {
FileCache.addDatabase(name, url)
}

private createModEntriesFromDatabase(databaseName: string): ModEntryServer[] {
const result: ModEntryServer[] = []
private createModEntriesFromDatabase(databaseName: string) {
this.modRecord = {}
for (const [name, data] of Object.entries(this.database)) {
if (typeof data === 'string') continue
const meta = data.metadata
const ccmod = data.metadataCCMod
result.push({
this.modRecord[name] = {
database: databaseName,
isLocal: false,
id: name,
Expand All @@ -32,20 +60,20 @@ export class ModDB {
isLegacy: !ccmod,
hasIcon: ccmod?.icons ? !!ccmod.icons['24'] : false,
stars: data.stars,
})
}
}
return result
}

async getMods(databaseName: string, callback: (mods: ModEntryServer[]) => void): Promise<void> {
async getMods(callback: (mods: ModEntryServer[]) => void): Promise<void> {
const create = (database: NPDatabase) => {
this.database = database
const result = this.createModEntriesFromDatabase(databaseName)
callback(result)
this.createModEntriesFromDatabase(this.name)
callback(Object.values(this.modRecord))
}
await FileCache.getDatabase(databaseName, create)
await FileCache.getDatabase(this.name, create)
}

/*
async downloadMod(id: ModID) {
const pkg = await this.getMod(id)
Expand Down Expand Up @@ -84,7 +112,6 @@ export class ModDB {
try {
await fs.promises.mkdir(path.dirname(filepath), { recursive: true })
} catch {
/* Directory already exists */
}
await fs.promises.writeFile(filepath, data)
})
Expand All @@ -99,8 +126,5 @@ export class ModDB {
if (!newData) throw new Error('Could not find name')
return newData
}
}

export const databases: Record<string, ModDB> = {
krypek: new ModDB('krypek', 'https://raw.githubusercontent.com/krypciak/CCModDB/ccmodjson'),
*/
}
3 changes: 1 addition & 2 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export type NPDatabasePackageInstallation = {
)

interface ModEntryBase {
database: string
id: ModID
name: string
description?: string
Expand All @@ -108,11 +109,9 @@ interface ModEntryBase {
stars?: number
}
export interface ModEntryServer extends ModEntryBase {
database: string
isLocal: false
}
export interface ModEntryLocal extends ModEntryBase {
database: 'LOCAL'
isLocal: true
active: boolean
iconConfig: ModImageConfig
Expand Down

0 comments on commit 7974ceb

Please sign in to comment.