Big AddonscriptJSON overhaul and many chaos
This commit is contained in:
parent
e9133fc5ba
commit
d68e591dd3
|
@ -24,9 +24,10 @@ public class CurseforgeRepository implements IRepository {
|
|||
|
||||
@Override
|
||||
public AddonscriptJSON.Meta getMeta(String artifact) {
|
||||
AddonscriptJSON.Meta meta = new AddonscriptJSON.Meta();
|
||||
AddonscriptJSON.Meta meta = null;
|
||||
CurseFile file = getFile(artifact);
|
||||
if (file != null) {
|
||||
meta = new AddonscriptJSON.Meta();
|
||||
try {
|
||||
CurseProject project = file.project();
|
||||
meta.name = project.name();
|
||||
|
|
|
@ -87,7 +87,7 @@ public class ManifestJSON extends JSON {
|
|||
AddonscriptJSON.File overrides = new AddonscriptJSON.File();
|
||||
overrides.id = "overrides";
|
||||
overrides.installer = "internal.override";
|
||||
overrides.path = this.overrides;
|
||||
overrides.link = "file://" + this.overrides;
|
||||
version.files.add(overrides);
|
||||
|
||||
for (File f : files) {
|
||||
|
|
|
@ -9,8 +9,6 @@ import java.nio.file.StandardCopyOption;
|
|||
|
||||
public class InternalDirInstaller implements IInstaller {
|
||||
|
||||
public static String ID = "internal.dir";
|
||||
|
||||
@Override
|
||||
public void install(String[] params, File input) {
|
||||
if (params.length >= 1) {
|
||||
|
|
|
@ -19,6 +19,6 @@ public class MavenRepository implements IRepository {
|
|||
|
||||
@Override
|
||||
public AddonscriptJSON.Meta getMeta(String artifact) {
|
||||
return new AddonscriptJSON.Meta();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ley.anvil.addonscript.util;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import ley.anvil.addonscript.v1.AddonscriptJSON;
|
||||
|
||||
import java.io.Reader;
|
||||
|
@ -14,6 +15,7 @@ public abstract class ASBase extends JSON {
|
|||
/**
|
||||
* The version of the AddonScript file
|
||||
*/
|
||||
@Expose
|
||||
public int asversion;
|
||||
|
||||
public Class<? extends ASBase> getImpl() {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package ley.anvil.addonscript.util;
|
||||
|
||||
import ley.anvil.addonscript.installer.IInstaller;
|
||||
import ley.anvil.addonscript.v1.AddonscriptJSON;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Indexes {
|
||||
|
||||
public Indexes() {
|
||||
INSTALLERS = new HashMap<>();
|
||||
REPOSITORIES = new HashMap<>();
|
||||
ADDONS = new HashMap<>();
|
||||
VERSIONS = new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<String, IInstaller> INSTALLERS;
|
||||
public Map<String, IRepository> REPOSITORIES;
|
||||
public Map<String, AddonscriptJSON> ADDONS;
|
||||
public Map<Integer, AddonscriptJSON.Version> VERSIONS;
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@ import java.io.Writer;
|
|||
|
||||
public abstract class JSON {
|
||||
|
||||
public static Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
public static Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().excludeFieldsWithoutExposeAnnotation().create();
|
||||
|
||||
public String toJSON() {
|
||||
return gson.toJson(this);
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package ley.anvil.addonscript.util;
|
||||
|
||||
import ley.anvil.addonscript.v1.AddonscriptJSON;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static AddonscriptJSON getFromURL(String link) {
|
||||
try {
|
||||
return AddonscriptJSON.read(new InputStreamReader(new URL(link).openStream()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return new AddonscriptJSON();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +1,30 @@
|
|||
package ley.anvil.addonscript.v1;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import javafx.util.Pair;
|
||||
import ley.anvil.addonscript.curse.CurseforgeRepository;
|
||||
import ley.anvil.addonscript.maven.MavenRepository;
|
||||
import ley.anvil.addonscript.python.PythonInstaller;
|
||||
import ley.anvil.addonscript.util.ASBase;
|
||||
import ley.anvil.addonscript.installer.IInstaller;
|
||||
import ley.anvil.addonscript.util.IRepository;
|
||||
import ley.anvil.addonscript.installer.InternalDirInstaller;
|
||||
import ley.anvil.addonscript.util.Indexes;
|
||||
import ley.anvil.addonscript.util.Utils;
|
||||
import org.python.jline.internal.Nullable;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AddonscriptJSON extends ASBase {
|
||||
|
||||
public Map<String, IInstaller> INSTALLERS;
|
||||
public Map<String, IRepository> REPOSITORIES;
|
||||
public Indexes indexes;
|
||||
public boolean loaded;
|
||||
|
||||
public static AddonscriptJSON fromJSON(String json) {
|
||||
return fromJSON(json, AddonscriptJSON.class);
|
||||
}
|
||||
|
||||
public static AddonscriptJSON read(Reader reader) {
|
||||
return read(reader, AddonscriptJSON.class);
|
||||
}
|
||||
|
@ -32,51 +36,78 @@ public class AddonscriptJSON extends ASBase {
|
|||
}
|
||||
|
||||
public AddonscriptJSON() {
|
||||
INSTALLERS = new HashMap<>();
|
||||
REPOSITORIES = new HashMap<>();
|
||||
indexes = new Indexes();
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
INSTALLERS.put("internal.dir", new InternalDirInstaller());
|
||||
for (Installer i : installers) {
|
||||
INSTALLERS.put(i.id, i.getInstaller());
|
||||
}
|
||||
public void load() {
|
||||
indexes.INSTALLERS.put("internal.dir", new InternalDirInstaller());
|
||||
for (Repository r : repositories) {
|
||||
REPOSITORIES.put(r.id, r.getRepository());
|
||||
indexes.REPOSITORIES.put(r.id, r.getRepository());
|
||||
}
|
||||
for (IndexEntry e : index) {
|
||||
if (e.type != null && e.type.equals("addon"))
|
||||
indexes.ADDONS.put(e.id, Utils.getFromURL(e.link));
|
||||
else if (e.type != null && e.type.equals("version"))
|
||||
indexes.VERSIONS.put(e.versionid, Utils.getFromURL(e.link).getDefaultVersion());
|
||||
}
|
||||
for (Version v : versions) {
|
||||
if (!indexes.VERSIONS.containsKey(v.versionid))
|
||||
indexes.VERSIONS.put(v.versionid, v);
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
|
||||
public Version getDefaultVersion() {
|
||||
for (Version v : versions) {
|
||||
if (v.versionid == -1)
|
||||
return v;
|
||||
}
|
||||
if (versions.size() > 0)
|
||||
return versions.get(0);
|
||||
return new Version();
|
||||
}
|
||||
|
||||
public Version getVersion(int versionid) {
|
||||
if (indexes.VERSIONS.containsKey(versionid))
|
||||
return indexes.VERSIONS.get(versionid);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Version getVersion(String versionCondition) {
|
||||
return null; //TODO Interpret version range
|
||||
}
|
||||
|
||||
|
||||
|
||||
//JSON Parts
|
||||
|
||||
/**
|
||||
* The ID of the addon
|
||||
*/
|
||||
@Expose
|
||||
public String id;
|
||||
|
||||
/**
|
||||
* The type of the addon
|
||||
* For example mod or modpack
|
||||
*/
|
||||
@Expose
|
||||
public String type;
|
||||
|
||||
/**
|
||||
* Optional
|
||||
* External Addonscript files for this Addon, specific versions of specific editions
|
||||
*/
|
||||
public List<External> external;
|
||||
|
||||
/**
|
||||
* Optional
|
||||
* Links to external Addonscript files, that should be applied/merged to this
|
||||
*/
|
||||
public List<String> apply;
|
||||
@Expose
|
||||
public List<IndexEntry> index;
|
||||
|
||||
/**
|
||||
* A list of versions of this addon
|
||||
*/
|
||||
@Expose
|
||||
public List<Version> versions;
|
||||
|
||||
/**
|
||||
* A list of repositories this file uses
|
||||
*/
|
||||
@Expose
|
||||
public List<Repository> repositories;
|
||||
|
||||
/**
|
||||
|
@ -88,35 +119,53 @@ public class AddonscriptJSON extends ASBase {
|
|||
* Optional
|
||||
* Meta information for this addon
|
||||
*/
|
||||
@Expose
|
||||
public Meta meta;
|
||||
|
||||
public static class Version implements Comparable<Version> {
|
||||
|
||||
public List<Relation> getRelations(String side, boolean optionals, @Nullable String edition) {
|
||||
List<Relation> list = new ArrayList<>();
|
||||
for (Relation r : relations) {
|
||||
if (r.hasOption(side) && (r.hasOption("required") || (optionals && r.hasOption("optional")) || r.hasOption("edition:" + edition)))
|
||||
list.add(r);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of this version
|
||||
* (for example: 1.0, 1.1, 2.0)
|
||||
*/
|
||||
public String versionname;
|
||||
@Expose
|
||||
public String version;
|
||||
/**
|
||||
* The numeric ID of this version
|
||||
* Used to identify, which version is higher/lower than another
|
||||
* Can be -1 if this file uses only one version
|
||||
*/
|
||||
@Expose
|
||||
public int versionid;
|
||||
/**
|
||||
* The Minecraft versions, which are compatile with this version
|
||||
*/
|
||||
@Expose
|
||||
public List<String> mcversion;
|
||||
/**
|
||||
* Optional
|
||||
* Meta Information about this version
|
||||
*/
|
||||
@Expose
|
||||
public VersionMeta meta;
|
||||
/**
|
||||
* A list of files of this version
|
||||
*/
|
||||
@Expose
|
||||
public List<File> files;
|
||||
/**
|
||||
* A lis of addons, that are related to this addon
|
||||
*/
|
||||
@Expose
|
||||
public List<Relation> relations;
|
||||
|
||||
@Override
|
||||
|
@ -129,11 +178,13 @@ public class AddonscriptJSON extends ASBase {
|
|||
/**
|
||||
* The name of the contributor
|
||||
*/
|
||||
@Expose
|
||||
public String name;
|
||||
/**
|
||||
* The roles of the contributor
|
||||
* (for example: author, developer, owner ...)
|
||||
*/
|
||||
@Expose
|
||||
public List<String> roles;
|
||||
}
|
||||
|
||||
|
@ -141,43 +192,45 @@ public class AddonscriptJSON extends ASBase {
|
|||
/**
|
||||
* The name of the addon
|
||||
*/
|
||||
@Expose
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* A link to the icon of this addon
|
||||
*/
|
||||
@Expose
|
||||
public String icon;
|
||||
|
||||
/**
|
||||
* A list of the contributors of this addon
|
||||
*/
|
||||
@Expose
|
||||
public List<Contributor> contributors;
|
||||
|
||||
/**
|
||||
* The website of the addon
|
||||
*/
|
||||
@Expose
|
||||
public String website;
|
||||
|
||||
/**
|
||||
* The description of the addon
|
||||
*/
|
||||
@Expose
|
||||
public List<String> description;
|
||||
|
||||
/**
|
||||
* A link to an external description
|
||||
*/
|
||||
public String extdescr;
|
||||
|
||||
}
|
||||
|
||||
public static class VersionMeta {
|
||||
/**
|
||||
* The changelog of this version
|
||||
*/
|
||||
@Expose
|
||||
public List<String> changelog;
|
||||
/**
|
||||
* The UNIX Timestamp when this version was released
|
||||
*/
|
||||
@Expose
|
||||
public int timestamp;
|
||||
}
|
||||
|
||||
|
@ -186,20 +239,24 @@ public class AddonscriptJSON extends ASBase {
|
|||
* The ID of this repository
|
||||
* Must be unique to this file
|
||||
*/
|
||||
@Expose
|
||||
public String id;
|
||||
/**
|
||||
* The type of this repository
|
||||
* Currently supported: curseforge, forge
|
||||
*/
|
||||
@Expose
|
||||
public String type;
|
||||
/**
|
||||
* The base url of this repository
|
||||
*/
|
||||
@Expose
|
||||
public String url;
|
||||
|
||||
public IRepository getRepository() {
|
||||
switch (type) {
|
||||
case "curseforge": return new CurseforgeRepository();
|
||||
case "maven": return new MavenRepository(url);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
@ -222,9 +279,6 @@ public class AddonscriptJSON extends ASBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static class File {
|
||||
/**
|
||||
* The ID of this file.
|
||||
|
@ -233,28 +287,26 @@ public class AddonscriptJSON extends ASBase {
|
|||
* Addonscript will then try to install the first of them
|
||||
* and only if this fails, it will try the next.
|
||||
*/
|
||||
@Expose
|
||||
public String id;
|
||||
/**
|
||||
* The installer for this file
|
||||
* Format: <installerid>:<param 1>:<param 2>...
|
||||
* Installer ID can be internal.<some internal installer>
|
||||
*/
|
||||
@Expose
|
||||
public String installer = "internal.dir:mods";
|
||||
/**
|
||||
* Optional: Use this, path or artifact
|
||||
* A link to this file.
|
||||
* Optional: Use this or artifact
|
||||
* A link to this file. Can also point to a relative file or directory by using file://<relative path>.
|
||||
*/
|
||||
@Expose
|
||||
public String link;
|
||||
/**
|
||||
* Optional: Use this, link or artifact
|
||||
* A relative path to this file.
|
||||
* It can also be a path to a directory, if the installer supports directories
|
||||
*/
|
||||
public String path;
|
||||
/**
|
||||
* Optional: Use this, link or path
|
||||
* Optional: Use this or link
|
||||
* An artifact from a repository, which is this file
|
||||
*/
|
||||
@Expose
|
||||
public String artifact;
|
||||
/**
|
||||
* Optional: Defaults if empty
|
||||
|
@ -266,46 +318,116 @@ public class AddonscriptJSON extends ASBase {
|
|||
* "client" - This file works on the client side
|
||||
* "server" - This file works on the server side
|
||||
*/
|
||||
@Expose
|
||||
public List<String> options;
|
||||
|
||||
public boolean server() {
|
||||
return options != null && options.contains("server");
|
||||
public boolean hasOption(String option) {
|
||||
if (options != null)
|
||||
return option.contains(option);
|
||||
else {
|
||||
switch (option) {
|
||||
case "client":
|
||||
case "server":
|
||||
case "required": return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean client() {
|
||||
return options != null && options.contains("client");
|
||||
public String getLink(Indexes indexes) {
|
||||
if (link != null && !link.equals("")) {
|
||||
return link;
|
||||
}
|
||||
else if (artifact != null && !artifact.equals("")) {
|
||||
for (IRepository repo : indexes.REPOSITORIES.values()) {
|
||||
String url = repo.getFileURL(artifact);
|
||||
if (!url.equals(""))
|
||||
return url;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public Meta getMeta(Indexes indexes) {
|
||||
if (artifact != null && !artifact.equals("")) {
|
||||
for (IRepository repo : indexes.REPOSITORIES.values()) {
|
||||
Meta meta = repo.getMeta(artifact);
|
||||
if (meta != null) {
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Relation {
|
||||
/**
|
||||
* Optional: Use either this or file
|
||||
* An external Addonscript for this relation
|
||||
*/
|
||||
public Script script;
|
||||
|
||||
public Meta getMeta(Indexes indexes) {
|
||||
if(indexes.ADDONS.values().contains(id))
|
||||
return indexes.ADDONS.get(id).meta;
|
||||
else if(meta != null)
|
||||
return meta;
|
||||
else
|
||||
return file.getMeta(indexes);
|
||||
}
|
||||
|
||||
public List<Pair<String, String>> getLinks(Indexes indexes, String side, boolean optionals, @Nullable String installer, @Nullable String edition) {
|
||||
List<Pair<String, String>> list = new ArrayList<>();
|
||||
|
||||
if (indexes.ADDONS.containsKey(id)) {
|
||||
AddonscriptJSON addon = indexes.ADDONS.get(id);
|
||||
if (!addon.loaded)
|
||||
addon.load();
|
||||
Version version = addon.getVersion(versions);
|
||||
if (version != null) {
|
||||
for (File f : version.files) {
|
||||
if (f != null && f.hasOption(side) && (installer == null || installer.equals(f.installer)) && ((f.hasOption("optional") && optionals) || f.hasOption("edition:" + edition) || f.hasOption("required")))
|
||||
list.add(new Pair<>(f.getLink(indexes), f.installer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file != null && file.hasOption(side) && (installer == null || installer.equals(file.installer)) && ((file.hasOption("optional") && optionals) || file.hasOption("edition:" + edition) || file.hasOption("required")))
|
||||
list.add(new Pair<>(file.getLink(indexes), file.installer));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The ID of the relation
|
||||
* This should be unique in this Addonscript file
|
||||
*/
|
||||
@Expose
|
||||
public String id;
|
||||
/**
|
||||
* Optional: Wildcard if empty
|
||||
* A version range string, which specifies, which versions of the addon can be used
|
||||
*/
|
||||
@Expose
|
||||
public String versions;
|
||||
/**
|
||||
* Optional: Use either this or script
|
||||
* The file of this relation
|
||||
* Can be a direct link or an artifact from a repository
|
||||
*/
|
||||
@Expose
|
||||
public File file;
|
||||
/**
|
||||
* The addon type of this relation
|
||||
* For example: mod, modloader, config, script...
|
||||
*/
|
||||
@Expose
|
||||
public String type;
|
||||
/**
|
||||
* Optional
|
||||
* Meta information for this relation
|
||||
* This is not always useful, because some repositories, like curseforge, are
|
||||
* This is not always useful, because some repositories, like curseforge or external Addonscripts are
|
||||
* already exposing this information
|
||||
*/
|
||||
@Expose
|
||||
public Meta meta;
|
||||
/**
|
||||
* Optional: Defaults if empty
|
||||
|
@ -320,45 +442,36 @@ public class AddonscriptJSON extends ASBase {
|
|||
* "recommended" - This relation is recomended but not required for this addon
|
||||
* "incompatible" - This relation is incompatible with this addon
|
||||
*/
|
||||
@Expose
|
||||
public List<String> options;
|
||||
|
||||
public boolean server() {
|
||||
return options != null && options.contains("server");
|
||||
public boolean hasOption(String option) {
|
||||
if (options != null)
|
||||
return option.contains(option);
|
||||
else {
|
||||
switch (option) {
|
||||
case "client":
|
||||
case "server":
|
||||
case "required": return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean client() {
|
||||
return options != null && options.contains("client");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class External {
|
||||
/**
|
||||
* Optional: Wildcard if empty
|
||||
* The versionid of the version, for which this external script should be used
|
||||
*/
|
||||
public static class IndexEntry {
|
||||
@Expose
|
||||
public String type;
|
||||
@Expose
|
||||
public String link;
|
||||
@Expose
|
||||
public int versionid;
|
||||
/**
|
||||
* Optional: Wildcard if empty
|
||||
* The edition id of the edition, for which this external script should be used
|
||||
*/
|
||||
@Expose
|
||||
public String edition;
|
||||
/**
|
||||
* The link to the external script
|
||||
*/
|
||||
public String link;
|
||||
}
|
||||
|
||||
public static class Script {
|
||||
/**
|
||||
* The link to the script
|
||||
*/
|
||||
public String link;
|
||||
/**
|
||||
* Optional: Wildcard if empty
|
||||
* A version range string, which specifies, which versions of the addon can be used
|
||||
*/
|
||||
public String version;
|
||||
@Expose
|
||||
public String id;
|
||||
}
|
||||
|
||||
public static class Edition {
|
||||
|
@ -370,7 +483,7 @@ public class AddonscriptJSON extends ASBase {
|
|||
* Optional: Wildcard if empty
|
||||
* A version range string, which specifies, which versions have this edition
|
||||
*/
|
||||
public String version;
|
||||
public String versions;
|
||||
/**
|
||||
* Optional
|
||||
* Meta information about this edition
|
||||
|
|
Loading…
Reference in New Issue