mirror of
https://git.bits.team/Bits/mod-manager.git
synced 2024-11-14 10:28:21 -05:00
Added functionality to mark mods as essential
This commit is contained in:
parent
ab83374735
commit
e913bafb1e
13
package-lock.json
generated
13
package-lock.json
generated
@ -15,7 +15,8 @@
|
||||
"commander": "^9.4.0",
|
||||
"ora": "^6.1.2",
|
||||
"pino": "^8.3.1",
|
||||
"string-format": "^2.0.0"
|
||||
"string-format": "^2.0.0",
|
||||
"string-similarity-js": "^2.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.6.3",
|
||||
@ -546,6 +547,11 @@
|
||||
"resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz",
|
||||
"integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA=="
|
||||
},
|
||||
"node_modules/string-similarity-js": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/string-similarity-js/-/string-similarity-js-2.1.4.tgz",
|
||||
"integrity": "sha512-uApODZNjCHGYROzDSAdCmAHf60L/pMDHnP/yk6TAbvGg7JSPZlSto/ceCI7hZEqzc53/juU2aOJFkM2yUVTMTA=="
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
|
||||
@ -946,6 +952,11 @@
|
||||
"resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz",
|
||||
"integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA=="
|
||||
},
|
||||
"string-similarity-js": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/string-similarity-js/-/string-similarity-js-2.1.4.tgz",
|
||||
"integrity": "sha512-uApODZNjCHGYROzDSAdCmAHf60L/pMDHnP/yk6TAbvGg7JSPZlSto/ceCI7hZEqzc53/juU2aOJFkM2yUVTMTA=="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
|
||||
|
@ -17,7 +17,8 @@
|
||||
"commander": "^9.4.0",
|
||||
"ora": "^6.1.2",
|
||||
"pino": "^8.3.1",
|
||||
"string-format": "^2.0.0"
|
||||
"string-format": "^2.0.0",
|
||||
"string-similarity-js": "^2.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.6.3",
|
||||
|
20
src/commands/essential_command.ts
Normal file
20
src/commands/essential_command.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import Subcommand from "./subcommand.js";
|
||||
import {Command} from "commander";
|
||||
import ModManager from "../mod-manager.js";
|
||||
import Mods from "../mods/mods.js";
|
||||
|
||||
export default class EssentialCommand implements Subcommand {
|
||||
registerCommand(program: Command): void {
|
||||
program.command("essential")
|
||||
.description("Marks mods as essential")
|
||||
.argument("<mods...>", "The mods to mark as essential (as names or ids)")
|
||||
.action((mods) => {
|
||||
ModManager.execute(() => {
|
||||
for (let mod of mods) {
|
||||
Mods.markEssential(mod)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
@ -8,10 +8,11 @@ export default class InstallCommand implements Subcommand {
|
||||
program.command("install")
|
||||
.description("Installs the provided mods")
|
||||
.argument("<mods...>", "The mods to install")
|
||||
.action((mods) => {
|
||||
.option("-e, --essential", "Marks these mods as essential", false)
|
||||
.action(function() {
|
||||
ModManager.execute(async () => {
|
||||
for (const mod of mods) {
|
||||
await Mods.install(mod);
|
||||
for (const mod of this.args) {
|
||||
await Mods.install(mod, this.opts().essential);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ export default class UninstallCommand implements Subcommand {
|
||||
registerCommand(program: Command): void {
|
||||
program.command("uninstall")
|
||||
.description("Uninstalls the provided mods")
|
||||
.argument("<mods...>")
|
||||
.argument("<mods...>", "The mods to uninstall (as names or ids)")
|
||||
.action((mods) => {
|
||||
ModManager.execute(() => {
|
||||
for (let mod of mods) {
|
||||
|
@ -9,6 +9,7 @@ import path from "path";
|
||||
import {Logger, pino} from "pino"
|
||||
import {ListCommand} from "./commands/list_command.js";
|
||||
import UninstallCommand from "./commands/uninstall_command.js";
|
||||
import EssentialCommand from "./commands/essential_command.js";
|
||||
|
||||
|
||||
export default class ModManager {
|
||||
@ -21,7 +22,8 @@ export default class ModManager {
|
||||
new InitCommand(),
|
||||
new InstallCommand(),
|
||||
new ListCommand(),
|
||||
new UninstallCommand()
|
||||
new UninstallCommand(),
|
||||
new EssentialCommand()
|
||||
];
|
||||
|
||||
static init() {
|
||||
|
2
src/mods/mod.d.ts
vendored
2
src/mods/mod.d.ts
vendored
@ -1,10 +1,12 @@
|
||||
declare global {
|
||||
// DONT FORGET TO UPDATE CONSTRUCTORS WHEN MOD SIGNATURE CHANGES
|
||||
type Mod = {
|
||||
id: string
|
||||
name: string
|
||||
fileName: string,
|
||||
version: string
|
||||
source: string,
|
||||
essential: boolean
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ export default class Mods {
|
||||
new ModrinthSource()
|
||||
];
|
||||
|
||||
public static async install(mod: string): Promise<void> {
|
||||
public static async install(mod: string, essential: boolean): Promise<void> {
|
||||
let success: boolean = false;
|
||||
|
||||
// Go through each mod source
|
||||
@ -47,7 +47,7 @@ export default class Mods {
|
||||
if (!this.isModInstalled(id)) {
|
||||
spinner.updateText(`Installing ${projectName}...`)
|
||||
try {
|
||||
const modObj: Mod = await source.install(id);
|
||||
const modObj: Mod = await source.install(id, essential);
|
||||
this.trackMod(modObj);
|
||||
|
||||
spinner.succeed(`Successfully installed ${projectName}`);
|
||||
@ -94,30 +94,17 @@ export default class Mods {
|
||||
}
|
||||
|
||||
static uninstall(mod: string) {
|
||||
let mods: Array<Mod> = this.getTrackedMods();
|
||||
|
||||
// Replace underscores with spaces
|
||||
mod = mod.replaceAll("_", " ");
|
||||
|
||||
// Find mod to uninstall
|
||||
const spinner = new PrintUtils.Spinner(`Uninstalling ${mod}...`)
|
||||
let modToUninstall: Mod | undefined = undefined;
|
||||
for (let modEle of mods) {
|
||||
const id = modEle.id.toLowerCase();
|
||||
const name = modEle.name.toLowerCase();
|
||||
|
||||
const query = mod.toLowerCase();
|
||||
if (id == query || name == query) {
|
||||
modToUninstall = modEle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const modToUninstall = this.findMod(mod);
|
||||
// IF a matching mod is found, remove it
|
||||
if (modToUninstall != undefined) {
|
||||
let mods: Array<Mod> = this.getTrackedMods();
|
||||
|
||||
// Remove mod from list and uninstall it
|
||||
unlinkSync(path.join(this.MODS_FOLDER_PATH, modToUninstall.fileName));
|
||||
mods = mods.filter(item => item !== modToUninstall);
|
||||
mods = mods.filter(item => !Mods.areModsEqual(item, modToUninstall));
|
||||
this.writeFile(mods);
|
||||
spinner.succeed(`${modToUninstall.name} successfully uninstalled!`)
|
||||
} else {
|
||||
@ -127,5 +114,46 @@ export default class Mods {
|
||||
|
||||
|
||||
|
||||
}
|
||||
static areModsEqual(mod1: Mod, mod2: Mod): boolean {
|
||||
return mod1.id === mod2.id;
|
||||
}
|
||||
|
||||
static markEssential(mod: string) {
|
||||
const modToMark = this.findMod(mod);
|
||||
|
||||
if (modToMark != undefined) {
|
||||
let mods = this.getTrackedMods();
|
||||
// Remove mod from list
|
||||
mods = mods.filter(item => !Mods.areModsEqual(item, modToMark));
|
||||
|
||||
// Mark is as essential, and read it
|
||||
modToMark.essential = true;
|
||||
mods.push(modToMark)
|
||||
|
||||
this.writeFile(mods);
|
||||
|
||||
PrintUtils.success(`Marked ${modToMark.name} as essential`)
|
||||
} else {
|
||||
PrintUtils.error(`${mod} not found.`)
|
||||
}
|
||||
}
|
||||
|
||||
private static findMod(mod: string): Mod | undefined {
|
||||
// Replace underscores with spaces
|
||||
mod = mod.replaceAll("_", " ");
|
||||
|
||||
let mods: Array<Mod> = this.getTrackedMods();
|
||||
for (let modEle of mods) {
|
||||
const id = modEle.id.toLowerCase();
|
||||
const name = modEle.name.toLowerCase();
|
||||
|
||||
const query = mod.toLowerCase();
|
||||
if (id == query || Util.areStringsSimilar(mod, name)) {
|
||||
return modEle;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
export default interface ModSource {
|
||||
search(query: string): Promise<string>;
|
||||
|
||||
install(id: string): Promise<Mod>;
|
||||
install(id: string, essential: boolean): Promise<Mod>;
|
||||
|
||||
getSourceName(): string;
|
||||
|
||||
|
@ -124,10 +124,11 @@ export default class ModrinthSource implements ModSource {
|
||||
* }
|
||||
* ]
|
||||
* @param id the id of the mod
|
||||
* @param essential whether this mod is essential or not
|
||||
* @throws DownloadError if an error occurs when downloading
|
||||
* @throws ModNotFoundError if there are no versions available for the current Minecraft Version
|
||||
*/
|
||||
async install(id: string): Promise<Mod> {
|
||||
async install(id: string, essential: boolean): Promise<Mod> {
|
||||
const mcVersion = await MinecraftUtils.getCurrentMinecraftVersion();
|
||||
|
||||
const params = {
|
||||
@ -161,7 +162,8 @@ export default class ModrinthSource implements ModSource {
|
||||
id: id,
|
||||
fileName: fileName,
|
||||
version: modVersion,
|
||||
source: this.getSourceName()
|
||||
source: this.getSourceName(),
|
||||
essential: essential
|
||||
};
|
||||
|
||||
} catch (e) {
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { stringSimilarity } from "string-similarity-js";
|
||||
|
||||
export default class Util {
|
||||
private static readonly SIMILARITY_THRESHOLD: number = 0.8;
|
||||
|
||||
static isArrayEmpty(array: Array<any> | undefined): boolean {
|
||||
return array === undefined || array.length == 0;
|
||||
}
|
||||
@ -9,4 +13,10 @@ export default class Util {
|
||||
// uppercase the first character
|
||||
.replace(/^./, function(str){ return str.toUpperCase(); })
|
||||
}
|
||||
|
||||
static areStringsSimilar(master: string, compare: string): boolean {
|
||||
master = master.toLowerCase();
|
||||
compare = compare.toLowerCase();
|
||||
return stringSimilarity(master, compare) >= this.SIMILARITY_THRESHOLD;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user