269 lines
10 KiB
Java
269 lines
10 KiB
Java
package de.mc8051.arma3launcher.repo;
|
|
|
|
import de.mc8051.arma3launcher.ArmA3Launcher;
|
|
import de.mc8051.arma3launcher.interfaces.Observable;
|
|
import de.mc8051.arma3launcher.interfaces.Observer;
|
|
import de.mc8051.arma3launcher.objects.AbstractMod;
|
|
import de.mc8051.arma3launcher.objects.Changelog;
|
|
import de.mc8051.arma3launcher.objects.Mod;
|
|
import de.mc8051.arma3launcher.objects.ModFile;
|
|
import de.mc8051.arma3launcher.objects.Modset;
|
|
import de.mc8051.arma3launcher.objects.Server;
|
|
import de.mc8051.arma3launcher.utils.Callback;
|
|
import org.ini4j.Ini;
|
|
import org.json.JSONArray;
|
|
import org.json.JSONObject;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
import java.net.http.HttpClient;
|
|
import java.net.http.HttpRequest;
|
|
import java.net.http.HttpResponse;
|
|
import java.time.Duration;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import java.util.stream.Collectors;
|
|
|
|
import static java.time.temporal.ChronoUnit.SECONDS;
|
|
|
|
/**
|
|
* Created by gurkengewuerz.de on 24.03.2020.
|
|
*/
|
|
public class RepositoryManger implements Observable {
|
|
|
|
private static RepositoryManger instance;
|
|
|
|
public static ArrayList<AbstractMod> MOD_LIST = new ArrayList<>();
|
|
public static int MOD_LIST_SIZE = 0;
|
|
private static HashMap<Type, DownloadStatus> statusMap = new HashMap<>();
|
|
|
|
private List<Observer> observerList = new ArrayList<>();
|
|
|
|
private RepositoryManger() {
|
|
statusMap.put(Type.METADATA, DownloadStatus.FINNISHED);
|
|
statusMap.put(Type.MODSET, DownloadStatus.FINNISHED);
|
|
statusMap.put(Type.CHANGELOG, DownloadStatus.FINNISHED);
|
|
}
|
|
|
|
public void getAsync(String urlS, Callback.HttpCallback callback) {
|
|
new Thread(() -> {
|
|
try {
|
|
URI url = new URI(urlS);
|
|
|
|
HttpRequest request = HttpRequest.newBuilder()
|
|
.uri(url)
|
|
.GET()
|
|
.headers("User-Agent", ArmA3Launcher.USER_AGENT)
|
|
.timeout(Duration.of(3, SECONDS))
|
|
.build();
|
|
|
|
HttpResponse<String> response = HttpClient.newBuilder()
|
|
.followRedirects(HttpClient.Redirect.ALWAYS)
|
|
.build().send(request, HttpResponse.BodyHandlers.ofString());
|
|
|
|
Response r = new Response(response);
|
|
|
|
if (!r.isSuccessful()) {
|
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Cant open " + r.request().uri() + " code " + r.getStatusCode());
|
|
return;
|
|
}
|
|
|
|
callback.response(r);
|
|
} catch (IOException | URISyntaxException | InterruptedException e) {
|
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
|
callback.response(null);
|
|
}
|
|
}).start();
|
|
}
|
|
|
|
public void refreshMeta() {
|
|
statusMap.replace(Type.METADATA, DownloadStatus.RUNNING);
|
|
RepositoryManger.getInstance().notifyObservers(Type.METADATA.toString());
|
|
getAsync(ArmA3Launcher.config.getString("sync.url") + "/.sync/server.json", new Callback.HttpCallback() {
|
|
@Override
|
|
public void response(Response r) {
|
|
if (!r.isSuccessful()) {
|
|
statusMap.replace(Type.METADATA, DownloadStatus.ERROR);
|
|
RepositoryManger.getInstance().notifyObservers(Type.METADATA.toString());
|
|
return;
|
|
}
|
|
|
|
try {
|
|
Modset.MODSET_LIST.clear();
|
|
Ini.Section section = ArmA3Launcher.user_config.get("presets");
|
|
if (section != null) {
|
|
for (String key : section.keySet()) {
|
|
String jsonString = section.get(key);
|
|
JSONArray ja = new JSONArray(jsonString);
|
|
new Modset(key, ja, Modset.Type.CLIENT);
|
|
}
|
|
}
|
|
|
|
JSONObject jsonObject = new JSONObject(r.getBody());
|
|
|
|
if (jsonObject.has("modsets")) {
|
|
JSONArray modsets = jsonObject.getJSONArray("modsets");
|
|
if (modsets.length() > 0) {
|
|
for (int i = 0; i < modsets.length(); i++) {
|
|
JSONObject modset = modsets.getJSONObject(i);
|
|
new Modset(modset, Modset.Type.SERVER);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Init servers after modsets because server search preset string in modsets
|
|
if (jsonObject.has("servers")) {
|
|
Server.SERVER_LIST.clear();
|
|
JSONArray servers = jsonObject.getJSONArray("servers");
|
|
if (servers.length() > 0) {
|
|
for (int i = 0; i < servers.length(); i++) {
|
|
JSONObject server = servers.getJSONObject(i);
|
|
new Server(server);
|
|
}
|
|
}
|
|
}
|
|
|
|
statusMap.replace(Type.METADATA, DownloadStatus.FINNISHED);
|
|
RepositoryManger.getInstance().notifyObservers(Type.METADATA.toString());
|
|
} catch (NullPointerException e) {
|
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void refreshModset() {
|
|
statusMap.replace(Type.MODSET, DownloadStatus.RUNNING);
|
|
RepositoryManger.getInstance().notifyObservers(Type.MODSET.toString());
|
|
getAsync(ArmA3Launcher.config.getString("sync.url") + "/.sync/modset.json", new Callback.HttpCallback() {
|
|
@Override
|
|
public void response(Response r) {
|
|
if (!r.isSuccessful()) {
|
|
statusMap.replace(Type.MODSET, DownloadStatus.ERROR);
|
|
RepositoryManger.getInstance().notifyObservers(Type.MODSET.toString());
|
|
return;
|
|
}
|
|
|
|
try {
|
|
RepositoryManger.MOD_LIST.clear();
|
|
RepositoryManger.MOD_LIST_SIZE = 0;
|
|
JSONObject jsonObject = new JSONObject(r.getBody());
|
|
|
|
String modPath = ArmA3Launcher.user_config.get("client", "modPath");
|
|
if(modPath == null) modPath = "";
|
|
|
|
String finalModPath = modPath;
|
|
jsonObject.keySet().forEach(modname ->
|
|
{
|
|
Object keyvalue = jsonObject.get(modname);
|
|
|
|
if (!(keyvalue instanceof JSONObject)) return;
|
|
|
|
JSONObject jsonMod = (JSONObject)keyvalue;
|
|
if(!jsonMod.has("size")) return;
|
|
|
|
long modsize = jsonMod.getLong("size");
|
|
|
|
if(jsonMod.has("content")) {
|
|
// Mod Directory
|
|
JSONObject content = jsonMod.getJSONObject("content");
|
|
|
|
ArrayList<ModFile> modFiles = new ArrayList<>();
|
|
Iterator<String> keys = content.keys();
|
|
while (keys.hasNext()) {
|
|
String modfile = keys.next();
|
|
JSONObject jo = content.getJSONObject(modfile);
|
|
long modfilesize = jo.getLong("size");
|
|
String sha1 = jo.getString("sha1");
|
|
|
|
modFiles.add(new ModFile(new File(finalModPath + File.separator + modname + File.separator + modfile), modfile, modname, modfilesize, sha1));
|
|
RepositoryManger.MOD_LIST_SIZE++;
|
|
}
|
|
|
|
MOD_LIST.add(new Mod(modname, modsize, modFiles));
|
|
} else {
|
|
// Single File
|
|
MOD_LIST.add(new ModFile(new File(finalModPath + File.separator + modname), modname, modsize, jsonMod.getString("sha1")));
|
|
RepositoryManger.MOD_LIST_SIZE++;
|
|
}
|
|
|
|
});
|
|
|
|
statusMap.replace(Type.MODSET, DownloadStatus.FINNISHED);
|
|
RepositoryManger.getInstance().notifyObservers(Type.MODSET.toString());
|
|
} catch (NullPointerException e) {
|
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void refreshChangelog() {
|
|
statusMap.replace(Type.CHANGELOG, DownloadStatus.RUNNING);
|
|
RepositoryManger.getInstance().notifyObservers(Type.CHANGELOG.toString());
|
|
|
|
getAsync(ArmA3Launcher.config.getString("sync.url") + "/.sync/changelog.txt", new Callback.HttpCallback() {
|
|
@Override
|
|
public void response(Response r) {
|
|
if (!r.isSuccessful()) {
|
|
statusMap.replace(Type.CHANGELOG, DownloadStatus.ERROR);
|
|
RepositoryManger.getInstance().notifyObservers(Type.CHANGELOG.toString());
|
|
return;
|
|
}
|
|
|
|
statusMap.replace(Type.CHANGELOG, DownloadStatus.FINNISHED);
|
|
RepositoryManger.getInstance().notifyObservers(Type.CHANGELOG.toString());
|
|
Changelog.setChangelog(r.getBody());
|
|
}
|
|
});
|
|
}
|
|
|
|
public static RepositoryManger getInstance() {
|
|
if (instance == null) instance = new RepositoryManger();
|
|
return instance;
|
|
}
|
|
|
|
public DownloadStatus getStatus(Type type) {
|
|
return statusMap.get(type);
|
|
}
|
|
|
|
@Override
|
|
public void addObserver(Observer observer) {
|
|
observerList.add(observer);
|
|
}
|
|
|
|
@Override
|
|
public void removeObserver(Observer observer) {
|
|
observerList.remove(observer);
|
|
}
|
|
|
|
@Override
|
|
public void notifyObservers(String obj) {
|
|
for (Observer obs : observerList) obs.update(obj);
|
|
}
|
|
|
|
public enum Type {
|
|
|
|
METADATA("metadata"),
|
|
MODSET("modset"),
|
|
CHANGELOG("changelog");
|
|
|
|
private String modset;
|
|
|
|
Type(String modset) {
|
|
this.modset = modset;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return modset;
|
|
}
|
|
}
|
|
}
|