Skip to content
3 changes: 2 additions & 1 deletion quasar.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export default defineConfig((ctx) => {
boot: [
'i18n',
// 'axios',
'floating-vue'
'floating-vue',
'ecosystem'
],

// https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#css
Expand Down
12 changes: 12 additions & 0 deletions src/boot/ecosystem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineBoot } from '#q-app/wrappers';
import {updateEcosystemReactives} from "src/r2mm/ecosystem/EcosystemSchema";
import FsProvider from "src/providers/generic/file/FsProvider";
import {NodeFsImplementation} from "src/providers/node/fs/NodeFsImplementation";

// @ts-ignore
export default defineBoot(async ({ app }) => {
FsProvider.provide(() => NodeFsImplementation);
await updateEcosystemReactives();
// @ts-ignore
FsProvider.provide(() => undefined);
});
4 changes: 2 additions & 2 deletions src/model/game/GameManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Game from '../../model/game/Game';
import StorePlatformMetadata from '../../model/game/StorePlatformMetadata';
import PathResolver from '../../r2mm/manager/PathResolver';
import FileUtils from '../../utils/FileUtils';
import { EcosystemSchema, Platform } from '../schema/ThunderstoreSchema';
import {EcosystemSupportedGames, Platform} from '../schema/ThunderstoreSchema';
import path from '../../providers/node/path/path';

export default class GameManager {
Expand All @@ -23,7 +23,7 @@ export default class GameManager {
}

static get gameList(): Game[] {
return EcosystemSchema.supportedGames.map(([identifier, game]) => new Game(
return EcosystemSupportedGames.value.map(([identifier, game]) => new Game(
game.meta.displayName,
game.internalFolderName,
game.settingsIdentifier,
Expand Down
55 changes: 4 additions & 51 deletions src/model/schema/ThunderstoreSchema.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import Ajv from "ajv";
import addFormats from "ajv-formats";

import ecosystem from "../../assets/data/ecosystem.json";
import { R2Modman, ThunderstoreEcosystem } from "../../assets/data/ecosystemTypes";
import jsonSchema from "../../assets/data/ecosystemJsonSchema.json";
import R2Error from "../errors/R2Error";
import {ModloaderPackage, R2Modman} from "../../assets/data/ecosystemTypes";
import {ref} from "@vue/reactivity";

// Re-export generated types/Enums to avoid having the whole codebase
// tightly coupled with the generated ecosystemTypes.
Expand All @@ -16,47 +11,5 @@ export {
Platform,
} from "../../assets/data/ecosystemTypes";

export class EcosystemSchema {
private static _isValidated: boolean = false;

/**
* Get a validated instance of the ecosystem schema.
*/
private static get ecosystem(): ThunderstoreEcosystem {
if (this._isValidated) {
return ecosystem as ThunderstoreEcosystem;
}

// Validate the schema via its schema schema.
const ajv = new Ajv();
addFormats(ajv);

const validate = ajv.compile(jsonSchema);
const isOk = validate(ecosystem);

if (!isOk) {
throw new R2Error("Schema validation error", ajv.errorsText(validate.errors));
}

this._isValidated = true;
return ecosystem as ThunderstoreEcosystem;
}

/**
* Get a list of [identifier, r2modman] entries i.e. games supported by the mod manager.
*/
static get supportedGames() {
const result: [string, R2Modman][] = []
for (const [identifier, game] of Object.entries(this.ecosystem.games)) {
if (game.r2modman == null) continue;
for (const entry of game.r2modman) {
result.push([identifier, entry]);
}
}
return result;
}

static get modloaderPackages() {
return this.ecosystem.modloaderPackages;
}
}
export const EcosystemSupportedGames = ref<[string, R2Modman][]>([]);
export const EcosystemModloaderPackages = ref<ModloaderPackage[]>([]);
9 changes: 6 additions & 3 deletions src/pages/GameSelectionScreen.vue
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ import { getStore } from '../providers/generic/store/StoreProvider';
import { State } from '../store';
import { useRouter } from 'vue-router';
import ProtocolProvider from '../providers/generic/protocol/ProtocolProvider';
import {updateEcosystemReactives, updateLatestEcosystemSchema} from "src/r2mm/ecosystem/EcosystemSchema";

const store = getStore<State>();
const router = useRouter();
Expand All @@ -203,7 +204,6 @@ const settings = ref<ManagerSettings | undefined>(undefined);
const isSettingDefaultPlatform = ref<boolean>(false);
const viewMode = ref<GameSelectionViewMode>(GameSelectionViewMode.LIST);
const activeTab = ref<GameInstanceType>(GameInstanceType.GAME);
const gameImages = reactive({});

const filteredGameList = computed(() => {
const displayNameInAdditionalSearch = (game: Game, filterText: string): boolean => {
Expand Down Expand Up @@ -369,6 +369,9 @@ onMounted(async () => {

await store.dispatch('resetLocalState');

// TODO - Enable once updating is viable
// updateLatestEcosystemSchema();

settings.value = await ManagerSettings.getSingleton(GameManager.defaultGame);
const globalSettings = settings.value.getContext().global;
favourites.value = globalSettings.favouriteGames || [];
Expand All @@ -384,12 +387,12 @@ onMounted(async () => {
}

// Skip game selection view if valid default game & platform are set.
const {defaultGame, defaultPlatform} = ManagerUtils.getDefaults(settings.value);
const {defaultGame, defaultPlatform} = ManagerUtils.getDefaults(settings.value!);

if (defaultGame && defaultPlatform) {
selectedGame.value = defaultGame;
selectedPlatform.value = defaultPlatform;
proceed();
return proceed();
}
})

Expand Down
Loading