org.legendofdragoon.scripting.meta.MetaManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of script-recompiler Show documentation
Show all versions of script-recompiler Show documentation
Tools for working with Legend of Dragoon scripts
package org.legendofdragoon.scripting.meta;
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MetaManager {
private final URI baseUri;
private final Path cacheDir;
private String[] versions;
public MetaManager(final URI baseUri, final Path cacheDir) {
this.baseUri = baseUri;
this.cacheDir = cacheDir;
}
public String[] getVersions() throws IOException, CsvException {
if(this.versions == null) {
this.versions = this.requestCsv(this.baseUri.resolve("versions.php").toURL()).getFirst();
}
return this.versions;
}
public Meta loadMeta(final String version) throws IOException, CsvException, NoSuchVersionException {
// Snapshot always loads from the server
if("snapshot".equals(version)) {
return this.loadMeta(this.baseUri.resolve(version + '/'), null);
}
// Load cache
final Path versionDir = this.cacheDir.resolve(version);
if(Files.exists(versionDir)) {
return this.loadMeta(versionDir);
}
// Pull from server
final List versions = Arrays.asList(this.getVersions());
if(!versions.contains(version)) {
throw new NoSuchVersionException("Invalid version: " + version);
}
return this.loadMeta(this.baseUri.resolve(version + '/'), this.cacheDir.resolve(version));
}
private Meta loadMeta(final Path basePath) throws IOException, CsvException {
final List descriptionsCsv = this.loadCsvFile(basePath.resolve("descriptions.csv"));
final List paramsCsv = this.loadCsvFile(basePath.resolve("params.csv"));
final List enumsCsv = this.loadCsvFile(basePath.resolve("enums.csv"));
final List methods = new ArrayList<>();
final List enumClasses = new ArrayList<>();
this.loadMeta(descriptionsCsv, paramsCsv, enumsCsv, methods, enumClasses);
final Meta.ScriptMethod[] methodsArr = methods.toArray(Meta.ScriptMethod[]::new);
final Map enums = new HashMap<>();
for(final String className : enumClasses) {
final String[] values = this.loadCsvFile(basePath.resolve(className + ".csv")).stream().map(v -> v[0]).toArray(String[]::new);
enums.put(className, values);
}
return new Meta(methodsArr, enums);
}
private Meta loadMeta(final URI uri, final Path cache) throws IOException, CsvException {
final List descriptionsCsv = this.requestCsv(uri.resolve("descriptions.csv").toURL(), this.child(cache, "descriptions.csv"));
final List paramsCsv = this.requestCsv(uri.resolve("params.csv").toURL(), this.child(cache, "params.csv"));
final List enumsCsv = this.requestCsv(uri.resolve("enums.csv").toURL(), this.child(cache, "enums.csv"));
final List methods = new ArrayList<>();
final List enumClasses = new ArrayList<>();
this.loadMeta(descriptionsCsv, paramsCsv, enumsCsv, methods, enumClasses);
final Meta.ScriptMethod[] methodsArr = methods.toArray(Meta.ScriptMethod[]::new);
final Map enums = new HashMap<>();
for(final String className : enumClasses) {
final String[] values = this.requestCsv(uri.resolve(className + ".csv").toURL(), this.child(cache, className + ".csv")).stream().map(v -> v[0]).toArray(String[]::new);
enums.put(className, values);
}
return new Meta(methodsArr, enums);
}
private void loadMeta(final List descriptionsCsv, final List paramsCsv, final List enumsCsv, final List methods, final List enumClasses) {
for(final String[] description : descriptionsCsv) {
final List params = new ArrayList<>();
for(final String[] param : paramsCsv) {
if(param[0].equals(description[0])) {
params.add(new Meta.ScriptParam(param[1], param[2], param[3], param[4], param[5]));
}
}
methods.add(new Meta.ScriptMethod(description[0], description[1], params.toArray(Meta.ScriptParam[]::new)));
}
for(final String[] val : enumsCsv) {
final String className = val[0];
enumClasses.add(className);
}
}
private Path child(final Path path, final String child) {
if(path == null) {
return null;
}
return path.resolve(child);
}
private List requestCsv(final URL url) throws IOException, CsvException {
return this.requestCsv(url, null);
}
private List requestCsv(final URL url, final Path cache) throws IOException, CsvException {
final HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
if(con.getResponseCode() != 200) {
throw new RuntimeException("Failed to download meta " + url + ": " + con.getResponseCode() + " - " + con.getResponseMessage());
}
final InputStream stream = con.getInputStream();
final byte[] data = stream.readAllBytes();
if(cache != null) {
Files.createDirectories(cache.getParent());
Files.write(cache, data, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
final List csv = this.loadCsv(new ByteArrayInputStream(data));
con.disconnect();
return csv;
}
private List loadCsvFile(final Path file) throws IOException, CsvException {
return this.loadCsv(Files.newInputStream(file));
}
private List loadCsv(final InputStream input) throws IOException, CsvException {
try(final CSVReader reader = new CSVReader(new InputStreamReader(input))) {
return reader.readAll();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy