mirror of
https://github.com/Kir-Antipov/mc-publish.git
synced 2025-01-30 13:29:46 -05:00
ForgeModMetadata
refactoring
This commit is contained in:
parent
9570097d5b
commit
2fc40453de
5 changed files with 137 additions and 67 deletions
34
README.md
34
README.md
|
@ -193,21 +193,9 @@ Can be automatically retrieved from the config file of your mod:
|
|||
|
||||
- `mods.toml` (Forge)
|
||||
|
||||
- Custom `mc-publish` field *(recommended)*:
|
||||
- Custom `mc-publish` field:
|
||||
```toml
|
||||
[custom.mc-publish]
|
||||
modrinth="AANobbMI"
|
||||
```
|
||||
|
||||
- Custom `projects` field:
|
||||
```toml
|
||||
[custom.projects]
|
||||
modrinth="AANobbMI"
|
||||
```
|
||||
|
||||
- `projects` field:
|
||||
```toml
|
||||
[projects]
|
||||
[mc-publish]
|
||||
modrinth="AANobbMI"
|
||||
```
|
||||
|
||||
|
@ -311,21 +299,9 @@ Can be automatically retrieved from the config file of your mod:
|
|||
|
||||
- `mods.toml` (Forge)
|
||||
|
||||
- Custom `mc-publish` field *(recommended)*:
|
||||
- Custom `mc-publish` field:
|
||||
```toml
|
||||
[custom.mc-publish]
|
||||
curseforge=394468
|
||||
```
|
||||
|
||||
- Custom `projects` field:
|
||||
```toml
|
||||
[custom.projects]
|
||||
curseforge=394468
|
||||
```
|
||||
|
||||
- `projects` field:
|
||||
```toml
|
||||
[projects]
|
||||
[mc-publish]
|
||||
curseforge=394468
|
||||
```
|
||||
|
||||
|
@ -617,7 +593,7 @@ Can be automatically retrieved from the config file of your mod:
|
|||
versionRange="0.3.0"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
[dependencies.mod-id.custom.mc-publish]
|
||||
[dependencies.mod-id.mc-publish]
|
||||
ignore=false # `mc-publish` will ignore this dependency, if `ignore` is set to true
|
||||
modrinth="included-dependency-forge" # Modrinth's project slug
|
||||
curseforge="included-dependency-forge" # CurseForge's project slug
|
||||
|
|
44
src/metadata/forge/forge-mod-config.ts
Normal file
44
src/metadata/forge/forge-mod-config.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
// https://forge.gemwire.uk/wiki/Mods.toml
|
||||
type ForgeModConfig = {
|
||||
// Non-Mod-Specific Properties
|
||||
modLoader: string;
|
||||
loaderVersion: string;
|
||||
license: string;
|
||||
showAsResourcePack?: boolean;
|
||||
properties?: Record<string, unknown>;
|
||||
issueTrackerURL?: string;
|
||||
|
||||
// Mod Properties
|
||||
mods: {
|
||||
modId: string;
|
||||
namespace?: string;
|
||||
version?: string;
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
logoFile?: string;
|
||||
logoBlur?: boolean;
|
||||
updateJSONURL?: string;
|
||||
modproperties?: Record<string, unknown>;
|
||||
credits?: string;
|
||||
authors?: string;
|
||||
displayURL?: string;
|
||||
displayTest?: "MATCH_VERSION" | "IGNORE_SERVER_VERSION" | "IGNORE_ALL_VERSION" | "NONE";
|
||||
}[];
|
||||
|
||||
// Dependency Configurations
|
||||
dependencies?: Record<string, ({
|
||||
modId: string;
|
||||
mandatory: boolean;
|
||||
incompatible?: boolean;
|
||||
embedded?: boolean;
|
||||
versionRange?: string;
|
||||
ordering?: "BEFORE" | "AFTER" | "NONE";
|
||||
side?: "CLIENT" | "SERVER" | "BOTH";
|
||||
} & Record<string, any>)[]>;
|
||||
} & Record<string, any>;
|
||||
|
||||
namespace ForgeModConfig {
|
||||
export const FILENAME = "META-INF/mods.toml";
|
||||
}
|
||||
|
||||
export default ForgeModConfig;
|
|
@ -1,18 +1,21 @@
|
|||
import ModMetadata from "../../metadata/mod-metadata";
|
||||
import ModMetadata from "../mod-metadata";
|
||||
import toml from "toml";
|
||||
import ZippedModMetadataReader from "../../metadata/zipped-mod-metadata-reader";
|
||||
import ZippedModMetadataReader from "../zipped-mod-metadata-reader";
|
||||
import ForgeModMetadata from "./forge-mod-metadata";
|
||||
import ForgeModConfig from "./forge-mod-config";
|
||||
|
||||
export default class ForgeModMetadataReader extends ZippedModMetadataReader {
|
||||
class ForgeModMetadataReader extends ZippedModMetadataReader<ForgeModConfig> {
|
||||
constructor() {
|
||||
super("META-INF/mods.toml");
|
||||
super(ForgeModConfig.FILENAME);
|
||||
}
|
||||
|
||||
protected loadConfig(buffer: Buffer): Record<string, unknown> {
|
||||
protected loadConfig(buffer: Buffer): ForgeModConfig {
|
||||
return toml.parse(buffer.toString("utf8"));
|
||||
}
|
||||
|
||||
protected createMetadataFromConfig(config: Record<string, unknown>): ModMetadata {
|
||||
protected createMetadataFromConfig(config: ForgeModConfig): ModMetadata {
|
||||
return new ForgeModMetadata(config);
|
||||
}
|
||||
}
|
||||
|
||||
export default ForgeModMetadataReader;
|
||||
|
|
|
@ -1,29 +1,74 @@
|
|||
import ModConfig from "../../metadata/mod-config";
|
||||
import ModConfigDependency from "../../metadata/mod-config-dependency";
|
||||
import Dependency from "../../metadata/dependency";
|
||||
import DependencyKind from "../../metadata/dependency-kind";
|
||||
import action from "../../../package.json";
|
||||
import Dependency from "../dependency";
|
||||
import DependencyKind from "../dependency-kind";
|
||||
import ForgeModConfig from "./forge-mod-config";
|
||||
import ModMetadata from "../mod-metadata";
|
||||
import PublisherTarget from "../../publishing/publisher-target";
|
||||
|
||||
const ignoredByDefault = ["minecraft", "java", "forge"];
|
||||
function createDependency(body: any): Dependency {
|
||||
return new ModConfigDependency({
|
||||
ignore: ignoredByDefault.includes(body.modId),
|
||||
...body,
|
||||
id: body.modId,
|
||||
version: body.versionRange,
|
||||
kind: body.incompatible && DependencyKind.Breaks || body.embedded && DependencyKind.Includes || body.mandatory && DependencyKind.Depends || DependencyKind.Recommends
|
||||
});
|
||||
type ForgeDependency = ForgeModConfig["dependencies"][string][number];
|
||||
|
||||
function getDependencies(config: ForgeModConfig): Dependency[] {
|
||||
return Object
|
||||
.values(config.dependencies || {})
|
||||
.filter(x => Array.isArray(x))
|
||||
.flatMap(x => x)
|
||||
.map(parseDependency)
|
||||
.filter((x, i, self) => self.findIndex(y => x.id === y.id && x.kind === y.kind) === i);
|
||||
}
|
||||
|
||||
export default class ForgeModMetadata extends ModConfig {
|
||||
public readonly id: string;
|
||||
public readonly name: string;
|
||||
public readonly version: string;
|
||||
public readonly loaders: string[];
|
||||
public readonly dependencies: Dependency[];
|
||||
function parseDependency(body: ForgeDependency): Dependency {
|
||||
const id = body.modId;
|
||||
const kind = body.incompatible && DependencyKind.Breaks || body.embedded && DependencyKind.Includes || body.mandatory && DependencyKind.Depends || DependencyKind.Recommends;
|
||||
const version = body.versionRange;
|
||||
const ignore = body[action.name]?.ignore ?? body.custom?.[action.name]?.ignore ?? body.ignore ?? isDependencyIgnoredByDefault(id);
|
||||
const aliases = new Map<PublisherTarget, string>();
|
||||
for (const target of PublisherTarget.getValues()) {
|
||||
const targetName = PublisherTarget.toString(target).toLowerCase();
|
||||
const alias = body[action.name]?.[targetName] ?? body.custom?.[action.name]?.[targetName];
|
||||
if (alias) {
|
||||
aliases.set(target, String(alias));
|
||||
}
|
||||
}
|
||||
|
||||
constructor(config: Record<string, unknown>) {
|
||||
super(config);
|
||||
const mods = Array.isArray(this.config.mods) && <any[]>this.config.mods || [];
|
||||
return Dependency.create({ id, kind, version, ignore, aliases });
|
||||
}
|
||||
|
||||
const ignoredByDefault = [
|
||||
"minecraft",
|
||||
"java",
|
||||
"forge",
|
||||
];
|
||||
function isDependencyIgnoredByDefault(id: string): boolean {
|
||||
return ignoredByDefault.includes(id);
|
||||
}
|
||||
|
||||
function getProjects(config: ForgeModConfig): Map<PublisherTarget, string> {
|
||||
const projects = new Map();
|
||||
for (const target of PublisherTarget.getValues()) {
|
||||
const targetName = PublisherTarget.toString(target).toLowerCase();
|
||||
const projectId = config[action.name]?.[targetName]
|
||||
?? config.custom?.[action.name]?.[targetName]
|
||||
?? config.projects?.[targetName]
|
||||
?? config.custom?.projects?.[targetName];
|
||||
|
||||
if (projectId) {
|
||||
projects.set(target, String(projectId));
|
||||
}
|
||||
}
|
||||
return projects;
|
||||
}
|
||||
|
||||
class ForgeModMetadata implements ModMetadata {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly version: string;
|
||||
readonly loaders: string[];
|
||||
readonly dependencies: Dependency[];
|
||||
|
||||
private readonly _projects: Map<PublisherTarget, string>;
|
||||
|
||||
constructor(config: ForgeModConfig) {
|
||||
const mods = Array.isArray(config.mods) && config.mods || [];
|
||||
const mod = mods[0];
|
||||
if (!mod) {
|
||||
throw new Error("At least one mod should be specified");
|
||||
|
@ -33,11 +78,14 @@ export default class ForgeModMetadata extends ModConfig {
|
|||
this.name = mod.displayName || this.id;
|
||||
this.version = mod.version || "*";
|
||||
this.loaders = ["forge"];
|
||||
this.dependencies = Object
|
||||
.values(this.config.dependencies || {})
|
||||
.filter(Array.isArray)
|
||||
.flatMap(x => x)
|
||||
.map(createDependency)
|
||||
.filter((x, i, self) => self.findIndex(y => x.id === y.id && x.kind === y.kind) === i);
|
||||
this.dependencies = getDependencies(config);
|
||||
|
||||
this._projects = getProjects(config);
|
||||
}
|
||||
|
||||
getProjectId(project: PublisherTarget): string | undefined {
|
||||
return this._projects.get(project);
|
||||
}
|
||||
}
|
||||
|
||||
export default ForgeModMetadata;
|
||||
|
|
|
@ -13,7 +13,7 @@ license="MIT"
|
|||
Example mod
|
||||
'''
|
||||
|
||||
[projects]
|
||||
[mc-publish]
|
||||
modrinth="AANobbMI"
|
||||
[custom.projects]
|
||||
curseforge=394468
|
||||
|
@ -46,13 +46,12 @@ license="MIT"
|
|||
versionRange="0.2.0"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
[dependencies.example-mod.projects]
|
||||
[dependencies.example-mod.mc-publish]
|
||||
modrinth="AAAA"
|
||||
[dependencies.example-mod.custom.projects]
|
||||
curseforge=42
|
||||
ignore=true
|
||||
[dependencies.example-mod.custom.mc-publish]
|
||||
github="v0.2.0"
|
||||
ignore=true
|
||||
|
||||
|
||||
[[dependencies.example-mod]]
|
||||
|
|
Loading…
Add table
Reference in a new issue