From c632e4aaa464947723b43b68bf04351262a98cbd Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 21:27:45 +0200 Subject: [PATCH 01/48] added DotMinecraftDirectoryService and moved version list logic --- .../json/DotMinecraftDirectoryService.java | 69 +++++++++++++++++++ .../launcherprofiles/LauncherProfileJson.java | 6 +- .../versionlist/VersionListEntryJson.java | 41 ----------- .../json/versionlist/VersionListJson.java | 17 ----- .../GenerateRecognisedVersionList.java | 3 +- .../devtools/GenerateWorldTestData.java | 3 +- ...necraftJarDownloadAvailabilityChecker.java | 6 +- .../devtools/MinecraftJarDownloader.java | 6 +- .../MinecraftVersionCompatibilityChecker.java | 3 +- 9 files changed, 86 insertions(+), 68 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java diff --git a/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java new file mode 100644 index 000000000..8fd89920b --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java @@ -0,0 +1,69 @@ +package amidst.mojangapi.file.json; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; + +import amidst.documentation.Immutable; +import amidst.logging.AmidstLogger; +import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.URIUtils; +import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; +import amidst.mojangapi.file.json.versionlist.VersionListJson; + +@Immutable +public class DotMinecraftDirectoryService { + public VersionDirectory tryFindFirstValidVersionDirectory( + List allowedReleaseTypes, + MojangApi mojangApi) throws FileNotFoundException { + VersionListJson versionListJson = mojangApi.getVersionList(); + + for (VersionListEntryJson version : versionListJson.getVersions()) { + if (allowedReleaseTypes.contains(version.getType())) { + VersionDirectory versionDirectory = version.createVersionDirectory(mojangApi); + if (versionDirectory.isValid()) { + return versionDirectory; + } + } + } + return null; + } + + public boolean hasServer(VersionListEntryJson versionListEntryJson) { + return URIUtils.exists(versionListEntryJson.getRemoteServerJar()); + } + + public boolean hasClient(VersionListEntryJson versionListEntryJson) { + return URIUtils.exists(versionListEntryJson.getRemoteClientJar()); + } + + public void downloadServer(String prefix, VersionListEntryJson versionListEntryJson) throws IOException { + URIUtils.download(versionListEntryJson.getRemoteServerJar(), versionListEntryJson.getServerJar(prefix)); + } + + public void downloadClient(String prefix, VersionListEntryJson versionListEntryJson) throws IOException { + URIUtils.download(versionListEntryJson.getRemoteClientJar(), versionListEntryJson.getClientJar(prefix)); + URIUtils.download(versionListEntryJson.getRemoteClientJson(), versionListEntryJson.getClientJson(prefix)); + } + + public boolean tryDownloadServer(String prefix, VersionListEntryJson versionListEntryJson) { + try { + downloadServer(prefix, versionListEntryJson); + return true; + } catch (IOException e) { + AmidstLogger.warn(e, "unable to download server: " + versionListEntryJson.getId()); + } + return false; + } + + public boolean tryDownloadClient(String prefix, VersionListEntryJson versionListEntryJson) { + try { + downloadClient(prefix, versionListEntryJson); + return true; + } catch (IOException e) { + AmidstLogger.warn(e, "unable to download client: " + versionListEntryJson.getId()); + } + return false; + } +} diff --git a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java index 299a49802..7996ca984 100644 --- a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java +++ b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java @@ -11,8 +11,8 @@ import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.ReleaseType; -import amidst.mojangapi.file.json.versionlist.VersionListJson; @Immutable public class LauncherProfileJson { @@ -65,14 +65,14 @@ public ProfileDirectory createValidProfileDirectory(MojangApi mojangApi) throws @NotNull public VersionDirectory createValidVersionDirectory(MojangApi mojangApi) throws FileNotFoundException { - VersionListJson versionList = mojangApi.getVersionList(); if (lastVersionId != null) { VersionDirectory result = mojangApi.createVersionDirectory(lastVersionId); if (result.isValid()) { return result; } } else { - VersionDirectory result = versionList.tryFindFirstValidVersionDirectory(allowedReleaseTypes, mojangApi); + VersionDirectory result = new DotMinecraftDirectoryService() + .tryFindFirstValidVersionDirectory(allowedReleaseTypes, mojangApi); if (result != null) { return result; } diff --git a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java index 5b4b9ba41..eac7cbb47 100644 --- a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java +++ b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java @@ -1,13 +1,9 @@ package amidst.mojangapi.file.json.versionlist; -import java.io.IOException; - import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; -import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.FilenameFactory; -import amidst.mojangapi.file.URIUtils; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.ReleaseType; @@ -55,41 +51,4 @@ public String getRemoteClientJson() { public String getRemoteServerJar() { return FilenameFactory.getRemoteServerJar(id); } - - public boolean hasServer() { - return URIUtils.exists(getRemoteServerJar()); - } - - public boolean hasClient() { - return URIUtils.exists(getRemoteClientJar()); - } - - public void downloadServer(String prefix) throws IOException { - URIUtils.download(getRemoteServerJar(), getServerJar(prefix)); - } - - public void downloadClient(String prefix) throws IOException { - URIUtils.download(getRemoteClientJar(), getClientJar(prefix)); - URIUtils.download(getRemoteClientJson(), getClientJson(prefix)); - } - - public boolean tryDownloadServer(String prefix) { - try { - downloadServer(prefix); - return true; - } catch (IOException e) { - AmidstLogger.warn(e, "unable to download server: " + id); - } - return false; - } - - public boolean tryDownloadClient(String prefix) { - try { - downloadClient(prefix); - return true; - } catch (IOException e) { - AmidstLogger.warn(e, "unable to download client: " + id); - } - return false; - } } diff --git a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListJson.java b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListJson.java index aa7456dec..cd95c6ff6 100644 --- a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListJson.java +++ b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListJson.java @@ -5,9 +5,6 @@ import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; -import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.ReleaseType; @Immutable public class VersionListJson { @@ -20,18 +17,4 @@ public VersionListJson() { public List getVersions() { return versions; } - - public VersionDirectory tryFindFirstValidVersionDirectory( - List allowedReleaseTypes, - MojangApi mojangApi) { - for (VersionListEntryJson version : versions) { - if (allowedReleaseTypes.contains(version.getType())) { - VersionDirectory versionDirectory = version.createVersionDirectory(mojangApi); - if (versionDirectory.isValid()) { - return versionDirectory; - } - } - } - return null; - } } diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 868054d89..259e08bea 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -11,6 +11,7 @@ import amidst.mojangapi.file.FilenameFactory; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -45,7 +46,7 @@ private void populate() { private void process(VersionListEntryJson version) { String versionId = version.getId(); - if (version.tryDownloadClient(prefix)) { + if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { try { process(versionId); } catch (ClassNotFoundException | MalformedURLException | NoClassDefFoundError e) { diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index c7da73505..383ce076b 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -8,6 +8,7 @@ import amidst.mojangapi.file.FilenameFactory; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; @@ -51,7 +52,7 @@ public void run() { private void generate(TestWorldDeclaration declaration, VersionListEntryJson version) { String versionId = version.getId(); - if (version.tryDownloadClient(prefix)) { + if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { try { TestWorldCache.createAndPut( declaration, diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java index b32b7b3d8..3f31a02ac 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java @@ -1,6 +1,7 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; +import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; @@ -13,9 +14,10 @@ public MinecraftJarDownloadAvailabilityChecker(VersionListJson versionList) { } public void run() { + DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); for (VersionListEntryJson version : versionList.getVersions()) { - boolean hasServer = version.hasServer(); - boolean hasClient = version.hasClient(); + boolean hasServer = dotMinecraftDirectoryService.hasServer(version); + boolean hasClient = dotMinecraftDirectoryService.hasClient(version); System.out.println(renderer.render(version, hasServer, hasClient)); } } diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloader.java b/src/test/java/amidst/devtools/MinecraftJarDownloader.java index 9465e54e3..4bc76aa1b 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloader.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloader.java @@ -1,6 +1,7 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; +import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; @@ -15,9 +16,10 @@ public MinecraftJarDownloader(String prefix, VersionListJson versionList) { } public void run() { + DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); for (VersionListEntryJson version : versionList.getVersions()) { - boolean hasServer = version.tryDownloadServer(prefix); - boolean hasClient = version.tryDownloadClient(prefix); + boolean hasServer = dotMinecraftDirectoryService.tryDownloadServer(prefix, version); + boolean hasClient = dotMinecraftDirectoryService.tryDownloadClient(prefix, version); System.out.println(renderer.render(version, hasServer, hasClient)); } } diff --git a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java index c7525ddc4..b0845345a 100644 --- a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java @@ -11,6 +11,7 @@ import amidst.clazz.real.JarFileParsingException; import amidst.clazz.symbolic.declaration.SymbolicClassDeclaration; import amidst.clazz.translator.ClassTranslator; +import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; @@ -45,7 +46,7 @@ public void run() { } private boolean checkOne(VersionListEntryJson version) { - if (version.tryDownloadClient(prefix)) { + if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { try { File jarFile = new File(version.getClientJar(prefix)); ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); From a37f1e023fd60b9104446f6901eadf21abd92525 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 21:36:52 +0200 Subject: [PATCH 02/48] replaced FilenameFactory by FilenameService --- src/main/java/amidst/mojangapi/MojangApi.java | 7 ++-- ...enameFactory.java => FilenameService.java} | 26 ++++++------- .../json/DotMinecraftDirectoryService.java | 39 ++++++++++++------- .../versionlist/VersionListEntryJson.java | 25 ------------ .../GenerateRecognisedVersionList.java | 7 ++-- .../devtools/GenerateWorldTestData.java | 7 ++-- .../MinecraftVersionCompatibilityChecker.java | 3 +- 7 files changed, 50 insertions(+), 64 deletions(-) rename src/main/java/amidst/mojangapi/file/{FilenameFactory.java => FilenameService.java} (58%) diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 786a1f8ad..d703ccdaf 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -6,7 +6,7 @@ import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; -import amidst.mojangapi.file.FilenameFactory; +import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; @@ -80,8 +80,9 @@ public void set(String profileName, ProfileDirectory profileDirectory, VersionDi public VersionDirectory createVersionDirectory(String versionId) { File versions = dotMinecraftDirectory.getVersions(); - File jar = FilenameFactory.getClientJarFile(versions, versionId); - File json = FilenameFactory.getClientJsonFile(versions, versionId); + FilenameService filenameService = new FilenameService(); + File jar = filenameService.getClientJarFile(versions, versionId); + File json = filenameService.getClientJsonFile(versions, versionId); return doCreateVersionDirectory(versionId, jar, json); } diff --git a/src/main/java/amidst/mojangapi/file/FilenameFactory.java b/src/main/java/amidst/mojangapi/file/FilenameService.java similarity index 58% rename from src/main/java/amidst/mojangapi/file/FilenameFactory.java rename to src/main/java/amidst/mojangapi/file/FilenameService.java index 09be06c65..a6dfc6185 100644 --- a/src/main/java/amidst/mojangapi/file/FilenameFactory.java +++ b/src/main/java/amidst/mojangapi/file/FilenameService.java @@ -5,56 +5,54 @@ import amidst.documentation.Immutable; @Immutable -public enum FilenameFactory { - ; - +public class FilenameService { private static final String REMOTE_PREFIX = "https://s3.amazonaws.com/Minecraft.Download/versions/"; private static final String MIDDLE_SERVER = "/minecraft_server."; private static final String MIDDLE_CLIENT = "/"; private static final String JAR_FILE_EXTENSION = ".jar"; private static final String JSON_FILE_EXTENSION = ".json"; - public static File getClientJsonFile(File prefix, String versionId) { + public File getClientJsonFile(File prefix, String versionId) { return getClientFile(prefix, versionId, JSON_FILE_EXTENSION); } - public static File getClientJarFile(File prefix, String versionId) { + public File getClientJarFile(File prefix, String versionId) { return getClientFile(prefix, versionId, JAR_FILE_EXTENSION); } - private static File getClientFile(File prefix, String versionId, String fileExtension) { + private File getClientFile(File prefix, String versionId, String fileExtension) { return new File(prefix, getClientLocation("", versionId, fileExtension)); } - public static String getRemoteClientJson(String versionId) { + public String getRemoteClientJson(String versionId) { return getClientJson(REMOTE_PREFIX, versionId); } - public static String getClientJson(String prefix, String versionId) { + public String getClientJson(String prefix, String versionId) { return getClientLocation(prefix, versionId, JSON_FILE_EXTENSION); } - public static String getRemoteClientJar(String versionId) { + public String getRemoteClientJar(String versionId) { return getClientJar(REMOTE_PREFIX, versionId); } - public static String getClientJar(String prefix, String versionId) { + public String getClientJar(String prefix, String versionId) { return getClientLocation(prefix, versionId, JAR_FILE_EXTENSION); } - private static String getClientLocation(String prefix, String versionId, String fileExtension) { + private String getClientLocation(String prefix, String versionId, String fileExtension) { return prefix + versionId + MIDDLE_CLIENT + versionId + fileExtension; } - public static String getRemoteServerJar(String versionId) { + public String getRemoteServerJar(String versionId) { return getServerJar(REMOTE_PREFIX, versionId); } - public static String getServerJar(String prefix, String versionId) { + public String getServerJar(String prefix, String versionId) { return getServerLocation(prefix, versionId, JAR_FILE_EXTENSION); } - private static String getServerLocation(String prefix, String versionId, String fileExtension) { + private String getServerLocation(String prefix, String versionId, String fileExtension) { return prefix + versionId + MIDDLE_SERVER + versionId + fileExtension; } } diff --git a/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java index 8fd89920b..1739b0c7c 100644 --- a/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java @@ -7,6 +7,7 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.URIUtils; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; @@ -14,6 +15,8 @@ @Immutable public class DotMinecraftDirectoryService { + private final FilenameService filenameService = new FilenameService(); + public VersionDirectory tryFindFirstValidVersionDirectory( List allowedReleaseTypes, MojangApi mojangApi) throws FileNotFoundException { @@ -30,39 +33,45 @@ public VersionDirectory tryFindFirstValidVersionDirectory( return null; } - public boolean hasServer(VersionListEntryJson versionListEntryJson) { - return URIUtils.exists(versionListEntryJson.getRemoteServerJar()); + public boolean hasServer(VersionListEntryJson version) { + return URIUtils.exists(filenameService.getRemoteServerJar(version.getId())); } - public boolean hasClient(VersionListEntryJson versionListEntryJson) { - return URIUtils.exists(versionListEntryJson.getRemoteClientJar()); + public boolean hasClient(VersionListEntryJson version) { + return URIUtils.exists(filenameService.getRemoteClientJar(version.getId())); } - public void downloadServer(String prefix, VersionListEntryJson versionListEntryJson) throws IOException { - URIUtils.download(versionListEntryJson.getRemoteServerJar(), versionListEntryJson.getServerJar(prefix)); + public void downloadServer(String prefix, VersionListEntryJson version) throws IOException { + URIUtils.download( + filenameService.getRemoteServerJar(version.getId()), + filenameService.getServerJar(prefix, version.getId())); } - public void downloadClient(String prefix, VersionListEntryJson versionListEntryJson) throws IOException { - URIUtils.download(versionListEntryJson.getRemoteClientJar(), versionListEntryJson.getClientJar(prefix)); - URIUtils.download(versionListEntryJson.getRemoteClientJson(), versionListEntryJson.getClientJson(prefix)); + public void downloadClient(String prefix, VersionListEntryJson version) throws IOException { + URIUtils.download( + filenameService.getRemoteClientJar(version.getId()), + filenameService.getClientJar(prefix, version.getId())); + URIUtils.download( + filenameService.getRemoteClientJson(version.getId()), + filenameService.getClientJson(prefix, version.getId())); } - public boolean tryDownloadServer(String prefix, VersionListEntryJson versionListEntryJson) { + public boolean tryDownloadServer(String prefix, VersionListEntryJson version) { try { - downloadServer(prefix, versionListEntryJson); + downloadServer(prefix, version); return true; } catch (IOException e) { - AmidstLogger.warn(e, "unable to download server: " + versionListEntryJson.getId()); + AmidstLogger.warn(e, "unable to download server: " + version.getId()); } return false; } - public boolean tryDownloadClient(String prefix, VersionListEntryJson versionListEntryJson) { + public boolean tryDownloadClient(String prefix, VersionListEntryJson version) { try { - downloadClient(prefix, versionListEntryJson); + downloadClient(prefix, version); return true; } catch (IOException e) { - AmidstLogger.warn(e, "unable to download client: " + versionListEntryJson.getId()); + AmidstLogger.warn(e, "unable to download client: " + version.getId()); } return false; } diff --git a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java index eac7cbb47..df6fa0729 100644 --- a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java +++ b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java @@ -3,7 +3,6 @@ import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.FilenameFactory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.ReleaseType; @@ -27,28 +26,4 @@ public ReleaseType getType() { public VersionDirectory createVersionDirectory(MojangApi mojangApi) { return mojangApi.createVersionDirectory(id); } - - public String getClientJar(String prefix) { - return FilenameFactory.getClientJar(prefix, id); - } - - public String getClientJson(String prefix) { - return FilenameFactory.getClientJson(prefix, id); - } - - public String getServerJar(String prefix) { - return FilenameFactory.getServerJar(prefix, id); - } - - public String getRemoteClientJar() { - return FilenameFactory.getRemoteClientJar(id); - } - - public String getRemoteClientJson() { - return FilenameFactory.getRemoteClientJson(id); - } - - public String getRemoteServerJar() { - return FilenameFactory.getRemoteServerJar(id); - } } diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 259e08bea..d4a4b4929 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -8,7 +8,7 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.FilenameFactory; +import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.DotMinecraftDirectoryService; @@ -67,8 +67,9 @@ private void process(String versionId) throws MalformedURLException, ClassNotFou } private VersionDirectory createVersionDirectory(String versionId) { - File jar = FilenameFactory.getClientJarFile(versions, versionId); - File json = FilenameFactory.getClientJsonFile(versions, versionId); + FilenameService filenameService = new FilenameService(); + File jar = filenameService.getClientJarFile(versions, versionId); + File json = filenameService.getClientJsonFile(versions, versionId); return new VersionDirectory(dotMinecraftDirectory, versionId, jar, json); } diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 383ce076b..588d9fbf6 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -5,7 +5,7 @@ import java.util.LinkedList; import java.util.List; -import amidst.mojangapi.file.FilenameFactory; +import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.DotMinecraftDirectoryService; @@ -68,8 +68,9 @@ private void generate(TestWorldDeclaration declaration, VersionListEntryJson ver } private VersionDirectory createVersionDirectory(String versionId) { - File jar = FilenameFactory.getClientJarFile(versions, versionId); - File json = FilenameFactory.getClientJsonFile(versions, versionId); + FilenameService filenameService = new FilenameService(); + File jar = filenameService.getClientJarFile(versions, versionId); + File json = filenameService.getClientJsonFile(versions, versionId); return new VersionDirectory(dotMinecraftDirectory, versionId, jar, json); } diff --git a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java index b0845345a..2431abd4d 100644 --- a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java @@ -11,6 +11,7 @@ import amidst.clazz.real.JarFileParsingException; import amidst.clazz.symbolic.declaration.SymbolicClassDeclaration; import amidst.clazz.translator.ClassTranslator; +import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; @@ -48,7 +49,7 @@ public void run() { private boolean checkOne(VersionListEntryJson version) { if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { try { - File jarFile = new File(version.getClientJar(prefix)); + File jarFile = new File(new FilenameService().getClientJar(prefix, version.getId())); ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); return isSupported(Classes.countMatches(jarFile, translator)); } catch (FileNotFoundException | JarFileParsingException e) { From 33c36b2b048927718045f0ecbeb1501449d1198d Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 21:50:17 +0200 Subject: [PATCH 03/48] moved remaining version list logic to DotMinecraftDirectoryService --- .../mojangapi/file/json/DotMinecraftDirectoryService.java | 2 +- .../file/json/versionlist/VersionListEntryJson.java | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java index 1739b0c7c..6ab685ceb 100644 --- a/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java @@ -24,7 +24,7 @@ public VersionDirectory tryFindFirstValidVersionDirectory( for (VersionListEntryJson version : versionListJson.getVersions()) { if (allowedReleaseTypes.contains(version.getType())) { - VersionDirectory versionDirectory = version.createVersionDirectory(mojangApi); + VersionDirectory versionDirectory = mojangApi.createVersionDirectory(version.getId()); if (versionDirectory.isValid()) { return versionDirectory; } diff --git a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java index df6fa0729..44f495319 100644 --- a/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java +++ b/src/main/java/amidst/mojangapi/file/json/versionlist/VersionListEntryJson.java @@ -2,8 +2,6 @@ import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; -import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.ReleaseType; @Immutable @@ -22,8 +20,4 @@ public String getId() { public ReleaseType getType() { return type; } - - public VersionDirectory createVersionDirectory(MojangApi mojangApi) { - return mojangApi.createVersionDirectory(id); - } } From 34a3a48a7977c98527b05b2b485e2aad430e3f3d Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 21:52:02 +0200 Subject: [PATCH 04/48] moved DotMinecraftDirectoryService --- .../file/{json => }/DotMinecraftDirectoryService.java | 5 ++--- .../file/json/launcherprofiles/LauncherProfileJson.java | 2 +- .../java/amidst/devtools/GenerateRecognisedVersionList.java | 2 +- src/test/java/amidst/devtools/GenerateWorldTestData.java | 2 +- .../devtools/MinecraftJarDownloadAvailabilityChecker.java | 2 +- src/test/java/amidst/devtools/MinecraftJarDownloader.java | 2 +- .../devtools/MinecraftVersionCompatibilityChecker.java | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) rename src/main/java/amidst/mojangapi/file/{json => }/DotMinecraftDirectoryService.java (95%) diff --git a/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java similarity index 95% rename from src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java rename to src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java index 6ab685ceb..7c9d7336a 100644 --- a/src/main/java/amidst/mojangapi/file/json/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.json; +package amidst.mojangapi.file; import java.io.FileNotFoundException; import java.io.IOException; @@ -7,9 +7,8 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.FilenameService; -import amidst.mojangapi.file.URIUtils; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; diff --git a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java index 7996ca984..d779d84a1 100644 --- a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java +++ b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java @@ -9,9 +9,9 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.ReleaseType; @Immutable diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index d4a4b4929..194b08cad 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -8,10 +8,10 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.RecognisedVersion; diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 588d9fbf6..f4216ce77 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -5,10 +5,10 @@ import java.util.LinkedList; import java.util.List; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java index 3f31a02ac..236620768 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java @@ -1,7 +1,7 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.json.DotMinecraftDirectoryService; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloader.java b/src/test/java/amidst/devtools/MinecraftJarDownloader.java index 4bc76aa1b..bfb2eeb9b 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloader.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloader.java @@ -1,7 +1,7 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.json.DotMinecraftDirectoryService; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; diff --git a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java index 2431abd4d..57a7fc5fc 100644 --- a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java @@ -11,8 +11,8 @@ import amidst.clazz.real.JarFileParsingException; import amidst.clazz.symbolic.declaration.SymbolicClassDeclaration; import amidst.clazz.translator.ClassTranslator; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.FilenameService; -import amidst.mojangapi.file.json.DotMinecraftDirectoryService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; From f2f97f41108db4f5af60f823571651a0457536e1 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 22:39:05 +0200 Subject: [PATCH 05/48] moved library logic to new LibraryService --- .../amidst/mojangapi/file/LibraryFinder.java | 2 +- .../amidst/mojangapi/file/LibraryService.java | 57 +++++++++++++++++++ .../file/directory/VersionDirectory.java | 3 +- .../file/json/version/LibraryJson.java | 18 +----- .../file/json/version/LibraryRuleJson.java | 10 ++-- .../file/json/version/LibraryRuleOsJson.java | 10 ++-- .../file/json/version/VersionJson.java | 9 --- 7 files changed, 72 insertions(+), 37 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/LibraryService.java diff --git a/src/main/java/amidst/mojangapi/file/LibraryFinder.java b/src/main/java/amidst/mojangapi/file/LibraryFinder.java index 531fc0861..197dbfc0d 100644 --- a/src/main/java/amidst/mojangapi/file/LibraryFinder.java +++ b/src/main/java/amidst/mojangapi/file/LibraryFinder.java @@ -37,7 +37,7 @@ public static List getLibraryUrls(File librariesDirectory, List rules = libraryJson.getRules(); + if (rules.isEmpty()) { + return true; + } + boolean result = false; + for (LibraryRuleJson rule : rules) { + if (isApplicable(os, version, rule)) { + result = isAllowed(rule); + } + } + return result; + } + + private boolean isApplicable(String os, String version, LibraryRuleJson rule) { + LibraryRuleOsJson osRule = rule.getOs(); + return osRule == null || isApplicable(os, version, osRule); + } + + private boolean isApplicable(String os, String version, LibraryRuleOsJson osRule) { + String nameInJson = osRule.getName(); + String versionInJson = osRule.getVersion(); + return nameInJson.equals(os) && (versionInJson == null || Pattern.matches(versionInJson, version)); + } + + public boolean isAllowed(LibraryRuleJson rule) { + return rule.getAction().equals(ACTION_ALLOW); + } + + @NotNull + public List getLibraryUrls(File librariesDirectory, VersionJson versionJson) { + return LibraryFinder.getLibraryUrls(librariesDirectory, versionJson.getLibraries()); + } +} diff --git a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java index 578b8766d..37a527a33 100644 --- a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java @@ -11,6 +11,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.LibraryService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.version.VersionJson; @@ -76,7 +77,7 @@ private URL getJarFileUrl() throws MalformedURLException { @NotNull private List getAllLibraryUrls() { try { - return readVersionJson().getLibraryUrls(dotMinecraftDirectory.getLibraries()); + return new LibraryService().getLibraryUrls(dotMinecraftDirectory.getLibraries(), readVersionJson()); } catch (IOException | MojangApiParsingException e) { AmidstLogger.warn("Invalid jar profile loaded. Library loading will be skipped. (Path: " + json + ")"); return new ArrayList<>(); diff --git a/src/main/java/amidst/mojangapi/file/json/version/LibraryJson.java b/src/main/java/amidst/mojangapi/file/json/version/LibraryJson.java index 05b7864d0..698698fd2 100644 --- a/src/main/java/amidst/mojangapi/file/json/version/LibraryJson.java +++ b/src/main/java/amidst/mojangapi/file/json/version/LibraryJson.java @@ -19,21 +19,7 @@ public String getName() { return name; } - /** - * Note, that multiple rules might be applicable. We take the last - * applicable rule. However, this might be wrong so we need to take the most - * specific rule? For now this works fine. - */ - public boolean isActive(String os, String version) { - if (rules.isEmpty()) { - return true; - } - boolean result = false; - for (LibraryRuleJson rule : rules) { - if (rule.isApplicable(os, version)) { - result = rule.isAllowed(); - } - } - return result; + public List getRules() { + return rules; } } diff --git a/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleJson.java b/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleJson.java index 7a8803d14..537b74109 100644 --- a/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleJson.java +++ b/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleJson.java @@ -5,8 +5,6 @@ @Immutable public class LibraryRuleJson { - private static final String ACTION_ALLOW = "allow"; - private volatile String action; private volatile LibraryRuleOsJson os; @@ -14,11 +12,11 @@ public class LibraryRuleJson { public LibraryRuleJson() { } - public boolean isApplicable(String os, String version) { - return this.os == null || this.os.isApplicable(os, version); + public String getAction() { + return action; } - public boolean isAllowed() { - return action.equals(ACTION_ALLOW); + public LibraryRuleOsJson getOs() { + return os; } } diff --git a/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleOsJson.java b/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleOsJson.java index b2ef1b438..f2c0e57dd 100644 --- a/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleOsJson.java +++ b/src/main/java/amidst/mojangapi/file/json/version/LibraryRuleOsJson.java @@ -1,7 +1,5 @@ package amidst.mojangapi.file.json.version; -import java.util.regex.Pattern; - import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; @@ -14,7 +12,11 @@ public class LibraryRuleOsJson { public LibraryRuleOsJson() { } - public boolean isApplicable(String os, String version) { - return this.name.equals(os) && (this.version == null || Pattern.matches(this.version, version)); + public String getName() { + return name; + } + + public String getVersion() { + return version; } } diff --git a/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java b/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java index 43f793ef3..9d3bea385 100644 --- a/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java +++ b/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java @@ -1,14 +1,10 @@ package amidst.mojangapi.file.json.version; -import java.io.File; -import java.net.URL; import java.util.Collections; import java.util.List; import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.file.LibraryFinder; @Immutable public class VersionJson { @@ -21,9 +17,4 @@ public VersionJson() { public List getLibraries() { return libraries; } - - @NotNull - public List getLibraryUrls(File librariesDirectory) { - return LibraryFinder.getLibraryUrls(librariesDirectory, libraries); - } } From 3b2e580357ae463f2b7cd0a5386f388c1496c556 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 22:58:32 +0200 Subject: [PATCH 06/48] moved logic from player json to new PlayerSkinService --- .../mojangapi/file/PlayerSkinService.java | 58 +++++++++++++++++++ .../file/json/player/PlayerJson.java | 27 --------- .../file/json/player/PropertyJson.java | 24 -------- .../mojangapi/file/json/player/SKINJson.java | 4 -- .../world/player/PlayerInformation.java | 3 +- 5 files changed, 60 insertions(+), 56 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/PlayerSkinService.java diff --git a/src/main/java/amidst/mojangapi/file/PlayerSkinService.java b/src/main/java/amidst/mojangapi/file/PlayerSkinService.java new file mode 100644 index 000000000..609c47db0 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/PlayerSkinService.java @@ -0,0 +1,58 @@ +package amidst.mojangapi.file; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Optional; + +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.mojangapi.file.json.JsonReader; +import amidst.mojangapi.file.json.player.PlayerJson; +import amidst.mojangapi.file.json.player.PropertyJson; +import amidst.mojangapi.file.json.player.SKINJson; +import amidst.mojangapi.file.json.player.TexturesJson; +import amidst.mojangapi.file.json.player.TexturesPropertyJson; + +@Immutable +public class PlayerSkinService { + @NotNull + public String getSkinUrl(PlayerJson playerJson) throws MojangApiParsingException { + return readTexturesProperty(playerJson) + .map(TexturesPropertyJson::getTextures) + .map(TexturesJson::getSKIN) + .map(SKINJson::getUrl) + .orElseThrow(() -> new MojangApiParsingException("unable to get skin url")); + } + + @NotNull + private Optional readTexturesProperty(PlayerJson playerJson) + throws MojangApiParsingException { + for (PropertyJson property : playerJson.getProperties()) { + if (isTexturesProperty(property)) { + return Optional.of(JsonReader.read(getDecodedValue(property), TexturesPropertyJson.class)); + } + } + return Optional.empty(); + } + + private boolean isTexturesProperty(PropertyJson propertyJson) throws MojangApiParsingException { + String name = propertyJson.getName(); + if (name == null) { + throw new MojangApiParsingException("property has no name"); + } else { + return name.equals("textures"); + } + } + + @NotNull + private String getDecodedValue(PropertyJson propertyJson) throws MojangApiParsingException { + String value = propertyJson.getValue(); + if (value == null) { + throw new MojangApiParsingException("unable to decode property value"); + } else { + return new String( + Base64.getDecoder().decode(value.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8); + } + } +} diff --git a/src/main/java/amidst/mojangapi/file/json/player/PlayerJson.java b/src/main/java/amidst/mojangapi/file/json/player/PlayerJson.java index a657e2f46..b3b3e4c93 100644 --- a/src/main/java/amidst/mojangapi/file/json/player/PlayerJson.java +++ b/src/main/java/amidst/mojangapi/file/json/player/PlayerJson.java @@ -5,9 +5,6 @@ import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.JsonReader; @Immutable public class PlayerJson { @@ -30,28 +27,4 @@ public String getName() { public List getProperties() { return properties; } - - @NotNull - public TexturesPropertyJson readTexturesProperty() throws MojangApiParsingException { - for (PropertyJson property : properties) { - if (property.isTexturesProperty()) { - return JsonReader.read(property.getDecodedValue(), TexturesPropertyJson.class); - } - } - throw new MojangApiParsingException("player json does not contain the textures property"); - } - - @NotNull - public String getSkinUrl() throws MojangApiParsingException { - try { - String result = readTexturesProperty().getTextures().getSKIN().getUrl(); - if (result != null) { - return result; - } else { - throw new MojangApiParsingException("unable to get skin url"); - } - } catch (NullPointerException e) { - throw new MojangApiParsingException("unable to get skin url", e); - } - } } diff --git a/src/main/java/amidst/mojangapi/file/json/player/PropertyJson.java b/src/main/java/amidst/mojangapi/file/json/player/PropertyJson.java index 406b478e5..5ed0058e4 100644 --- a/src/main/java/amidst/mojangapi/file/json/player/PropertyJson.java +++ b/src/main/java/amidst/mojangapi/file/json/player/PropertyJson.java @@ -1,12 +1,7 @@ package amidst.mojangapi.file.json.player; -import java.nio.charset.StandardCharsets; -import java.util.Base64; - import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.file.MojangApiParsingException; @Immutable public class PropertyJson { @@ -24,23 +19,4 @@ public String getName() { public String getValue() { return value; } - - @NotNull - public String getDecodedValue() throws MojangApiParsingException { - if (value == null) { - throw new MojangApiParsingException("unable to decode property value"); - } else { - return new String( - Base64.getDecoder().decode(value.getBytes(StandardCharsets.UTF_8)), - StandardCharsets.UTF_8); - } - } - - public boolean isTexturesProperty() throws MojangApiParsingException { - if (name == null) { - throw new MojangApiParsingException("property has no name"); - } else { - return name.equals("textures"); - } - } } diff --git a/src/main/java/amidst/mojangapi/file/json/player/SKINJson.java b/src/main/java/amidst/mojangapi/file/json/player/SKINJson.java index af4332e2b..bf46646f9 100644 --- a/src/main/java/amidst/mojangapi/file/json/player/SKINJson.java +++ b/src/main/java/amidst/mojangapi/file/json/player/SKINJson.java @@ -19,8 +19,4 @@ public String getUrl() { public MetadataJson getMetadata() { return metadata; } - - public boolean isSlimModel() { - return metadata != null && metadata.getModel().equals("slim"); - } } diff --git a/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java b/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java index 893848d69..37fb59783 100644 --- a/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java +++ b/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java @@ -5,6 +5,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.PlayerSkinService; import amidst.mojangapi.file.json.PlayerInformationRetriever; import amidst.mojangapi.file.json.player.PlayerJson; import amidst.mojangapi.world.icon.WorldIconImage; @@ -63,7 +64,7 @@ public static PlayerInformation fromName(String name) { private static WorldIconImage tryGetPlayerHeadBySkinUrl(PlayerJson player) { BufferedImage head; try { - head = PlayerInformationRetriever.tryGetPlayerHeadBySkinUrl(player.getSkinUrl()); + head = PlayerInformationRetriever.tryGetPlayerHeadBySkinUrl(new PlayerSkinService().getSkinUrl(player)); return head != null ? WorldIconImage.from(head) : null; } catch (MojangApiParsingException e) { return null; From afb28dd1191df3bd0a00adf0a754addd8a7341dd Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 23:17:06 +0200 Subject: [PATCH 07/48] moved launcher profile logic to new LauncherProfileService --- .../profileselect/LocalProfileComponent.java | 5 +- .../profileselect/ProfileSelectWindow.java | 4 +- .../file/LauncherProfileService.java | 52 +++++++++++++++++++ .../launcherprofiles/LauncherProfileJson.java | 39 +------------- .../LauncherProfilesJson.java | 5 +- 5 files changed, 61 insertions(+), 44 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/LauncherProfileService.java diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index eb412c021..5e3e7fb47 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -11,6 +11,7 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.LauncherProfileService; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; @@ -55,8 +56,8 @@ private void initDirectoriesLater() { @CalledOnlyBy(AmidstThread.WORKER) private boolean tryFind() { try { - profileDirectory = profile.createValidProfileDirectory(mojangApi); - versionDirectory = profile.createValidVersionDirectory(mojangApi); + profileDirectory = new LauncherProfileService().createValidProfileDirectory(profile, mojangApi); + versionDirectory = new LauncherProfileService().createValidVersionDirectory(profile, mojangApi); return true; } catch (FileNotFoundException e) { AmidstLogger.warn(e); diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index ee44112e2..43c1a205b 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -128,7 +128,7 @@ private void displayProfiles(LauncherProfilesJson launcherProfile) { @CalledOnlyBy(AmidstThread.EDT) private void createProfileComponentsIfNecessary(LauncherProfilesJson launcherProfile) { - if (launcherProfile.getProfiles().isEmpty()) { + if (launcherProfile.getProfiles().values().isEmpty()) { AmidstLogger.warn("No profiles found in launcher_profiles.json"); profileSelectPanel.setEmptyMessage("No profiles found"); } else { @@ -138,7 +138,7 @@ private void createProfileComponentsIfNecessary(LauncherProfilesJson launcherPro @CalledOnlyBy(AmidstThread.EDT) private void createProfileComponents(LauncherProfilesJson launcherProfile) { - for (LauncherProfileJson profile : launcherProfile.getProfiles()) { + for (LauncherProfileJson profile : launcherProfile.getProfiles().values()) { profileSelectPanel.addProfile(new LocalProfileComponent(application, workerExecutor, mojangApi, profile)); } } diff --git a/src/main/java/amidst/mojangapi/file/LauncherProfileService.java b/src/main/java/amidst/mojangapi/file/LauncherProfileService.java new file mode 100644 index 000000000..1db33bcf6 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/LauncherProfileService.java @@ -0,0 +1,52 @@ +package amidst.mojangapi.file; + +import java.io.File; +import java.io.FileNotFoundException; + +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.directory.ProfileDirectory; +import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; + +@Immutable +public class LauncherProfileService { + @NotNull + public ProfileDirectory createValidProfileDirectory(LauncherProfileJson launcherProfileJson, MojangApi mojangApi) + throws FileNotFoundException { + String gameDir = launcherProfileJson.getGameDir(); + if (gameDir != null) { + ProfileDirectory result = new ProfileDirectory(new File(gameDir)); + if (result.isValid()) { + return result; + } else { + throw new FileNotFoundException( + "cannot find valid profile directory for launcher profile '" + launcherProfileJson.getName() + + "': " + gameDir); + } + } else { + return new ProfileDirectory(mojangApi.getDotMinecraftDirectory().getRoot()); + } + } + + @NotNull + public VersionDirectory createValidVersionDirectory(LauncherProfileJson launcherProfileJson, MojangApi mojangApi) + throws FileNotFoundException { + String lastVersionId = launcherProfileJson.getLastVersionId(); + if (lastVersionId != null) { + VersionDirectory result = mojangApi.createVersionDirectory(lastVersionId); + if (result.isValid()) { + return result; + } + } else { + VersionDirectory result = new DotMinecraftDirectoryService() + .tryFindFirstValidVersionDirectory(launcherProfileJson.getAllowedReleaseTypes(), mojangApi); + if (result != null) { + return result; + } + } + throw new FileNotFoundException( + "cannot find valid version directory for launcher profile '" + launcherProfileJson.getName() + "'"); + } +} diff --git a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java index d779d84a1..e1ad22318 100644 --- a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java +++ b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfileJson.java @@ -1,17 +1,10 @@ package amidst.mojangapi.file.json.launcherprofiles; -import java.io.File; -import java.io.FileNotFoundException; import java.util.Arrays; import java.util.List; import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.DotMinecraftDirectoryService; -import amidst.mojangapi.file.directory.ProfileDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.ReleaseType; @Immutable @@ -48,35 +41,7 @@ public String getGameDir() { return gameDir; } - @NotNull - public ProfileDirectory createValidProfileDirectory(MojangApi mojangApi) throws FileNotFoundException { - if (gameDir != null) { - ProfileDirectory result = new ProfileDirectory(new File(gameDir)); - if (result.isValid()) { - return result; - } else { - throw new FileNotFoundException( - "cannot find valid profile directory for launcher profile '" + name + "': " + gameDir); - } - } else { - return new ProfileDirectory(mojangApi.getDotMinecraftDirectory().getRoot()); - } - } - - @NotNull - public VersionDirectory createValidVersionDirectory(MojangApi mojangApi) throws FileNotFoundException { - if (lastVersionId != null) { - VersionDirectory result = mojangApi.createVersionDirectory(lastVersionId); - if (result.isValid()) { - return result; - } - } else { - VersionDirectory result = new DotMinecraftDirectoryService() - .tryFindFirstValidVersionDirectory(allowedReleaseTypes, mojangApi); - if (result != null) { - return result; - } - } - throw new FileNotFoundException("cannot find valid version directory for launcher profile '" + name + "'"); + public List getAllowedReleaseTypes() { + return allowedReleaseTypes; } } diff --git a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfilesJson.java b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfilesJson.java index acfa402f8..0d9877245 100644 --- a/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfilesJson.java +++ b/src/main/java/amidst/mojangapi/file/json/launcherprofiles/LauncherProfilesJson.java @@ -1,6 +1,5 @@ package amidst.mojangapi.file.json.launcherprofiles; -import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -15,7 +14,7 @@ public class LauncherProfilesJson { public LauncherProfilesJson() { } - public Collection getProfiles() { - return profiles.values(); + public Map getProfiles() { + return profiles; } } From 80bbd6cb0dab301b37506dd8dad7c3580f3b4083 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sat, 27 May 2017 23:34:21 +0200 Subject: [PATCH 08/48] moved directory logic --- .../profileselect/ProfileSelectWindow.java | 4 +- src/main/java/amidst/mojangapi/MojangApi.java | 11 +- .../mojangapi/file/AmidstBackupService.java | 61 +++++++ .../mojangapi/file/ClassLoaderService.java | 64 +++++++ .../file/LauncherProfileService.java | 11 ++ .../mojangapi/file/SaveDirectoryService.java | 139 +++++++++++++++ .../file/directory/DotMinecraftDirectory.java | 10 -- .../directory/SaveAmidstBackupDirectory.java | 55 ------ .../file/directory/SaveDirectory.java | 161 ------------------ .../file/directory/VersionDirectory.java | 70 +------- .../file/nbt/player/LevelDatPlayerNbt.java | 6 +- .../file/nbt/player/PlayerdataPlayerNbt.java | 3 +- .../file/nbt/player/PlayersPlayerNbt.java | 3 +- .../local/LocalMinecraftInterface.java | 10 ++ .../local/LocalMinecraftInterfaceBuilder.java | 11 +- .../amidst/mojangapi/world/WorldBuilder.java | 3 +- .../world/player/WorldPlayerType.java | 10 +- .../GenerateRecognisedVersionList.java | 6 +- .../devtools/GenerateWorldTestData.java | 12 +- 19 files changed, 329 insertions(+), 321 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/AmidstBackupService.java create mode 100644 src/main/java/amidst/mojangapi/file/ClassLoaderService.java create mode 100644 src/main/java/amidst/mojangapi/file/SaveDirectoryService.java diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index 43c1a205b..f772aa823 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -20,6 +20,7 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.LauncherProfileService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; @@ -114,7 +115,8 @@ private void scanAndLoadProfilesLater() { @CalledOnlyBy(AmidstThread.WORKER) private LauncherProfilesJson scanAndLoadProfiles() throws MojangApiParsingException, IOException { AmidstLogger.info("Scanning for profiles."); - LauncherProfilesJson launcherProfile = mojangApi.getDotMinecraftDirectory().readLauncherProfilesJson(); + LauncherProfilesJson launcherProfile = new LauncherProfileService() + .readLauncherProfilesFrom(mojangApi.getDotMinecraftDirectory()); AmidstLogger.info("Successfully loaded profile list."); return launcherProfile; } diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index d703ccdaf..8023a9434 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -8,15 +8,17 @@ import amidst.documentation.ThreadSafe; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.SaveDirectoryService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; -import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; +import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; +import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.World; import amidst.mojangapi.world.WorldBuilder; @@ -68,7 +70,8 @@ public void set(String profileName, ProfileDirectory profileDirectory, VersionDi this.versionDirectory = versionDirectory; if (versionDirectory != null) { try { - this.minecraftInterface = versionDirectory.createLocalMinecraftInterface(); + this.minecraftInterface = LocalMinecraftInterface + .create(DefaultClassTranslator.INSTANCE.get(), versionDirectory, dotMinecraftDirectory); } catch (LocalMinecraftInterfaceCreationException e) { this.minecraftInterface = null; throw e; @@ -91,7 +94,7 @@ public VersionDirectory createVersionDirectory(File jar, File json) { } private VersionDirectory doCreateVersionDirectory(String versionId, File jar, File json) { - return new VersionDirectory(dotMinecraftDirectory, versionId, jar, json); + return new VersionDirectory(versionId, jar, json); } public MojangApi createSilentPlayerlessCopy() { @@ -148,7 +151,7 @@ public World createWorldFromSaveGame(File file) MojangApiParsingException { MinecraftInterface minecraftInterface = this.minecraftInterface; if (minecraftInterface != null) { - return worldBuilder.fromSaveGame(minecraftInterface, SaveDirectory.from(file)); + return worldBuilder.fromSaveGame(minecraftInterface, new SaveDirectoryService().from(file)); } else { throw new IllegalStateException("cannot create a world without a minecraft interface"); } diff --git a/src/main/java/amidst/mojangapi/file/AmidstBackupService.java b/src/main/java/amidst/mojangapi/file/AmidstBackupService.java new file mode 100644 index 000000000..6630642a0 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/AmidstBackupService.java @@ -0,0 +1,61 @@ +package amidst.mojangapi.file; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.sql.Timestamp; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.directory.SaveDirectory; + +@Immutable +public class AmidstBackupService { + public boolean tryBackupPlayersFile(SaveDirectory saveDirectory, String playerName) { + File toDirectory = saveDirectory.getAmidst().getBackup().getPlayers(); + File from = saveDirectory.getPlayersFile(playerName); + File to = new File(toDirectory, playerName + ".dat" + "_" + millis()); + return tryBackup(toDirectory, from, to); + } + + public boolean tryBackupPlayerdataFile(SaveDirectory saveDirectory, String playerUUID) { + File toDirectory = saveDirectory.getAmidst().getBackup().getPlayerdata(); + File from = saveDirectory.getPlayerdataFile(playerUUID); + File to = new File(toDirectory, playerUUID + ".dat" + "_" + millis()); + return tryBackup(toDirectory, from, to); + } + + public boolean tryBackupLevelDat(SaveDirectory saveDirectory) { + File toDirectory = saveDirectory.getAmidst().getBackup().getRoot(); + File from = saveDirectory.getLevelDat(); + File to = new File(toDirectory, "level.dat" + "_" + millis()); + return tryBackup(toDirectory, from, to); + } + + private String millis() { + return new Timestamp(System.currentTimeMillis()) + .toString() + .replace(" ", "_") + .replace(":", "-") + .replace(".", "_"); + } + + public boolean tryBackup(File toDirectory, File from, File to) { + return ensureDirectoryExists(toDirectory) && tryCopy(from, to) && to.isFile(); + } + + private boolean ensureDirectoryExists(File directory) { + if (!directory.exists()) { + directory.mkdirs(); + } + return directory.isDirectory(); + } + + private boolean tryCopy(File from, File to) { + try { + Files.copy(from.toPath(), to.toPath()); + return true; + } catch (IOException e) { + return false; + } + } +} diff --git a/src/main/java/amidst/mojangapi/file/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/ClassLoaderService.java new file mode 100644 index 000000000..35e4eec4b --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/ClassLoaderService.java @@ -0,0 +1,64 @@ +package amidst.mojangapi.file; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; + +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.directory.DotMinecraftDirectory; +import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.JsonReader; + +@Immutable +public class ClassLoaderService { + @NotNull + public URLClassLoader createClassLoader( + VersionDirectory versionDirectory, + DotMinecraftDirectory dotMinecraftDirectory) throws MalformedURLException { + if (versionDirectory.getJson().isFile()) { + AmidstLogger.info("Loading libraries."); + return doCreateClassLoader( + getJarFileUrl(versionDirectory), + getAllLibraryUrls(versionDirectory, dotMinecraftDirectory)); + } else { + AmidstLogger + .info("Unable to find Minecraft library JSON at: " + versionDirectory.getJson() + ". Skipping."); + return doCreateClassLoader(getJarFileUrl(versionDirectory)); + } + } + + @NotNull + private URLClassLoader doCreateClassLoader(URL jarFileUrl, List libraries) { + libraries.add(jarFileUrl); + return new URLClassLoader(libraries.toArray(new URL[libraries.size()])); + } + + @NotNull + private URLClassLoader doCreateClassLoader(URL jarFileUrl) { + return new URLClassLoader(new URL[] { jarFileUrl }); + } + + @NotNull + private URL getJarFileUrl(VersionDirectory versionDirectory) throws MalformedURLException { + return versionDirectory.getJar().toURI().toURL(); + } + + private List getAllLibraryUrls( + VersionDirectory versionDirectory, + DotMinecraftDirectory dotMinecraftDirectory) { + File json = versionDirectory.getJson(); + try { + return new LibraryService() + .getLibraryUrls(dotMinecraftDirectory.getLibraries(), JsonReader.readVersionFrom(json)); + } catch (IOException | MojangApiParsingException e) { + AmidstLogger.warn("Invalid jar profile loaded. Library loading will be skipped. (Path: " + json + ")"); + return new ArrayList<>(); + } + } +} diff --git a/src/main/java/amidst/mojangapi/file/LauncherProfileService.java b/src/main/java/amidst/mojangapi/file/LauncherProfileService.java index 1db33bcf6..747f6f8e5 100644 --- a/src/main/java/amidst/mojangapi/file/LauncherProfileService.java +++ b/src/main/java/amidst/mojangapi/file/LauncherProfileService.java @@ -2,13 +2,17 @@ import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; +import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; @Immutable public class LauncherProfileService { @@ -49,4 +53,11 @@ public VersionDirectory createValidVersionDirectory(LauncherProfileJson launcher throw new FileNotFoundException( "cannot find valid version directory for launcher profile '" + launcherProfileJson.getName() + "'"); } + + @NotNull + public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMinecraftDirectory) + throws MojangApiParsingException, + IOException { + return JsonReader.readLauncherProfilesFrom(dotMinecraftDirectory.getLauncherProfilesJson()); + } } diff --git a/src/main/java/amidst/mojangapi/file/SaveDirectoryService.java b/src/main/java/amidst/mojangapi/file/SaveDirectoryService.java new file mode 100644 index 000000000..0ecaa171f --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/SaveDirectoryService.java @@ -0,0 +1,139 @@ +package amidst.mojangapi.file; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.directory.SaveDirectory; +import amidst.mojangapi.file.nbt.LevelDatNbt; +import amidst.mojangapi.file.nbt.NBTUtils; +import amidst.mojangapi.file.nbt.player.LevelDatPlayerNbt; +import amidst.mojangapi.file.nbt.player.PlayerNbt; +import amidst.mojangapi.file.nbt.player.PlayerdataPlayerNbt; +import amidst.mojangapi.file.nbt.player.PlayersPlayerNbt; + +@Immutable +public class SaveDirectoryService { + /** + * Returns a new valid instance of the class SaveDirectory. It tries to use + * the given file. If that is not valid it tires to use its parent file. If + * that is also not valid it will throw a FileNotFoundException. + */ + @NotNull + public SaveDirectory from(File file) throws FileNotFoundException { + File currentFile = file; + SaveDirectory result = null; + if (currentFile == null) { + // error + } else { + result = createValidSaveDirectory(currentFile); + currentFile = currentFile.getParentFile(); + if (result != null) { + return result; + } else if (currentFile == null) { + // error + } else { + result = createValidSaveDirectory(currentFile); + currentFile = currentFile.getParentFile(); + if (result != null) { + return result; + } else { + // error + } + } + } + throw new FileNotFoundException("unable to load save directory: " + file); + } + + private SaveDirectory createValidSaveDirectory(File currentFile) { + SaveDirectory result = new SaveDirectory(currentFile); + if (result.isValid()) { + return result; + } else { + return null; + } + } + + public LevelDatNbt createLevelDat(SaveDirectory saveDirectory) throws IOException, MojangApiParsingException { + return new LevelDatNbt(NBTUtils.readTagFromFile(saveDirectory.getLevelDat())); + } + + /** + * We need to let the user decide if he wants to load the singleplayer + * player from the level.dat file or if he wants to load the multiplayer + * players. That is, because a singleplayer map will have the playerdata + * directory. It contains information about each player that ever played on + * the map. However, if the map is loaded as singleplayer map, minecraft + * will use the information that is stored in the level.dat file. It will + * also overwrite the file in the playerdata directory that belongs to the + * player that loaded the map in singleplayer mode. So, if we change the + * player location in the playerdata directory it will just be ignored if + * the map is used as singleplayer map. + */ + @NotNull + public List createSingleplayerPlayerNbts(SaveDirectory saveDirectory) { + AmidstLogger.info("using player from level.dat"); + return Arrays.asList(new LevelDatPlayerNbt(saveDirectory)); + } + + /** + * Since version 1.7.6, minecraft stores players in the playerdata directory + * and uses the player uuid as filename. + */ + @NotNull + public List createMultiplayerPlayerNbts(SaveDirectory saveDirectory) { + List result = new ArrayList<>(); + for (File playerdataFile : getPlayerdataFiles(saveDirectory)) { + if (playerdataFile.isFile()) { + result.add(new PlayerdataPlayerNbt(saveDirectory, getPlayerUUIDFromPlayerdataFile(playerdataFile))); + } + } + if (!result.isEmpty()) { + AmidstLogger.info("using players from the playerdata directory"); + return result; + } + for (File playersFile : getPlayersFiles(saveDirectory)) { + if (playersFile.isFile()) { + result.add(new PlayersPlayerNbt(saveDirectory, getPlayerNameFromPlayersFile(playersFile))); + } + } + if (!result.isEmpty()) { + AmidstLogger.info("using players from the players directory"); + return result; + } + AmidstLogger.info("no multiplayer players found"); + return result; + } + + private File[] getPlayerdataFiles(SaveDirectory saveDirectory) { + File[] files = saveDirectory.getPlayerdata().listFiles(); + if (files == null) { + return new File[0]; + } else { + return files; + } + } + + private File[] getPlayersFiles(SaveDirectory saveDirectory) { + File[] files = saveDirectory.getPlayers().listFiles(); + if (files == null) { + return new File[0]; + } else { + return files; + } + } + + private String getPlayerUUIDFromPlayerdataFile(File playerdataFile) { + return playerdataFile.getName().split("\\.")[0]; + } + + private String getPlayerNameFromPlayersFile(File playersFile) { + return playersFile.getName().split("\\.")[0]; + } +} diff --git a/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java b/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java index 057e57731..157f05c9a 100644 --- a/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java @@ -1,13 +1,8 @@ package amidst.mojangapi.file.directory; import java.io.File; -import java.io.IOException; import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.JsonReader; -import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; @Immutable public class DotMinecraftDirectory { @@ -56,9 +51,4 @@ public File getVersions() { public File getLauncherProfilesJson() { return launcherProfilesJson; } - - @NotNull - public LauncherProfilesJson readLauncherProfilesJson() throws MojangApiParsingException, IOException { - return JsonReader.readLauncherProfilesFrom(launcherProfilesJson); - } } diff --git a/src/main/java/amidst/mojangapi/file/directory/SaveAmidstBackupDirectory.java b/src/main/java/amidst/mojangapi/file/directory/SaveAmidstBackupDirectory.java index cb1c6d25d..d638411be 100644 --- a/src/main/java/amidst/mojangapi/file/directory/SaveAmidstBackupDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/SaveAmidstBackupDirectory.java @@ -1,9 +1,6 @@ package amidst.mojangapi.file.directory; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.sql.Timestamp; public class SaveAmidstBackupDirectory { private final File root; @@ -27,56 +24,4 @@ public File getPlayers() { public File getPlayerdata() { return playerdata; } - - public File getPlayersFile(String playerName) { - return new File(players, playerName + ".dat" + "_" + millis()); - } - - public File getPlayerdataFile(String playerUUID) { - return new File(playerdata, playerUUID + ".dat" + "_" + millis()); - } - - public File getLevelDat() { - return new File(root, "level.dat" + "_" + millis()); - } - - private String millis() { - return new Timestamp(System.currentTimeMillis()) - .toString() - .replace(" ", "_") - .replace(":", "-") - .replace(".", "_"); - } - - public boolean tryBackupPlayersFile(File from, String playerName) { - return tryBackup(players, from, getPlayersFile(playerName)); - } - - public boolean tryBackupPlayerdataFile(File from, String playerUUID) { - return tryBackup(playerdata, from, getPlayerdataFile(playerUUID)); - } - - public boolean tryBackupLevelDat(File from) { - return tryBackup(root, from, getLevelDat()); - } - - private boolean tryBackup(File toDirectory, File from, File to) { - return ensureDirectoryExists(toDirectory) && tryCopy(from, to) && to.isFile(); - } - - private boolean ensureDirectoryExists(File directory) { - if (!directory.exists()) { - directory.mkdirs(); - } - return directory.isDirectory(); - } - - private boolean tryCopy(File from, File to) { - try { - Files.copy(from.toPath(), to.toPath()); - return true; - } catch (IOException e) { - return false; - } - } } diff --git a/src/main/java/amidst/mojangapi/file/directory/SaveDirectory.java b/src/main/java/amidst/mojangapi/file/directory/SaveDirectory.java index 3c64f853a..e3c684617 100644 --- a/src/main/java/amidst/mojangapi/file/directory/SaveDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/SaveDirectory.java @@ -1,67 +1,11 @@ package amidst.mojangapi.file.directory; import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.jnbt.CompoundTag; import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.nbt.LevelDatNbt; -import amidst.mojangapi.file.nbt.NBTUtils; -import amidst.mojangapi.file.nbt.player.LevelDatPlayerNbt; -import amidst.mojangapi.file.nbt.player.PlayerNbt; -import amidst.mojangapi.file.nbt.player.PlayerdataPlayerNbt; -import amidst.mojangapi.file.nbt.player.PlayersPlayerNbt; @Immutable public class SaveDirectory { - /** - * Returns a new valid instance of the class SaveDirectory. It tries to use - * the given file. If that is not valid it tires to use its parent file. If - * that is also not valid it will throw a FileNotFoundException. - */ - @NotNull - public static SaveDirectory from(File file) throws FileNotFoundException { - File currentFile = file; - SaveDirectory result = null; - if (currentFile == null) { - // error - } else { - result = createValidSaveDirectory(currentFile); - currentFile = currentFile.getParentFile(); - if (result != null) { - return result; - } else if (currentFile == null) { - // error - } else { - result = createValidSaveDirectory(currentFile); - currentFile = currentFile.getParentFile(); - if (result != null) { - return result; - } else { - // error - } - } - } - throw new FileNotFoundException("unable to load save directory: " + file); - } - - private static SaveDirectory createValidSaveDirectory(File currentFile) { - SaveDirectory result = new SaveDirectory(currentFile); - if (result.isValid()) { - return result; - } else { - return null; - } - } - private final File root; private final SaveAmidstDirectory amidst; private final File players; @@ -111,109 +55,4 @@ public File getPlayersFile(String playerName) { public File getPlayerdataFile(String playerUUID) { return new File(playerdata, playerUUID + ".dat"); } - - public File[] getPlayersFiles() { - File[] files = players.listFiles(); - if (files == null) { - return new File[0]; - } else { - return files; - } - } - - public File[] getPlayerdataFiles() { - File[] files = playerdata.listFiles(); - if (files == null) { - return new File[0]; - } else { - return files; - } - } - - public CompoundTag readLevelDat() throws IOException { - return NBTUtils.readTagFromFile(levelDat); - } - - public LevelDatNbt createLevelDat() throws IOException, MojangApiParsingException { - return new LevelDatNbt(readLevelDat()); - } - - public boolean tryBackupPlayersFile(String playerName) { - return amidst.getBackup().tryBackupPlayersFile(getPlayersFile(playerName), playerName); - } - - public boolean tryBackupPlayerdataFile(String playerUUID) { - return amidst.getBackup().tryBackupPlayerdataFile(getPlayerdataFile(playerUUID), playerUUID); - } - - public boolean tryBackupLevelDat() { - return amidst.getBackup().tryBackupLevelDat(getLevelDat()); - } - - /** - * Since version 1.7.6, minecraft stores players in the playerdata directory - * and uses the player uuid as filename. - */ - @NotNull - public List createMultiplayerPlayerNbts() { - List result = new ArrayList<>(); - for (File playerdataFile : getPlayerdataFiles()) { - if (playerdataFile.isFile()) { - result.add(createPlayerdataPlayerNbt(getPlayerUUIDFromPlayerdataFile(playerdataFile))); - } - } - if (!result.isEmpty()) { - AmidstLogger.info("using players from the playerdata directory"); - return result; - } - for (File playersFile : getPlayersFiles()) { - if (playersFile.isFile()) { - result.add(createPlayersPlayerNbt(getPlayerNameFromPlayersFile(playersFile))); - } - } - if (!result.isEmpty()) { - AmidstLogger.info("using players from the players directory"); - return result; - } - AmidstLogger.info("no multiplayer players found"); - return result; - } - - /** - * We need to let the user decide if he wants to load the singleplayer - * player from the level.dat file or if he wants to load the multiplayer - * players. That is, because a singleplayer map will have the playerdata - * directory. It contains information about each player that ever played on - * the map. However, if the map is loaded as singleplayer map, minecraft - * will use the information that is stored in the level.dat file. It will - * also overwrite the file in the playerdata directory that belongs to the - * player that loaded the map in singleplayer mode. So, if we change the - * player location in the playerdata directory it will just be ignored if - * the map is used as singleplayer map. - */ - @NotNull - public List createSingleplayerPlayerNbts() { - AmidstLogger.info("using player from level.dat"); - return Arrays.asList(createLevelDatPlayerNbt()); - } - - private PlayerNbt createLevelDatPlayerNbt() { - return new LevelDatPlayerNbt(this); - } - - private PlayerNbt createPlayerdataPlayerNbt(String playerUUID) { - return new PlayerdataPlayerNbt(this, playerUUID); - } - - private PlayerNbt createPlayersPlayerNbt(String playerName) { - return new PlayersPlayerNbt(this, playerName); - } - - private String getPlayerUUIDFromPlayerdataFile(File playerdataFile) { - return playerdataFile.getName().split("\\.")[0]; - } - - private String getPlayerNameFromPlayersFile(File playersFile) { - return playersFile.getName().split("\\.")[0]; - } } diff --git a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java index 37a527a33..d6dd48f88 100644 --- a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java @@ -1,37 +1,16 @@ package amidst.mojangapi.file.directory; import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.LibraryService; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.JsonReader; -import amidst.mojangapi.file.json.version.VersionJson; -import amidst.mojangapi.minecraftinterface.MinecraftInterface; -import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; -import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceBuilder; -import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; @Immutable public class VersionDirectory { - private static final LocalMinecraftInterfaceBuilder LOCAL_MINECRAFT_INTERFACE_BUILDER = new LocalMinecraftInterfaceBuilder( - DefaultClassTranslator.INSTANCE.get()); - - private final DotMinecraftDirectory dotMinecraftDirectory; private final String versionId; private final File jar; private final File json; - public VersionDirectory(DotMinecraftDirectory dotMinecraftDirectory, String versionId, File jar, File json) { - this.dotMinecraftDirectory = dotMinecraftDirectory; + public VersionDirectory(String versionId, File jar, File json) { this.versionId = versionId; this.jar = jar; this.json = json; @@ -52,51 +31,4 @@ public File getJar() { public File getJson() { return json; } - - @NotNull - public VersionJson readVersionJson() throws MojangApiParsingException, IOException { - return JsonReader.readVersionFrom(json); - } - - @NotNull - public URLClassLoader createClassLoader() throws MalformedURLException { - if (json.isFile()) { - AmidstLogger.info("Loading libraries."); - return doCreateClassLoader(getJarFileUrl(), getAllLibraryUrls()); - } else { - AmidstLogger.info("Unable to find Minecraft library JSON at: " + json + ". Skipping."); - return doCreateClassLoader(getJarFileUrl()); - } - } - - @NotNull - private URL getJarFileUrl() throws MalformedURLException { - return jar.toURI().toURL(); - } - - @NotNull - private List getAllLibraryUrls() { - try { - return new LibraryService().getLibraryUrls(dotMinecraftDirectory.getLibraries(), readVersionJson()); - } catch (IOException | MojangApiParsingException e) { - AmidstLogger.warn("Invalid jar profile loaded. Library loading will be skipped. (Path: " + json + ")"); - return new ArrayList<>(); - } - } - - @NotNull - private URLClassLoader doCreateClassLoader(URL jarFileUrl, List libraries) { - libraries.add(jarFileUrl); - return new URLClassLoader(libraries.toArray(new URL[libraries.size()])); - } - - @NotNull - private URLClassLoader doCreateClassLoader(URL jarFileUrl) { - return new URLClassLoader(new URL[] { jarFileUrl }); - } - - @NotNull - public MinecraftInterface createLocalMinecraftInterface() throws LocalMinecraftInterfaceCreationException { - return LOCAL_MINECRAFT_INTERFACE_BUILDER.create(this); - } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java index a743958a6..9eb039ac7 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java @@ -3,8 +3,10 @@ import java.io.IOException; import amidst.documentation.Immutable; +import amidst.mojangapi.file.AmidstBackupService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; +import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; import amidst.mojangapi.world.player.PlayerInformation; @@ -20,7 +22,7 @@ public LevelDatPlayerNbt(SaveDirectory saveDirectory) { @Override protected boolean tryBackup() { - return saveDirectory.tryBackupLevelDat(); + return new AmidstBackupService().tryBackupLevelDat(saveDirectory); } @Override @@ -30,7 +32,7 @@ protected void doWriteCoordinates(PlayerCoordinates coordinates) throws MojangAp @Override public PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingException { - return PlayerLocationLoader.readFromLevelDat(saveDirectory.readLevelDat()); + return PlayerLocationLoader.readFromLevelDat(NBTUtils.readTagFromFile(saveDirectory.getLevelDat())); } @Override diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java index f02be21dd..6c58ffe5f 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java @@ -3,6 +3,7 @@ import java.io.IOException; import amidst.documentation.Immutable; +import amidst.mojangapi.file.AmidstBackupService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; @@ -22,7 +23,7 @@ public PlayerdataPlayerNbt(SaveDirectory saveDirectory, String playerUUID) { @Override protected boolean tryBackup() { - return saveDirectory.tryBackupPlayerdataFile(playerUUID); + return new AmidstBackupService().tryBackupPlayerdataFile(saveDirectory, playerUUID); } @Override diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java index 53c7cede9..7084970ca 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java @@ -3,6 +3,7 @@ import java.io.IOException; import amidst.documentation.Immutable; +import amidst.mojangapi.file.AmidstBackupService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; @@ -22,7 +23,7 @@ public PlayersPlayerNbt(SaveDirectory saveDirectory, String playerName) { @Override protected boolean tryBackup() { - return saveDirectory.tryBackupPlayersFile(playerName); + return new AmidstBackupService().tryBackupPlayersFile(saveDirectory, playerName); } @Override diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java index 30116410f..072f86f75 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java @@ -4,8 +4,11 @@ import amidst.clazz.symbolic.SymbolicClass; import amidst.clazz.symbolic.SymbolicObject; +import amidst.clazz.translator.ClassTranslator; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.directory.DotMinecraftDirectory; +import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -13,6 +16,13 @@ @ThreadSafe public class LocalMinecraftInterface implements MinecraftInterface { + public static LocalMinecraftInterface create( + ClassTranslator translator, + VersionDirectory versionDirectory, + DotMinecraftDirectory dotMinecraftDirectory) throws LocalMinecraftInterfaceCreationException { + return new LocalMinecraftInterfaceBuilder(translator).create(versionDirectory, dotMinecraftDirectory); + } + /** * A GenLayer instance, at quarter scale to the final biome layer (i.e. both * axis are divided by 4). Minecraft calculates biomes at diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java index 011997c5f..5dc66f977 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java @@ -13,8 +13,9 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.ClassLoaderService; +import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @Immutable @@ -26,10 +27,12 @@ public LocalMinecraftInterfaceBuilder(ClassTranslator translator) { } @NotNull - public MinecraftInterface create(VersionDirectory versionDirectory) - throws LocalMinecraftInterfaceCreationException { + public LocalMinecraftInterface create( + VersionDirectory versionDirectory, + DotMinecraftDirectory dotMinecraftDirectory) throws LocalMinecraftInterfaceCreationException { try { - URLClassLoader classLoader = versionDirectory.createClassLoader(); + URLClassLoader classLoader = new ClassLoaderService() + .createClassLoader(versionDirectory, dotMinecraftDirectory); RecognisedVersion recognisedVersion = RecognisedVersion.from(classLoader); Map symbolicClassMap = Classes .createSymbolicClassMap(versionDirectory.getJar(), classLoader, translator); diff --git a/src/main/java/amidst/mojangapi/world/WorldBuilder.java b/src/main/java/amidst/mojangapi/world/WorldBuilder.java index 9e2505e05..282cd2104 100644 --- a/src/main/java/amidst/mojangapi/world/WorldBuilder.java +++ b/src/main/java/amidst/mojangapi/world/WorldBuilder.java @@ -4,6 +4,7 @@ import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.SaveDirectoryService; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.LevelDatNbt; import amidst.mojangapi.minecraftinterface.MinecraftInterface; @@ -78,7 +79,7 @@ public World fromSaveGame(MinecraftInterface minecraftInterface, SaveDirectory s MinecraftInterfaceException, MojangApiParsingException { VersionFeatures versionFeatures = DefaultVersionFeatures.create(minecraftInterface.getRecognisedVersion()); - LevelDatNbt levelDat = saveDirectory.createLevelDat(); + LevelDatNbt levelDat = new SaveDirectoryService().createLevelDat(saveDirectory); MovablePlayerList movablePlayerList = new MovablePlayerList( playerInformationCache, saveDirectory, diff --git a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java index 222416708..413d060f6 100644 --- a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java +++ b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java @@ -7,6 +7,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; +import amidst.mojangapi.file.SaveDirectoryService; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.LevelDatNbt; import amidst.mojangapi.file.nbt.player.PlayerNbt; @@ -52,15 +53,16 @@ public String getName() { @NotNull public List createPlayerNbts(SaveDirectory saveDirectory) { + SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); if (this == BOTH) { List result = new ArrayList<>(); - result.addAll(saveDirectory.createSingleplayerPlayerNbts()); - result.addAll(saveDirectory.createMultiplayerPlayerNbts()); + result.addAll(saveDirectoryService.createSingleplayerPlayerNbts(saveDirectory)); + result.addAll(saveDirectoryService.createMultiplayerPlayerNbts(saveDirectory)); return result; } else if (this == SINGLEPLAYER) { - return saveDirectory.createSingleplayerPlayerNbts(); + return saveDirectoryService.createSingleplayerPlayerNbts(saveDirectory); } else if (this == MULTIPLAYER) { - return saveDirectory.createMultiplayerPlayerNbts(); + return saveDirectoryService.createMultiplayerPlayerNbts(saveDirectory); } else { return Collections.emptyList(); } diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 194b08cad..6b747a254 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -8,6 +8,7 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.ClassLoaderService; import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; @@ -61,7 +62,8 @@ private void process(VersionListEntryJson version) { private void process(String versionId) throws MalformedURLException, ClassNotFoundException { AmidstLogger.info("version " + versionId); VersionDirectory versionDirectory = createVersionDirectory(versionId); - URLClassLoader classLoader = versionDirectory.createClassLoader(); + URLClassLoader classLoader = new ClassLoaderService() + .createClassLoader(versionDirectory, dotMinecraftDirectory); String magicString = RecognisedVersion.generateMagicString(classLoader); builder.addLauncherVersionId(versionId, magicString); } @@ -70,7 +72,7 @@ private VersionDirectory createVersionDirectory(String versionId) { FilenameService filenameService = new FilenameService(); File jar = filenameService.getClientJarFile(versions, versionId); File json = filenameService.getClientJsonFile(versions, versionId); - return new VersionDirectory(dotMinecraftDirectory, versionId, jar, json); + return new VersionDirectory(versionId, jar, json); } private void print() { diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index f4216ce77..764f7a8ad 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -5,6 +5,7 @@ import java.util.LinkedList; import java.util.List; +import amidst.clazz.translator.ClassTranslator; import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; @@ -13,15 +14,12 @@ import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; -import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceBuilder; +import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.testworld.TestWorldCache; import amidst.mojangapi.world.testworld.TestWorldDeclaration; public class GenerateWorldTestData { - private static final LocalMinecraftInterfaceBuilder LOCAL_MINECRAFT_INTERFACE_BUILDER = new LocalMinecraftInterfaceBuilder( - DefaultClassTranslator.INSTANCE.get()); - private final String prefix; private final File libraries; private final VersionListJson versionList; @@ -54,9 +52,11 @@ private void generate(TestWorldDeclaration declaration, VersionListEntryJson ver String versionId = version.getId(); if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { try { + ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); + VersionDirectory versionDirectory = createVersionDirectory(versionId); TestWorldCache.createAndPut( declaration, - LOCAL_MINECRAFT_INTERFACE_BUILDER.create(createVersionDirectory(versionId))); + LocalMinecraftInterface.create(translator, versionDirectory, dotMinecraftDirectory)); successful.add(versionId); } catch (LocalMinecraftInterfaceCreationException | MinecraftInterfaceException | IOException e) { e.printStackTrace(); @@ -71,7 +71,7 @@ private VersionDirectory createVersionDirectory(String versionId) { FilenameService filenameService = new FilenameService(); File jar = filenameService.getClientJarFile(versions, versionId); File json = filenameService.getClientJsonFile(versions, versionId); - return new VersionDirectory(dotMinecraftDirectory, versionId, jar, json); + return new VersionDirectory(versionId, jar, json); } private void print(String title, Iterable lines) { From 1e24538c54e15484dc607a797d087493697893ff Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 01:39:31 +0200 Subject: [PATCH 09/48] renamed DotMinecraftDirectoryService to DownloadService --- ...ctoryService.java => DownloadService.java} | 24 +------------------ .../file/LauncherProfileService.java | 22 +++++++++++++++-- .../GenerateRecognisedVersionList.java | 4 ++-- .../devtools/GenerateWorldTestData.java | 4 ++-- ...necraftJarDownloadAvailabilityChecker.java | 8 +++---- .../devtools/MinecraftJarDownloader.java | 8 +++---- .../MinecraftVersionCompatibilityChecker.java | 4 ++-- 7 files changed, 35 insertions(+), 39 deletions(-) rename src/main/java/amidst/mojangapi/file/{DotMinecraftDirectoryService.java => DownloadService.java} (66%) diff --git a/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/DownloadService.java similarity index 66% rename from src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java rename to src/main/java/amidst/mojangapi/file/DownloadService.java index 7c9d7336a..5017631a8 100644 --- a/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/DownloadService.java @@ -1,37 +1,15 @@ package amidst.mojangapi.file; -import java.io.FileNotFoundException; import java.io.IOException; -import java.util.List; import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; -import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; @Immutable -public class DotMinecraftDirectoryService { +public class DownloadService { private final FilenameService filenameService = new FilenameService(); - public VersionDirectory tryFindFirstValidVersionDirectory( - List allowedReleaseTypes, - MojangApi mojangApi) throws FileNotFoundException { - VersionListJson versionListJson = mojangApi.getVersionList(); - - for (VersionListEntryJson version : versionListJson.getVersions()) { - if (allowedReleaseTypes.contains(version.getType())) { - VersionDirectory versionDirectory = mojangApi.createVersionDirectory(version.getId()); - if (versionDirectory.isValid()) { - return versionDirectory; - } - } - } - return null; - } - public boolean hasServer(VersionListEntryJson version) { return URIUtils.exists(filenameService.getRemoteServerJar(version.getId())); } diff --git a/src/main/java/amidst/mojangapi/file/LauncherProfileService.java b/src/main/java/amidst/mojangapi/file/LauncherProfileService.java index 747f6f8e5..28df517d8 100644 --- a/src/main/java/amidst/mojangapi/file/LauncherProfileService.java +++ b/src/main/java/amidst/mojangapi/file/LauncherProfileService.java @@ -3,6 +3,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.List; import amidst.documentation.Immutable; import amidst.documentation.NotNull; @@ -11,8 +12,10 @@ import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.JsonReader; +import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; +import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; @Immutable public class LauncherProfileService { @@ -44,8 +47,9 @@ public VersionDirectory createValidVersionDirectory(LauncherProfileJson launcher return result; } } else { - VersionDirectory result = new DotMinecraftDirectoryService() - .tryFindFirstValidVersionDirectory(launcherProfileJson.getAllowedReleaseTypes(), mojangApi); + VersionDirectory result = tryFindFirstValidVersionDirectory( + launcherProfileJson.getAllowedReleaseTypes(), + mojangApi); if (result != null) { return result; } @@ -54,6 +58,20 @@ public VersionDirectory createValidVersionDirectory(LauncherProfileJson launcher "cannot find valid version directory for launcher profile '" + launcherProfileJson.getName() + "'"); } + private VersionDirectory tryFindFirstValidVersionDirectory( + List allowedReleaseTypes, + MojangApi mojangApi) throws FileNotFoundException { + for (VersionListEntryJson version : mojangApi.getVersionList().getVersions()) { + if (allowedReleaseTypes.contains(version.getType())) { + VersionDirectory versionDirectory = mojangApi.createVersionDirectory(version.getId()); + if (versionDirectory.isValid()) { + return versionDirectory; + } + } + } + return null; + } + @NotNull public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMinecraftDirectory) throws MojangApiParsingException, diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 6b747a254..f4bf110cf 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -9,7 +9,7 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.ClassLoaderService; -import amidst.mojangapi.file.DotMinecraftDirectoryService; +import amidst.mojangapi.file.DownloadService; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; @@ -47,7 +47,7 @@ private void populate() { private void process(VersionListEntryJson version) { String versionId = version.getId(); - if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { + if (new DownloadService().tryDownloadClient(prefix, version)) { try { process(versionId); } catch (ClassNotFoundException | MalformedURLException | NoClassDefFoundError e) { diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 764f7a8ad..5868a68e4 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -6,7 +6,7 @@ import java.util.List; import amidst.clazz.translator.ClassTranslator; -import amidst.mojangapi.file.DotMinecraftDirectoryService; +import amidst.mojangapi.file.DownloadService; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; @@ -50,7 +50,7 @@ public void run() { private void generate(TestWorldDeclaration declaration, VersionListEntryJson version) { String versionId = version.getId(); - if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { + if (new DownloadService().tryDownloadClient(prefix, version)) { try { ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); VersionDirectory versionDirectory = createVersionDirectory(versionId); diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java index 236620768..df141c8af 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java @@ -1,7 +1,7 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.DotMinecraftDirectoryService; +import amidst.mojangapi.file.DownloadService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; @@ -14,10 +14,10 @@ public MinecraftJarDownloadAvailabilityChecker(VersionListJson versionList) { } public void run() { - DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); + DownloadService downloadService = new DownloadService(); for (VersionListEntryJson version : versionList.getVersions()) { - boolean hasServer = dotMinecraftDirectoryService.hasServer(version); - boolean hasClient = dotMinecraftDirectoryService.hasClient(version); + boolean hasServer = downloadService.hasServer(version); + boolean hasClient = downloadService.hasClient(version); System.out.println(renderer.render(version, hasServer, hasClient)); } } diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloader.java b/src/test/java/amidst/devtools/MinecraftJarDownloader.java index bfb2eeb9b..3f57dc185 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloader.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloader.java @@ -1,7 +1,7 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.DotMinecraftDirectoryService; +import amidst.mojangapi.file.DownloadService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; @@ -16,10 +16,10 @@ public MinecraftJarDownloader(String prefix, VersionListJson versionList) { } public void run() { - DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); + DownloadService downloadService = new DownloadService(); for (VersionListEntryJson version : versionList.getVersions()) { - boolean hasServer = dotMinecraftDirectoryService.tryDownloadServer(prefix, version); - boolean hasClient = dotMinecraftDirectoryService.tryDownloadClient(prefix, version); + boolean hasServer = downloadService.tryDownloadServer(prefix, version); + boolean hasClient = downloadService.tryDownloadClient(prefix, version); System.out.println(renderer.render(version, hasServer, hasClient)); } } diff --git a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java index 57a7fc5fc..6a587bd95 100644 --- a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java @@ -11,7 +11,7 @@ import amidst.clazz.real.JarFileParsingException; import amidst.clazz.symbolic.declaration.SymbolicClassDeclaration; import amidst.clazz.translator.ClassTranslator; -import amidst.mojangapi.file.DotMinecraftDirectoryService; +import amidst.mojangapi.file.DownloadService; import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; @@ -47,7 +47,7 @@ public void run() { } private boolean checkOne(VersionListEntryJson version) { - if (new DotMinecraftDirectoryService().tryDownloadClient(prefix, version)) { + if (new DownloadService().tryDownloadClient(prefix, version)) { try { File jarFile = new File(new FilenameService().getClientJar(prefix, version.getId())); ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); From cef9b7ec5662b0a3f4331f78043505dcd3ac27ad Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 01:57:23 +0200 Subject: [PATCH 10/48] merged LibraryFinder into LibraryService --- .../mojangapi/file/ClassLoaderService.java | 5 +- .../amidst/mojangapi/file/LibraryFinder.java | 103 ------------------ .../amidst/mojangapi/file/LibraryService.java | 99 +++++++++++++++-- 3 files changed, 94 insertions(+), 113 deletions(-) delete mode 100644 src/main/java/amidst/mojangapi/file/LibraryFinder.java diff --git a/src/main/java/amidst/mojangapi/file/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/ClassLoaderService.java index 35e4eec4b..eae920b11 100644 --- a/src/main/java/amidst/mojangapi/file/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/ClassLoaderService.java @@ -54,8 +54,9 @@ private List getAllLibraryUrls( DotMinecraftDirectory dotMinecraftDirectory) { File json = versionDirectory.getJson(); try { - return new LibraryService() - .getLibraryUrls(dotMinecraftDirectory.getLibraries(), JsonReader.readVersionFrom(json)); + return new LibraryService().getLibraryUrls( + dotMinecraftDirectory.getLibraries(), + JsonReader.readVersionFrom(json).getLibraries()); } catch (IOException | MojangApiParsingException e) { AmidstLogger.warn("Invalid jar profile loaded. Library loading will be skipped. (Path: " + json + ")"); return new ArrayList<>(); diff --git a/src/main/java/amidst/mojangapi/file/LibraryFinder.java b/src/main/java/amidst/mojangapi/file/LibraryFinder.java deleted file mode 100644 index 197dbfc0d..000000000 --- a/src/main/java/amidst/mojangapi/file/LibraryFinder.java +++ /dev/null @@ -1,103 +0,0 @@ -package amidst.mojangapi.file; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.json.version.LibraryJson; -import amidst.util.OperatingSystemDetector; - -@Immutable -public enum LibraryFinder { - ; - - @NotNull - public static List getLibraryUrls(File librariesDirectory, List libraries) { - List result = new ArrayList<>(); - for (LibraryJson library : libraries) { - File libraryFile = getLibraryFile(librariesDirectory, library); - if (libraryFile != null) { - try { - result.add(libraryFile.toURI().toURL()); - AmidstLogger.info("Found library: " + libraryFile); - } catch (MalformedURLException e) { - AmidstLogger.warn(e, "Unable to convert library file to URL: " + libraryFile); - } - } else { - AmidstLogger.info("Skipping library: " + library.getName()); - } - } - return result; - } - - private static File getLibraryFile(File librariesDirectory, LibraryJson library) { - try { - if (new LibraryService().isLibraryActive(library, getOs(), OperatingSystemDetector.getVersion())) { - return getLibraryFile(getLibrarySearchPath(librariesDirectory, library.getName())); - } else { - return null; - } - } catch (NullPointerException e) { - return null; - } - } - - private static String getOs() { - if (OperatingSystemDetector.isWindows()) { - return "windows"; - } else if (OperatingSystemDetector.isMac()) { - return "osx"; - } else { - return "linux"; - } - } - - private static File getLibrarySearchPath(File librariesDirectory, String libraryName) { - String result = librariesDirectory.getAbsolutePath() + "/"; - String[] split = libraryName.split(":"); - split[0] = split[0].replace('.', '/'); - for (String element : split) { - result += element + "/"; - } - return new File(result); - } - - private static File getLibraryFile(File librarySearchPath) { - if (librarySearchPath.exists()) { - File result = getFirstFileWithExtension(librarySearchPath.listFiles(), "jar"); - if (result != null && result.exists()) { - return result; - } else { - AmidstLogger.warn( - "Attempted to search for file at path: " + librarySearchPath + " but found nothing. Skipping."); - return null; - } - } else { - AmidstLogger.warn("Failed attempt to load library at: " + librarySearchPath); - return null; - } - } - - private static File getFirstFileWithExtension(File[] files, String extension) { - for (File libraryFile : files) { - if (getFileExtension(libraryFile.getName()).equals(extension)) { - return libraryFile; - } - } - return null; - } - - private static String getFileExtension(String fileName) { - String extension = ""; - int q = fileName.lastIndexOf('.'); - if (q > 0) { - extension = fileName.substring(q + 1); - } - return extension; - } -} diff --git a/src/main/java/amidst/mojangapi/file/LibraryService.java b/src/main/java/amidst/mojangapi/file/LibraryService.java index 900159ad5..a5a37a3a0 100644 --- a/src/main/java/amidst/mojangapi/file/LibraryService.java +++ b/src/main/java/amidst/mojangapi/file/LibraryService.java @@ -1,27 +1,115 @@ package amidst.mojangapi.file; import java.io.File; +import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import amidst.documentation.Immutable; import amidst.documentation.NotNull; +import amidst.logging.AmidstLogger; import amidst.mojangapi.file.json.version.LibraryJson; import amidst.mojangapi.file.json.version.LibraryRuleJson; import amidst.mojangapi.file.json.version.LibraryRuleOsJson; -import amidst.mojangapi.file.json.version.VersionJson; +import amidst.util.OperatingSystemDetector; @Immutable public class LibraryService { private static final String ACTION_ALLOW = "allow"; + @NotNull + public List getLibraryUrls(File librariesDirectory, List libraries) { + List result = new ArrayList<>(); + for (LibraryJson library : libraries) { + File libraryFile = getLibraryFile(librariesDirectory, library); + if (libraryFile != null) { + try { + result.add(libraryFile.toURI().toURL()); + AmidstLogger.info("Found library: " + libraryFile); + } catch (MalformedURLException e) { + AmidstLogger.warn(e, "Unable to convert library file to URL: " + libraryFile); + } + } else { + AmidstLogger.info("Skipping library: " + library.getName()); + } + } + return result; + } + + private File getLibraryFile(File librariesDirectory, LibraryJson library) { + try { + if (isLibraryActive(library, getOs(), OperatingSystemDetector.getVersion())) { + return getLibraryFile(getLibrarySearchPath(librariesDirectory, library.getName())); + } else { + return null; + } + } catch (NullPointerException e) { + return null; + } + } + + private String getOs() { + if (OperatingSystemDetector.isWindows()) { + return "windows"; + } else if (OperatingSystemDetector.isMac()) { + return "osx"; + } else { + return "linux"; + } + } + + private File getLibrarySearchPath(File librariesDirectory, String libraryName) { + String result = librariesDirectory.getAbsolutePath() + "/"; + String[] split = libraryName.split(":"); + split[0] = split[0].replace('.', '/'); + for (String element : split) { + result += element + "/"; + } + return new File(result); + } + + private File getLibraryFile(File librarySearchPath) { + if (librarySearchPath.exists()) { + File result = getFirstFileWithExtension(librarySearchPath.listFiles(), "jar"); + if (result != null && result.exists()) { + return result; + } else { + AmidstLogger.warn( + "Attempted to search for file at path: " + librarySearchPath + " but found nothing. Skipping."); + return null; + } + } else { + AmidstLogger.warn("Failed attempt to load library at: " + librarySearchPath); + return null; + } + } + + private File getFirstFileWithExtension(File[] files, String extension) { + for (File libraryFile : files) { + if (getFileExtension(libraryFile.getName()).equals(extension)) { + return libraryFile; + } + } + return null; + } + + private String getFileExtension(String fileName) { + String extension = ""; + int q = fileName.lastIndexOf('.'); + if (q > 0) { + extension = fileName.substring(q + 1); + } + return extension; + } + /** * Note, that multiple rules might be applicable. We take the last * applicable rule. However, this might be wrong so we need to take the most * specific rule? For now this works fine. */ - public boolean isLibraryActive(LibraryJson libraryJson, String os, String version) { + private boolean isLibraryActive(LibraryJson libraryJson, String os, String version) { List rules = libraryJson.getRules(); if (rules.isEmpty()) { return true; @@ -46,12 +134,7 @@ private boolean isApplicable(String os, String version, LibraryRuleOsJson osRule return nameInJson.equals(os) && (versionInJson == null || Pattern.matches(versionInJson, version)); } - public boolean isAllowed(LibraryRuleJson rule) { + private boolean isAllowed(LibraryRuleJson rule) { return rule.getAction().equals(ACTION_ALLOW); } - - @NotNull - public List getLibraryUrls(File librariesDirectory, VersionJson versionJson) { - return LibraryFinder.getLibraryUrls(librariesDirectory, versionJson.getLibraries()); - } } From 24e09eeec99cf6999476f5ef2e1be1a284758743 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 02:09:16 +0200 Subject: [PATCH 11/48] merged LauncherProfileService and DotMinecraftDirectoryFinder to DotMinecraftDirectoryService --- .../profileselect/LocalProfileComponent.java | 7 +-- .../profileselect/ProfileSelectWindow.java | 4 +- .../amidst/mojangapi/MojangApiBuilder.java | 5 +- .../file/DotMinecraftDirectoryFinder.java | 42 ----------------- ...java => DotMinecraftDirectoryService.java} | 47 +++++++++++++++---- .../mojangapi/file/nbt/LevelDatNbt.java | 2 +- 6 files changed, 49 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryFinder.java rename src/main/java/amidst/mojangapi/file/{LauncherProfileService.java => DotMinecraftDirectoryService.java} (73%) diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index 5e3e7fb47..145dfbb61 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -11,7 +11,7 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.LauncherProfileService; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; @@ -55,9 +55,10 @@ private void initDirectoriesLater() { @CalledOnlyBy(AmidstThread.WORKER) private boolean tryFind() { + DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); try { - profileDirectory = new LauncherProfileService().createValidProfileDirectory(profile, mojangApi); - versionDirectory = new LauncherProfileService().createValidVersionDirectory(profile, mojangApi); + profileDirectory = dotMinecraftDirectoryService.createValidProfileDirectory(profile, mojangApi); + versionDirectory = dotMinecraftDirectoryService.createValidVersionDirectory(profile, mojangApi); return true; } catch (FileNotFoundException e) { AmidstLogger.warn(e); diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index f772aa823..935c99f27 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -20,7 +20,7 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.LauncherProfileService; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; @@ -115,7 +115,7 @@ private void scanAndLoadProfilesLater() { @CalledOnlyBy(AmidstThread.WORKER) private LauncherProfilesJson scanAndLoadProfiles() throws MojangApiParsingException, IOException { AmidstLogger.info("Scanning for profiles."); - LauncherProfilesJson launcherProfile = new LauncherProfileService() + LauncherProfilesJson launcherProfile = new DotMinecraftDirectoryService() .readLauncherProfilesFrom(mojangApi.getDotMinecraftDirectory()); AmidstLogger.info("Successfully loaded profile list."); return launcherProfile; diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java index 4d0454293..100bbc0d3 100644 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ b/src/main/java/amidst/mojangapi/MojangApiBuilder.java @@ -6,8 +6,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.DotMinecraftDirectoryFinder; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; @@ -44,7 +44,8 @@ public MojangApi construct() @NotNull private DotMinecraftDirectory createDotMinecraftDirectory() { - File dotMinecraftDirectory = DotMinecraftDirectoryFinder.find(parameters.dotMinecraftDirectory); + File dotMinecraftDirectory = new DotMinecraftDirectoryService() + .createDotMinecraftDirectory(parameters.dotMinecraftDirectory); if (parameters.minecraftLibrariesDirectory != null) { return new DotMinecraftDirectory(dotMinecraftDirectory, new File(parameters.minecraftLibrariesDirectory)); } else { diff --git a/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryFinder.java b/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryFinder.java deleted file mode 100644 index 60c584df0..000000000 --- a/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryFinder.java +++ /dev/null @@ -1,42 +0,0 @@ -package amidst.mojangapi.file; - -import java.io.File; - -import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; -import amidst.util.OperatingSystemDetector; - -@Immutable -public enum DotMinecraftDirectoryFinder { - ; - - @NotNull - public static File find(String dotMinecraftCMDParameter) { - if (dotMinecraftCMDParameter != null) { - File result = new File(dotMinecraftCMDParameter); - if (result.isDirectory()) { - return result; - } else { - AmidstLogger.warn( - "Unable to set Minecraft directory to: " + result - + " as that location does not exist or is not a folder."); - } - } - return getMinecraftDirectory(); - } - - @NotNull - private static File getMinecraftDirectory() { - File home = new File(System.getProperty("user.home", ".")); - if (OperatingSystemDetector.isWindows()) { - File appData = new File(System.getenv("APPDATA")); - if (appData.isDirectory()) { - return new File(appData, ".minecraft"); - } - } else if (OperatingSystemDetector.isMac()) { - return new File(home, "Library/Application Support/minecraft"); - } - return new File(home, ".minecraft"); - } -} diff --git a/src/main/java/amidst/mojangapi/file/LauncherProfileService.java b/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java similarity index 73% rename from src/main/java/amidst/mojangapi/file/LauncherProfileService.java rename to src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java index 28df517d8..38fab2e98 100644 --- a/src/main/java/amidst/mojangapi/file/LauncherProfileService.java +++ b/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java @@ -7,6 +7,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; +import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; @@ -16,9 +17,46 @@ import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; +import amidst.util.OperatingSystemDetector; @Immutable -public class LauncherProfileService { +public class DotMinecraftDirectoryService { + @NotNull + public File createDotMinecraftDirectory(String dotMinecraftCMDParameter) { + if (dotMinecraftCMDParameter != null) { + File result = new File(dotMinecraftCMDParameter); + if (result.isDirectory()) { + return result; + } else { + AmidstLogger.warn( + "Unable to set Minecraft directory to: " + result + + " as that location does not exist or is not a folder."); + } + } + return getMinecraftDirectory(); + } + + @NotNull + private File getMinecraftDirectory() { + File home = new File(System.getProperty("user.home", ".")); + if (OperatingSystemDetector.isWindows()) { + File appData = new File(System.getenv("APPDATA")); + if (appData.isDirectory()) { + return new File(appData, ".minecraft"); + } + } else if (OperatingSystemDetector.isMac()) { + return new File(home, "Library/Application Support/minecraft"); + } + return new File(home, ".minecraft"); + } + + @NotNull + public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMinecraftDirectory) + throws MojangApiParsingException, + IOException { + return JsonReader.readLauncherProfilesFrom(dotMinecraftDirectory.getLauncherProfilesJson()); + } + @NotNull public ProfileDirectory createValidProfileDirectory(LauncherProfileJson launcherProfileJson, MojangApi mojangApi) throws FileNotFoundException { @@ -71,11 +109,4 @@ private VersionDirectory tryFindFirstValidVersionDirectory( } return null; } - - @NotNull - public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMinecraftDirectory) - throws MojangApiParsingException, - IOException { - return JsonReader.readLauncherProfilesFrom(dotMinecraftDirectory.getLauncherProfilesJson()); - } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java b/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java index 650d5564d..7030676f6 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java @@ -33,7 +33,7 @@ public LevelDatNbt(CompoundTag root) throws MojangApiParsingException { } this.hasPlayer = hasPlayerTag(dataTag); } catch (NullPointerException e) { - throw new MojangApiParsingException("cannot read leve.dat", e); + throw new MojangApiParsingException("cannot read level.dat", e); } } From fd59c434dce77cce0c293b19aab06ef195a8e8f4 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 02:18:43 +0200 Subject: [PATCH 12/48] moved download logic to DownloadService --- .../mojangapi/file/DownloadService.java | 42 ++++++++++++++++--- .../java/amidst/mojangapi/file/URIUtils.java | 41 +----------------- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/DownloadService.java b/src/main/java/amidst/mojangapi/file/DownloadService.java index 5017631a8..687aea119 100644 --- a/src/main/java/amidst/mojangapi/file/DownloadService.java +++ b/src/main/java/amidst/mojangapi/file/DownloadService.java @@ -1,6 +1,13 @@ package amidst.mojangapi.file; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; @@ -11,28 +18,53 @@ public class DownloadService { private final FilenameService filenameService = new FilenameService(); public boolean hasServer(VersionListEntryJson version) { - return URIUtils.exists(filenameService.getRemoteServerJar(version.getId())); + return exists(filenameService.getRemoteServerJar(version.getId())); } public boolean hasClient(VersionListEntryJson version) { - return URIUtils.exists(filenameService.getRemoteClientJar(version.getId())); + return exists(filenameService.getRemoteClientJar(version.getId())); + } + + private static boolean exists(String location) { + try { + HttpURLConnection connection = (HttpURLConnection) URIUtils.newURL(location).openConnection(); + connection.setRequestMethod("HEAD"); + return connection.getResponseCode() == HttpURLConnection.HTTP_OK; + } catch (IOException e) { + return false; + } } public void downloadServer(String prefix, VersionListEntryJson version) throws IOException { - URIUtils.download( + download( filenameService.getRemoteServerJar(version.getId()), filenameService.getServerJar(prefix, version.getId())); } public void downloadClient(String prefix, VersionListEntryJson version) throws IOException { - URIUtils.download( + download( filenameService.getRemoteClientJar(version.getId()), filenameService.getClientJar(prefix, version.getId())); - URIUtils.download( + download( filenameService.getRemoteClientJson(version.getId()), filenameService.getClientJson(prefix, version.getId())); } + private void download(String from, String to) throws IOException { + download(URIUtils.newURL(from), Paths.get(to)); + } + + private void download(URL from, Path to) throws IOException { + to.getParent().toFile().mkdirs(); + if (to.toFile().exists()) { + return; + } + Path part = Paths.get(to.toString() + ".part"); + InputStream in = URIUtils.newInputStream(from); + Files.copy(in, part, StandardCopyOption.REPLACE_EXISTING); + Files.move(part, to, StandardCopyOption.REPLACE_EXISTING); + } + public boolean tryDownloadServer(String prefix, VersionListEntryJson version) { try { downloadServer(prefix, version); diff --git a/src/main/java/amidst/mojangapi/file/URIUtils.java b/src/main/java/amidst/mojangapi/file/URIUtils.java index 9ceac4341..cfc316a8c 100644 --- a/src/main/java/amidst/mojangapi/file/URIUtils.java +++ b/src/main/java/amidst/mojangapi/file/URIUtils.java @@ -6,16 +6,10 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -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.Paths; -import java.nio.file.StandardCopyOption; import amidst.documentation.Immutable; @@ -47,40 +41,7 @@ public static Reader newReader(File file) throws FileNotFoundException { return new BufferedReader(new FileReader(file)); } - public static boolean exists(String location) { - try { - return exists(newURL(location)); - } catch (IOException e) { - return false; - } - } - - public static boolean exists(URL url) { - try { - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("HEAD"); - return connection.getResponseCode() == HttpURLConnection.HTTP_OK; - } catch (IOException e) { - return false; - } - } - - public static void download(String from, String to) throws IOException { - download(newURL(from), Paths.get(to)); - } - - private static void download(URL from, Path to) throws IOException { - to.getParent().toFile().mkdirs(); - if (to.toFile().exists()) { - return; - } - Path part = Paths.get(to.toString() + ".part"); - InputStream in = newInputStream(from); - Files.copy(in, part, StandardCopyOption.REPLACE_EXISTING); - Files.move(part, to, StandardCopyOption.REPLACE_EXISTING); - } - - private static BufferedInputStream newInputStream(URL url) throws IOException { + public static BufferedInputStream newInputStream(URL url) throws IOException { return new BufferedInputStream(url.openStream()); } } From 862af90c216df3e4d8a44109b203767d0a9054c1 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 02:31:13 +0200 Subject: [PATCH 13/48] moved classes --- .../amidst/gui/profileselect/LocalProfileComponent.java | 2 +- .../java/amidst/gui/profileselect/ProfileSelectWindow.java | 2 +- src/main/java/amidst/mojangapi/MojangApi.java | 6 +++--- src/main/java/amidst/mojangapi/MojangApiBuilder.java | 2 +- .../java/amidst/mojangapi/file/{json => }/JsonReader.java | 4 +--- .../file/{json => }/PlayerInformationRetriever.java | 3 +-- .../amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java | 2 +- .../mojangapi/file/nbt/player/PlayerdataPlayerNbt.java | 2 +- .../amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java | 2 +- .../mojangapi/file/{ => service}/AmidstBackupService.java | 2 +- .../mojangapi/file/{ => service}/ClassLoaderService.java | 5 +++-- .../file/{ => service}/DotMinecraftDirectoryService.java | 5 +++-- .../mojangapi/file/{ => service}/DownloadService.java | 3 ++- .../mojangapi/file/{ => service}/FilenameService.java | 2 +- .../amidst/mojangapi/file/{ => service}/LibraryService.java | 2 +- .../mojangapi/file/{ => service}/PlayerSkinService.java | 5 +++-- .../mojangapi/file/{ => service}/SaveDirectoryService.java | 3 ++- .../local/LocalMinecraftInterfaceBuilder.java | 2 +- src/main/java/amidst/mojangapi/world/WorldBuilder.java | 2 +- .../amidst/mojangapi/world/player/PlayerInformation.java | 4 ++-- .../java/amidst/mojangapi/world/player/WorldPlayerType.java | 2 +- src/test/java/amidst/devtools/DevToolRunner.java | 2 +- .../java/amidst/devtools/GenerateRecognisedVersionList.java | 6 +++--- src/test/java/amidst/devtools/GenerateWorldTestData.java | 4 ++-- .../devtools/MinecraftJarDownloadAvailabilityChecker.java | 2 +- src/test/java/amidst/devtools/MinecraftJarDownloader.java | 2 +- .../devtools/MinecraftVersionCompatibilityChecker.java | 4 ++-- 27 files changed, 42 insertions(+), 40 deletions(-) rename src/main/java/amidst/mojangapi/file/{json => }/JsonReader.java (97%) rename src/main/java/amidst/mojangapi/file/{json => }/PlayerInformationRetriever.java (96%) rename src/main/java/amidst/mojangapi/file/{ => service}/AmidstBackupService.java (97%) rename src/main/java/amidst/mojangapi/file/{ => service}/ClassLoaderService.java (93%) rename src/main/java/amidst/mojangapi/file/{ => service}/DotMinecraftDirectoryService.java (96%) rename src/main/java/amidst/mojangapi/file/{ => service}/DownloadService.java (97%) rename src/main/java/amidst/mojangapi/file/{ => service}/FilenameService.java (98%) rename src/main/java/amidst/mojangapi/file/{ => service}/LibraryService.java (99%) rename src/main/java/amidst/mojangapi/file/{ => service}/PlayerSkinService.java (93%) rename src/main/java/amidst/mojangapi/file/{ => service}/SaveDirectoryService.java (97%) diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index 145dfbb61..db08b809b 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -11,10 +11,10 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; +import amidst.mojangapi.file.service.DotMinecraftDirectoryService; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.threading.WorkerExecutor; diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index 935c99f27..b930380f2 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -20,10 +20,10 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; +import amidst.mojangapi.file.service.DotMinecraftDirectoryService; import amidst.threading.WorkerExecutor; import net.miginfocom.swing.MigLayout; diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 8023a9434..463a466d7 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -6,14 +6,14 @@ import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; -import amidst.mojangapi.file.FilenameService; +import amidst.mojangapi.file.JsonReader; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.SaveDirectoryService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.FilenameService; +import amidst.mojangapi.file.service.SaveDirectoryService; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java index 100bbc0d3..40c16cfff 100644 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ b/src/main/java/amidst/mojangapi/MojangApiBuilder.java @@ -7,9 +7,9 @@ import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.DotMinecraftDirectoryService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.service.DotMinecraftDirectoryService; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.WorldBuilder; diff --git a/src/main/java/amidst/mojangapi/file/json/JsonReader.java b/src/main/java/amidst/mojangapi/file/JsonReader.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/json/JsonReader.java rename to src/main/java/amidst/mojangapi/file/JsonReader.java index 146978a88..48e3f270d 100644 --- a/src/main/java/amidst/mojangapi/file/json/JsonReader.java +++ b/src/main/java/amidst/mojangapi/file/JsonReader.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.json; +package amidst.mojangapi.file; import java.io.File; import java.io.FileNotFoundException; @@ -14,8 +14,6 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.URIUtils; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; import amidst.mojangapi.file.json.player.PlayerJson; import amidst.mojangapi.file.json.player.SimplePlayerJson; diff --git a/src/main/java/amidst/mojangapi/file/json/PlayerInformationRetriever.java b/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java similarity index 96% rename from src/main/java/amidst/mojangapi/file/json/PlayerInformationRetriever.java rename to src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java index 352bb91be..71a7950a1 100644 --- a/src/main/java/amidst/mojangapi/file/json/PlayerInformationRetriever.java +++ b/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.json; +package amidst.mojangapi.file; import java.awt.Color; import java.awt.Graphics2D; @@ -10,7 +10,6 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.player.PlayerJson; @Immutable diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java index 9eb039ac7..054e58ac1 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java @@ -3,10 +3,10 @@ import java.io.IOException; import amidst.documentation.Immutable; -import amidst.mojangapi.file.AmidstBackupService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; +import amidst.mojangapi.file.service.AmidstBackupService; import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; import amidst.mojangapi.world.player.PlayerInformation; diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java index 6c58ffe5f..f7c3f7230 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java @@ -3,10 +3,10 @@ import java.io.IOException; import amidst.documentation.Immutable; -import amidst.mojangapi.file.AmidstBackupService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; +import amidst.mojangapi.file.service.AmidstBackupService; import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; import amidst.mojangapi.world.player.PlayerInformationCache; diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java index 7084970ca..8e4abec61 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java @@ -3,10 +3,10 @@ import java.io.IOException; import amidst.documentation.Immutable; -import amidst.mojangapi.file.AmidstBackupService; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; +import amidst.mojangapi.file.service.AmidstBackupService; import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; import amidst.mojangapi.world.player.PlayerInformationCache; diff --git a/src/main/java/amidst/mojangapi/file/AmidstBackupService.java b/src/main/java/amidst/mojangapi/file/service/AmidstBackupService.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/AmidstBackupService.java rename to src/main/java/amidst/mojangapi/file/service/AmidstBackupService.java index 6630642a0..e3a1795c0 100644 --- a/src/main/java/amidst/mojangapi/file/AmidstBackupService.java +++ b/src/main/java/amidst/mojangapi/file/service/AmidstBackupService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.io.File; import java.io.IOException; diff --git a/src/main/java/amidst/mojangapi/file/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java similarity index 93% rename from src/main/java/amidst/mojangapi/file/ClassLoaderService.java rename to src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index eae920b11..17f6a6fcb 100644 --- a/src/main/java/amidst/mojangapi/file/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.io.File; import java.io.IOException; @@ -11,9 +11,10 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.JsonReader; +import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.JsonReader; @Immutable public class ClassLoaderService { diff --git a/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java similarity index 96% rename from src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java rename to src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index 38fab2e98..4a5593d72 100644 --- a/src/main/java/amidst/mojangapi/file/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.io.File; import java.io.FileNotFoundException; @@ -9,10 +9,11 @@ import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.JsonReader; +import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; diff --git a/src/main/java/amidst/mojangapi/file/DownloadService.java b/src/main/java/amidst/mojangapi/file/service/DownloadService.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/DownloadService.java rename to src/main/java/amidst/mojangapi/file/service/DownloadService.java index 687aea119..b970f1e49 100644 --- a/src/main/java/amidst/mojangapi/file/DownloadService.java +++ b/src/main/java/amidst/mojangapi/file/service/DownloadService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.io.IOException; import java.io.InputStream; @@ -11,6 +11,7 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.URIUtils; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; @Immutable diff --git a/src/main/java/amidst/mojangapi/file/FilenameService.java b/src/main/java/amidst/mojangapi/file/service/FilenameService.java similarity index 98% rename from src/main/java/amidst/mojangapi/file/FilenameService.java rename to src/main/java/amidst/mojangapi/file/service/FilenameService.java index a6dfc6185..599342609 100644 --- a/src/main/java/amidst/mojangapi/file/FilenameService.java +++ b/src/main/java/amidst/mojangapi/file/service/FilenameService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.io.File; diff --git a/src/main/java/amidst/mojangapi/file/LibraryService.java b/src/main/java/amidst/mojangapi/file/service/LibraryService.java similarity index 99% rename from src/main/java/amidst/mojangapi/file/LibraryService.java rename to src/main/java/amidst/mojangapi/file/service/LibraryService.java index a5a37a3a0..6e4b3f453 100644 --- a/src/main/java/amidst/mojangapi/file/LibraryService.java +++ b/src/main/java/amidst/mojangapi/file/service/LibraryService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.io.File; import java.net.MalformedURLException; diff --git a/src/main/java/amidst/mojangapi/file/PlayerSkinService.java b/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java similarity index 93% rename from src/main/java/amidst/mojangapi/file/PlayerSkinService.java rename to src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java index 609c47db0..62d8d9c69 100644 --- a/src/main/java/amidst/mojangapi/file/PlayerSkinService.java +++ b/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -6,7 +6,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.json.JsonReader; +import amidst.mojangapi.file.JsonReader; +import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.player.PlayerJson; import amidst.mojangapi.file.json.player.PropertyJson; import amidst.mojangapi.file.json.player.SKINJson; diff --git a/src/main/java/amidst/mojangapi/file/SaveDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/SaveDirectoryService.java rename to src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java index 0ecaa171f..e88234b60 100644 --- a/src/main/java/amidst/mojangapi/file/SaveDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.mojangapi.file.service; import java.io.File; import java.io.FileNotFoundException; @@ -10,6 +10,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.LevelDatNbt; import amidst.mojangapi.file.nbt.NBTUtils; diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java index 5dc66f977..2eac9a4dd 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java @@ -13,9 +13,9 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.ClassLoaderService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.service.ClassLoaderService; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @Immutable diff --git a/src/main/java/amidst/mojangapi/world/WorldBuilder.java b/src/main/java/amidst/mojangapi/world/WorldBuilder.java index 282cd2104..25daa34ec 100644 --- a/src/main/java/amidst/mojangapi/world/WorldBuilder.java +++ b/src/main/java/amidst/mojangapi/world/WorldBuilder.java @@ -4,9 +4,9 @@ import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.SaveDirectoryService; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.LevelDatNbt; +import amidst.mojangapi.file.service.SaveDirectoryService; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; diff --git a/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java b/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java index 37fb59783..6c549d50a 100644 --- a/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java +++ b/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java @@ -5,9 +5,9 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.PlayerSkinService; -import amidst.mojangapi.file.json.PlayerInformationRetriever; +import amidst.mojangapi.file.PlayerInformationRetriever; import amidst.mojangapi.file.json.player.PlayerJson; +import amidst.mojangapi.file.service.PlayerSkinService; import amidst.mojangapi.world.icon.WorldIconImage; import amidst.mojangapi.world.icon.type.DefaultWorldIconTypes; diff --git a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java index 413d060f6..9e0ecec61 100644 --- a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java +++ b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java @@ -7,10 +7,10 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.SaveDirectoryService; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.LevelDatNbt; import amidst.mojangapi.file.nbt.player.PlayerNbt; +import amidst.mojangapi.file.service.SaveDirectoryService; @Immutable public enum WorldPlayerType { diff --git a/src/test/java/amidst/devtools/DevToolRunner.java b/src/test/java/amidst/devtools/DevToolRunner.java index 6fb4b9898..746fa799d 100644 --- a/src/test/java/amidst/devtools/DevToolRunner.java +++ b/src/test/java/amidst/devtools/DevToolRunner.java @@ -9,8 +9,8 @@ import amidst.AmidstVersion; import amidst.ResourceLoader; import amidst.devtools.settings.DevToolSettings; +import amidst.mojangapi.file.JsonReader; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.world.biome.Biome; diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index f4bf110cf..589f203a7 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -8,13 +8,13 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.ClassLoaderService; -import amidst.mojangapi.file.DownloadService; -import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.ClassLoaderService; +import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.minecraftinterface.RecognisedVersion; public class GenerateRecognisedVersionList { diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 5868a68e4..82aa4bcae 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -6,12 +6,12 @@ import java.util.List; import amidst.clazz.translator.ClassTranslator; -import amidst.mojangapi.file.DownloadService; -import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java index df141c8af..3ea45734e 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java @@ -1,9 +1,9 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.DownloadService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.DownloadService; public class MinecraftJarDownloadAvailabilityChecker { private VersionStateRenderer renderer = new VersionStateRenderer(); diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloader.java b/src/test/java/amidst/devtools/MinecraftJarDownloader.java index 3f57dc185..5c75155ea 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloader.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloader.java @@ -1,9 +1,9 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.DownloadService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.DownloadService; public class MinecraftJarDownloader { private VersionStateRenderer renderer = new VersionStateRenderer(); diff --git a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java index 6a587bd95..d76066ac5 100644 --- a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java @@ -11,10 +11,10 @@ import amidst.clazz.real.JarFileParsingException; import amidst.clazz.symbolic.declaration.SymbolicClassDeclaration; import amidst.clazz.translator.ClassTranslator; -import amidst.mojangapi.file.DownloadService; -import amidst.mojangapi.file.FilenameService; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; /** From 51d6f44121b68b25d3ead1e8879aaf4c853863ad Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 03:13:33 +0200 Subject: [PATCH 14/48] moved domain logic out of the JsonReader --- src/main/java/amidst/mojangapi/MojangApi.java | 4 +- .../amidst/mojangapi/file/JsonReader.java | 137 ------------------ .../file/PlayerInformationRetriever.java | 16 +- .../mojangapi/file/json/JsonReader.java | 72 +++++++++ .../file/service/ClassLoaderService.java | 5 +- .../service/DotMinecraftDirectoryService.java | 4 +- .../file/service/PlayerSkinService.java | 4 +- .../file/service/VersionListService.java | 57 ++++++++ .../java/amidst/devtools/DevToolRunner.java | 4 +- 9 files changed, 152 insertions(+), 151 deletions(-) delete mode 100644 src/main/java/amidst/mojangapi/file/JsonReader.java create mode 100644 src/main/java/amidst/mojangapi/file/json/JsonReader.java create mode 100644 src/main/java/amidst/mojangapi/file/service/VersionListService.java diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 463a466d7..56a7cea50 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -6,7 +6,6 @@ import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; -import amidst.mojangapi.file.JsonReader; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; @@ -14,6 +13,7 @@ import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.file.service.SaveDirectoryService; +import amidst.mojangapi.file.service.VersionListService; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -55,7 +55,7 @@ public VersionListJson getVersionList() throws FileNotFoundException { synchronized (this) { versionList = this.versionList; if (versionList == null) { - versionList = JsonReader.readRemoteOrLocalVersionList(); + versionList = new VersionListService().readRemoteOrLocalVersionList(); this.versionList = versionList; } } diff --git a/src/main/java/amidst/mojangapi/file/JsonReader.java b/src/main/java/amidst/mojangapi/file/JsonReader.java deleted file mode 100644 index 48e3f270d..000000000 --- a/src/main/java/amidst/mojangapi/file/JsonReader.java +++ /dev/null @@ -1,137 +0,0 @@ -package amidst.mojangapi.file; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.Reader; -import java.net.URL; - -import com.google.gson.Gson; -import com.google.gson.JsonIOException; -import com.google.gson.JsonSyntaxException; - -import amidst.ResourceLoader; -import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; -import amidst.mojangapi.file.json.player.PlayerJson; -import amidst.mojangapi.file.json.player.SimplePlayerJson; -import amidst.mojangapi.file.json.version.VersionJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; - -/** - * This is a utility class used to read JSON data. Please use this class only to - * read JSON data provided by Mojang, because it throws a - * MojangApiParsingException when an error occurs. - */ -@Immutable -public enum JsonReader { - ; - - private static final Gson GSON = new Gson(); - - private static final String REMOTE_VERSION_LIST = "https://launchermeta.mojang.com/mc/game/version_manifest.json"; - private static final URL LOCAL_VERSION_LIST = ResourceLoader - .getResourceURL("/amidst/mojangapi/version_manifest.json"); - - private static final String UUID_TO_PROFILE = "https://sessionserver.mojang.com/session/minecraft/profile/"; - private static final String PLAYERNAME_TO_UUID = "https://api.mojang.com/users/profiles/minecraft/"; - - @NotNull - public static VersionListJson readRemoteOrLocalVersionList() throws FileNotFoundException { - AmidstLogger.info("Beginning latest version list load."); - AmidstLogger.info("Attempting to download remote version list..."); - VersionListJson remote = null; - try { - remote = readRemoteVersionList(); - } catch (IOException | MojangApiParsingException e) { - AmidstLogger.warn("Unable to read remote version list."); - AmidstLogger.warn(e); - AmidstLogger.warn("Aborting version list load. URL: " + REMOTE_VERSION_LIST); - } - if (remote != null) { - AmidstLogger.info("Successfully loaded version list. URL: " + REMOTE_VERSION_LIST); - return remote; - } - AmidstLogger.info("Attempting to load local version list..."); - VersionListJson local = null; - try { - local = readLocalVersionListFromResource(); - } catch (IOException | MojangApiParsingException e) { - AmidstLogger.warn("Unable to read local version list."); - AmidstLogger.warn(e); - AmidstLogger.warn("Aborting version list load. URL: " + LOCAL_VERSION_LIST); - } - if (local != null) { - AmidstLogger.info("Successfully loaded version list. URL: " + LOCAL_VERSION_LIST); - return local; - } - AmidstLogger.warn("Failed to load both remote and local version list."); - throw new FileNotFoundException("unable to read version list"); - } - - @NotNull - public static VersionListJson readRemoteVersionList() throws IOException, MojangApiParsingException { - return read(URIUtils.newReader(REMOTE_VERSION_LIST), VersionListJson.class); - } - - @NotNull - public static VersionListJson readLocalVersionListFromResource() throws IOException, MojangApiParsingException { - return read(URIUtils.newReader(LOCAL_VERSION_LIST), VersionListJson.class); - } - - @NotNull - public static VersionJson readVersionFrom(File file) throws MojangApiParsingException, IOException { - return read(URIUtils.newReader(file), VersionJson.class); - } - - @NotNull - public static LauncherProfilesJson readLauncherProfilesFrom(File file) - throws MojangApiParsingException, - IOException { - return read(URIUtils.newReader(file), LauncherProfilesJson.class); - } - - @NotNull - public static T read(Reader reader, Class clazz) throws MojangApiParsingException, IOException { - try (Reader theReader = reader) { - T result = GSON.fromJson(theReader, clazz); - if (result != null) { - return result; - } else { - throw new MojangApiParsingException("result was null"); - } - } catch (JsonSyntaxException e) { - throw new MojangApiParsingException(e); - } catch (JsonIOException e) { - throw new IOException(e); - } - } - - @NotNull - public static PlayerJson readPlayerFromUUID(String uuid) throws IOException, MojangApiParsingException { - return read(URIUtils.newReader(UUID_TO_PROFILE + uuid), PlayerJson.class); - } - - @NotNull - public static SimplePlayerJson readSimplePlayerFromPlayerName(String playerName) - throws IOException, - MojangApiParsingException { - return read(URIUtils.newReader(PLAYERNAME_TO_UUID + playerName), SimplePlayerJson.class); - } - - @NotNull - public static T read(String string, Class clazz) throws MojangApiParsingException { - try { - T result = GSON.fromJson(string, clazz); - if (result != null) { - return result; - } else { - throw new MojangApiParsingException("result was null"); - } - } catch (JsonSyntaxException e) { - throw new MojangApiParsingException(e); - } - } -} diff --git a/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java b/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java index 71a7950a1..52125b0a6 100644 --- a/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java +++ b/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java @@ -10,13 +10,17 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.player.PlayerJson; +import amidst.mojangapi.file.json.player.SimplePlayerJson; @Immutable public enum PlayerInformationRetriever { ; private static final String SIMPLE_PLAYER_SKIN_URL = "http://s3.amazonaws.com/MinecraftSkins/"; + private static final String PLAYERNAME_TO_UUID = "https://api.mojang.com/users/profiles/minecraft/"; + private static final String UUID_TO_PROFILE = "https://sessionserver.mojang.com/session/minecraft/profile/"; public static PlayerJson tryGetPlayerJsonByName(String name) { try { @@ -54,12 +58,16 @@ public static BufferedImage tryGetPlayerHeadBySkinUrl(String skinUrl) { } } - private static PlayerJson getPlayerJsonByName(String name) throws IOException, MojangApiParsingException { - return JsonReader.readPlayerFromUUID(JsonReader.readSimplePlayerFromPlayerName(name).getId()); + private static PlayerJson getPlayerJsonByUUID(String uuid) throws MojangApiParsingException, IOException { + return JsonReader.readLocation(UUID_TO_PROFILE + uuid, PlayerJson.class); } - private static PlayerJson getPlayerJsonByUUID(String uuid) throws IOException, MojangApiParsingException { - return JsonReader.readPlayerFromUUID(uuid); + private static PlayerJson getPlayerJsonByName(String name) throws MojangApiParsingException, IOException { + return getPlayerJsonByUUID(getUUIDByName(name)); + } + + private static String getUUIDByName(String name) throws MojangApiParsingException, IOException { + return JsonReader.readLocation(PLAYERNAME_TO_UUID + name, SimplePlayerJson.class).getId(); } private static BufferedImage getPlayerHeadByName(String name) throws IOException { diff --git a/src/main/java/amidst/mojangapi/file/json/JsonReader.java b/src/main/java/amidst/mojangapi/file/json/JsonReader.java new file mode 100644 index 000000000..dc04ff7d1 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/json/JsonReader.java @@ -0,0 +1,72 @@ +package amidst.mojangapi.file.json; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.net.URL; + +import com.google.gson.Gson; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; + +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.URIUtils; + +/** + * This is a utility class used to read JSON data. Please use this class only to + * read JSON data provided by Mojang, because it throws a + * MojangApiParsingException when an error occurs. + */ +@Immutable +public enum JsonReader { + ; + + private static final Gson GSON = new Gson(); + + @NotNull + public static T readLocation(File location, Class clazz) throws MojangApiParsingException, IOException { + return readReader(URIUtils.newReader(location), clazz); + } + + @NotNull + public static T readLocation(URL location, Class clazz) throws MojangApiParsingException, IOException { + return readReader(URIUtils.newReader(location), clazz); + } + + @NotNull + public static T readLocation(String location, Class clazz) throws MojangApiParsingException, IOException { + return readReader(URIUtils.newReader(location), clazz); + } + + @NotNull + private static T readReader(Reader reader, Class clazz) throws MojangApiParsingException, IOException { + try (Reader theReader = reader) { + T result = GSON.fromJson(theReader, clazz); + if (result != null) { + return result; + } else { + throw new MojangApiParsingException("result was null"); + } + } catch (JsonSyntaxException e) { + throw new MojangApiParsingException(e); + } catch (JsonIOException e) { + throw new IOException(e); + } + } + + @NotNull + public static T readString(String string, Class clazz) throws MojangApiParsingException { + try { + T result = GSON.fromJson(string, clazz); + if (result != null) { + return result; + } else { + throw new MojangApiParsingException("result was null"); + } + } catch (JsonSyntaxException e) { + throw new MojangApiParsingException(e); + } + } +} diff --git a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index 17f6a6fcb..61db92614 100644 --- a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -11,10 +11,11 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.JsonReader; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.JsonReader; +import amidst.mojangapi.file.json.version.VersionJson; @Immutable public class ClassLoaderService { @@ -57,7 +58,7 @@ private List getAllLibraryUrls( try { return new LibraryService().getLibraryUrls( dotMinecraftDirectory.getLibraries(), - JsonReader.readVersionFrom(json).getLibraries()); + JsonReader.readLocation(json, VersionJson.class).getLibraries()); } catch (IOException | MojangApiParsingException e) { AmidstLogger.warn("Invalid jar profile loaded. Library loading will be skipped. (Path: " + json + ")"); return new ArrayList<>(); diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index 4a5593d72..20954fc41 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -9,11 +9,11 @@ import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.JsonReader; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; @@ -55,7 +55,7 @@ private File getMinecraftDirectory() { public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMinecraftDirectory) throws MojangApiParsingException, IOException { - return JsonReader.readLauncherProfilesFrom(dotMinecraftDirectory.getLauncherProfilesJson()); + return JsonReader.readLocation(dotMinecraftDirectory.getLauncherProfilesJson(), LauncherProfilesJson.class); } @NotNull diff --git a/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java b/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java index 62d8d9c69..27a023cb0 100644 --- a/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java +++ b/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java @@ -6,8 +6,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.JsonReader; import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.player.PlayerJson; import amidst.mojangapi.file.json.player.PropertyJson; import amidst.mojangapi.file.json.player.SKINJson; @@ -30,7 +30,7 @@ private Optional readTexturesProperty(PlayerJson playerJso throws MojangApiParsingException { for (PropertyJson property : playerJson.getProperties()) { if (isTexturesProperty(property)) { - return Optional.of(JsonReader.read(getDecodedValue(property), TexturesPropertyJson.class)); + return Optional.of(JsonReader.readString(getDecodedValue(property), TexturesPropertyJson.class)); } } return Optional.empty(); diff --git a/src/main/java/amidst/mojangapi/file/service/VersionListService.java b/src/main/java/amidst/mojangapi/file/service/VersionListService.java new file mode 100644 index 000000000..33c5b2c91 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/service/VersionListService.java @@ -0,0 +1,57 @@ +package amidst.mojangapi.file.service; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URL; + +import amidst.ResourceLoader; +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.json.JsonReader; +import amidst.mojangapi.file.json.versionlist.VersionListJson; + +@Immutable +public class VersionListService { + private static final String REMOTE_VERSION_LIST = "https://launchermeta.mojang.com/mc/game/version_manifest.json"; + private static final URL LOCAL_VERSION_LIST = ResourceLoader + .getResourceURL("/amidst/mojangapi/version_manifest.json"); + + @NotNull + public VersionListJson readRemoteOrLocalVersionList() throws FileNotFoundException { + AmidstLogger.info("Beginning latest version list load."); + AmidstLogger.info("Attempting to download remote version list..."); + try { + VersionListJson remote = readRemoteVersionList(); + AmidstLogger.info("Successfully loaded version list. URL: " + REMOTE_VERSION_LIST); + return remote; + } catch (IOException | MojangApiParsingException e) { + AmidstLogger.warn("Unable to read remote version list."); + AmidstLogger.warn(e); + AmidstLogger.warn("Aborting version list load. URL: " + REMOTE_VERSION_LIST); + } + AmidstLogger.info("Attempting to load local version list..."); + try { + VersionListJson local = readLocalVersionListFromResource(); + AmidstLogger.info("Successfully loaded version list. URL: " + LOCAL_VERSION_LIST); + return local; + } catch (IOException | MojangApiParsingException e) { + AmidstLogger.warn("Unable to read local version list."); + AmidstLogger.warn(e); + AmidstLogger.warn("Aborting version list load. URL: " + LOCAL_VERSION_LIST); + } + AmidstLogger.warn("Failed to load both remote and local version list."); + throw new FileNotFoundException("unable to read version list"); + } + + @NotNull + public VersionListJson readRemoteVersionList() throws MojangApiParsingException, IOException { + return JsonReader.readLocation(REMOTE_VERSION_LIST, VersionListJson.class); + } + + @NotNull + public VersionListJson readLocalVersionListFromResource() throws MojangApiParsingException, IOException { + return JsonReader.readLocation(LOCAL_VERSION_LIST, VersionListJson.class); + } +} diff --git a/src/test/java/amidst/devtools/DevToolRunner.java b/src/test/java/amidst/devtools/DevToolRunner.java index 746fa799d..23ea6a40f 100644 --- a/src/test/java/amidst/devtools/DevToolRunner.java +++ b/src/test/java/amidst/devtools/DevToolRunner.java @@ -9,9 +9,9 @@ import amidst.AmidstVersion; import amidst.ResourceLoader; import amidst.devtools.settings.DevToolSettings; -import amidst.mojangapi.file.JsonReader; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.VersionListService; import amidst.mojangapi.world.biome.Biome; /** @@ -63,7 +63,7 @@ public void generateBiomeColorImages() throws IOException { } private VersionListJson versionList() throws IOException, MojangApiParsingException { - return JsonReader.readRemoteVersionList(); + return new VersionListService().readRemoteVersionList(); } private String librariesDirectory() { From a44ab58a5623636eeb9bed6b61ee12b12e84d4ef Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 03:56:11 +0200 Subject: [PATCH 15/48] merged PlayerSkinService, PlayerInformationRetriever and parts of PlayerInformation to PlayerInformationService --- .../file/PlayerInformationRetriever.java | 95 -------- .../service/PlayerInformationService.java | 205 ++++++++++++++++++ .../file/service/PlayerSkinService.java | 59 ----- .../amidst/mojangapi/world/player/Player.java | 2 +- .../world/player/PlayerInformation.java | 68 +----- .../player/PlayerInformationCacheImpl.java | 6 +- 6 files changed, 212 insertions(+), 223 deletions(-) delete mode 100644 src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java create mode 100644 src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java delete mode 100644 src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java diff --git a/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java b/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java deleted file mode 100644 index 52125b0a6..000000000 --- a/src/main/java/amidst/mojangapi/file/PlayerInformationRetriever.java +++ /dev/null @@ -1,95 +0,0 @@ -package amidst.mojangapi.file; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.net.URL; - -import javax.imageio.ImageIO; - -import amidst.documentation.Immutable; -import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.json.JsonReader; -import amidst.mojangapi.file.json.player.PlayerJson; -import amidst.mojangapi.file.json.player.SimplePlayerJson; - -@Immutable -public enum PlayerInformationRetriever { - ; - - private static final String SIMPLE_PLAYER_SKIN_URL = "http://s3.amazonaws.com/MinecraftSkins/"; - private static final String PLAYERNAME_TO_UUID = "https://api.mojang.com/users/profiles/minecraft/"; - private static final String UUID_TO_PROFILE = "https://sessionserver.mojang.com/session/minecraft/profile/"; - - public static PlayerJson tryGetPlayerJsonByName(String name) { - try { - return getPlayerJsonByName(name); - } catch (IOException | MojangApiParsingException | NullPointerException e) { - AmidstLogger.warn("unable to load player information by name: " + name); - return null; - } - } - - public static PlayerJson tryGetPlayerJsonByUUID(String uuid) { - try { - return getPlayerJsonByUUID(uuid); - } catch (IOException | MojangApiParsingException | NullPointerException e) { - AmidstLogger.warn("unable to load player information by uuid: " + uuid); - return null; - } - } - - public static BufferedImage tryGetPlayerHeadByName(String name) { - try { - return getPlayerHeadByName(name); - } catch (IOException | NullPointerException e) { - AmidstLogger.warn("unable to load player head by name: " + name); - return null; - } - } - - public static BufferedImage tryGetPlayerHeadBySkinUrl(String skinUrl) { - try { - return getPlayerHeadBySkinUrl(skinUrl); - } catch (IOException | NullPointerException e) { - AmidstLogger.warn("unable to load player head by skin url: " + skinUrl); - return null; - } - } - - private static PlayerJson getPlayerJsonByUUID(String uuid) throws MojangApiParsingException, IOException { - return JsonReader.readLocation(UUID_TO_PROFILE + uuid, PlayerJson.class); - } - - private static PlayerJson getPlayerJsonByName(String name) throws MojangApiParsingException, IOException { - return getPlayerJsonByUUID(getUUIDByName(name)); - } - - private static String getUUIDByName(String name) throws MojangApiParsingException, IOException { - return JsonReader.readLocation(PLAYERNAME_TO_UUID + name, SimplePlayerJson.class).getId(); - } - - private static BufferedImage getPlayerHeadByName(String name) throws IOException { - return extractPlayerHead(new URL(SIMPLE_PLAYER_SKIN_URL + name + ".png")); - } - - private static BufferedImage getPlayerHeadBySkinUrl(String skinUrl) throws IOException { - return extractPlayerHead(new URL(skinUrl)); - } - - private static BufferedImage extractPlayerHead(URL url) throws IOException { - return extractPlayerHead(ImageIO.read(url)); - } - - private static BufferedImage extractPlayerHead(BufferedImage skin) { - BufferedImage head = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2d = head.createGraphics(); - g2d.setColor(Color.black); - g2d.fillRect(0, 0, 20, 20); - g2d.drawImage(skin, 2, 2, 18, 18, 8, 8, 16, 16, null); - g2d.dispose(); - skin.flush(); - return head; - } -} diff --git a/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java new file mode 100644 index 000000000..f99b6d25c --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java @@ -0,0 +1,205 @@ +package amidst.mojangapi.file.service; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Optional; + +import javax.imageio.ImageIO; + +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.json.JsonReader; +import amidst.mojangapi.file.json.player.PlayerJson; +import amidst.mojangapi.file.json.player.PropertyJson; +import amidst.mojangapi.file.json.player.SKINJson; +import amidst.mojangapi.file.json.player.SimplePlayerJson; +import amidst.mojangapi.file.json.player.TexturesJson; +import amidst.mojangapi.file.json.player.TexturesPropertyJson; +import amidst.mojangapi.world.icon.WorldIconImage; +import amidst.mojangapi.world.icon.type.DefaultWorldIconTypes; +import amidst.mojangapi.world.player.PlayerInformation; + +@Immutable +public class PlayerInformationService { + private static final WorldIconImage DEFAULT_HEAD = DefaultWorldIconTypes.PLAYER.getImage(); + + private static final String SIMPLE_PLAYER_SKIN_URL = "http://s3.amazonaws.com/MinecraftSkins/"; + private static final String PLAYERNAME_TO_UUID = "https://api.mojang.com/users/profiles/minecraft/"; + private static final String UUID_TO_PROFILE = "https://sessionserver.mojang.com/session/minecraft/profile/"; + + @NotNull + public PlayerInformation fromUUID(String uuid) { + Optional optionalPlayer = tryGetPlayerJsonByUUID(uuid); + Optional head; + if (optionalPlayer.isPresent()) { + PlayerJson player = optionalPlayer.get(); + head = tryGetSkinUrl(player).flatMap(this::tryGetPlayerHeadBySkinUrl); + if (head.isPresent()) { + return new PlayerInformation(player.getId(), player.getName(), head.get()); + } else { + return new PlayerInformation(player.getId(), player.getName(), DEFAULT_HEAD); + } + } else { + return new PlayerInformation(uuid, null, DEFAULT_HEAD); + } + } + + @NotNull + public PlayerInformation fromName(String name) { + Optional optionalPlayer = tryGetPlayerJsonByName(name); + Optional head; + if (optionalPlayer.isPresent()) { + PlayerJson player = optionalPlayer.get(); + head = tryGetSkinUrl(player).flatMap(this::tryGetPlayerHeadBySkinUrl); + if (head.isPresent()) { + return new PlayerInformation(player.getId(), player.getName(), head.get()); + } else { + head = tryGetPlayerHeadByName(name); + if (head.isPresent()) { + return new PlayerInformation(player.getId(), player.getName(), head.get()); + } else { + return new PlayerInformation(player.getId(), player.getName(), DEFAULT_HEAD); + } + } + } else { + head = tryGetPlayerHeadByName(name); + if (head.isPresent()) { + return new PlayerInformation(null, name, head.get()); + } else { + return new PlayerInformation(null, name, DEFAULT_HEAD); + } + } + } + + @NotNull + private Optional tryGetSkinUrl(PlayerJson playerJson) { + return tryReadTexturesProperty(playerJson) + .map(TexturesPropertyJson::getTextures) + .map(TexturesJson::getSKIN) + .map(SKINJson::getUrl); + } + + @NotNull + private Optional tryReadTexturesProperty(PlayerJson playerJson) { + try { + for (PropertyJson property : playerJson.getProperties()) { + if (isTexturesProperty(property)) { + return Optional.of(JsonReader.readString(getDecodedValue(property), TexturesPropertyJson.class)); + } + } + return Optional.empty(); + } catch (MojangApiParsingException e) { + return Optional.empty(); + } + } + + private boolean isTexturesProperty(PropertyJson propertyJson) throws MojangApiParsingException { + String name = propertyJson.getName(); + if (name == null) { + throw new MojangApiParsingException("property has no name"); + } else { + return name.equals("textures"); + } + } + + @NotNull + private String getDecodedValue(PropertyJson propertyJson) throws MojangApiParsingException { + String value = propertyJson.getValue(); + if (value == null) { + throw new MojangApiParsingException("unable to decode property value"); + } else { + return new String( + Base64.getDecoder().decode(value.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8); + } + } + + @NotNull + private Optional tryGetPlayerJsonByName(String name) { + try { + return Optional.of(getPlayerJsonByName(name)); + } catch (IOException | MojangApiParsingException | NullPointerException e) { + AmidstLogger.warn("unable to load player information by name: " + name); + return Optional.empty(); + } + } + + @NotNull + private Optional tryGetPlayerJsonByUUID(String uuid) { + try { + return Optional.of(getPlayerJsonByUUID(uuid)); + } catch (IOException | MojangApiParsingException | NullPointerException e) { + AmidstLogger.warn("unable to load player information by uuid: " + uuid); + return Optional.empty(); + } + } + + @NotNull + private PlayerJson getPlayerJsonByName(String name) throws MojangApiParsingException, IOException { + return getPlayerJsonByUUID(getUUIDByName(name).getId()); + } + + @NotNull + private PlayerJson getPlayerJsonByUUID(String uuid) throws MojangApiParsingException, IOException { + return JsonReader.readLocation(UUID_TO_PROFILE + uuid, PlayerJson.class); + } + + @NotNull + private SimplePlayerJson getUUIDByName(String name) throws MojangApiParsingException, IOException { + return JsonReader.readLocation(PLAYERNAME_TO_UUID + name, SimplePlayerJson.class); + } + + @NotNull + private Optional tryGetPlayerHeadByName(String name) { + try { + return Optional.of(WorldIconImage.from(getPlayerHeadByName(name))); + } catch (IOException | NullPointerException e) { + AmidstLogger.warn("unable to load player head by name: " + name); + return Optional.empty(); + } + } + + @NotNull + private Optional tryGetPlayerHeadBySkinUrl(String skinUrl) { + try { + return Optional.of(WorldIconImage.from(getPlayerHeadBySkinUrl(skinUrl))); + } catch (IOException | NullPointerException e) { + AmidstLogger.warn("unable to load player head by skin url: " + skinUrl); + return Optional.empty(); + } + } + + @NotNull + private BufferedImage getPlayerHeadByName(String name) throws IOException { + return extractPlayerHead(new URL(SIMPLE_PLAYER_SKIN_URL + name + ".png")); + } + + @NotNull + private BufferedImage getPlayerHeadBySkinUrl(String skinUrl) throws IOException { + return extractPlayerHead(new URL(skinUrl)); + } + + @NotNull + private BufferedImage extractPlayerHead(URL url) throws IOException { + return extractPlayerHead(ImageIO.read(url)); + } + + @NotNull + private BufferedImage extractPlayerHead(BufferedImage skin) { + BufferedImage head = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = head.createGraphics(); + g2d.setColor(Color.black); + g2d.fillRect(0, 0, 20, 20); + g2d.drawImage(skin, 2, 2, 18, 18, 8, 8, 16, 16, null); + g2d.dispose(); + skin.flush(); + return head; + } +} diff --git a/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java b/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java deleted file mode 100644 index 27a023cb0..000000000 --- a/src/main/java/amidst/mojangapi/file/service/PlayerSkinService.java +++ /dev/null @@ -1,59 +0,0 @@ -package amidst.mojangapi.file.service; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.Optional; - -import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.JsonReader; -import amidst.mojangapi.file.json.player.PlayerJson; -import amidst.mojangapi.file.json.player.PropertyJson; -import amidst.mojangapi.file.json.player.SKINJson; -import amidst.mojangapi.file.json.player.TexturesJson; -import amidst.mojangapi.file.json.player.TexturesPropertyJson; - -@Immutable -public class PlayerSkinService { - @NotNull - public String getSkinUrl(PlayerJson playerJson) throws MojangApiParsingException { - return readTexturesProperty(playerJson) - .map(TexturesPropertyJson::getTextures) - .map(TexturesJson::getSKIN) - .map(SKINJson::getUrl) - .orElseThrow(() -> new MojangApiParsingException("unable to get skin url")); - } - - @NotNull - private Optional readTexturesProperty(PlayerJson playerJson) - throws MojangApiParsingException { - for (PropertyJson property : playerJson.getProperties()) { - if (isTexturesProperty(property)) { - return Optional.of(JsonReader.readString(getDecodedValue(property), TexturesPropertyJson.class)); - } - } - return Optional.empty(); - } - - private boolean isTexturesProperty(PropertyJson propertyJson) throws MojangApiParsingException { - String name = propertyJson.getName(); - if (name == null) { - throw new MojangApiParsingException("property has no name"); - } else { - return name.equals("textures"); - } - } - - @NotNull - private String getDecodedValue(PropertyJson propertyJson) throws MojangApiParsingException { - String value = propertyJson.getValue(); - if (value == null) { - throw new MojangApiParsingException("unable to decode property value"); - } else { - return new String( - Base64.getDecoder().decode(value.getBytes(StandardCharsets.UTF_8)), - StandardCharsets.UTF_8); - } - } -} diff --git a/src/main/java/amidst/mojangapi/world/player/Player.java b/src/main/java/amidst/mojangapi/world/player/Player.java index 37506e330..7c44fc174 100644 --- a/src/main/java/amidst/mojangapi/world/player/Player.java +++ b/src/main/java/amidst/mojangapi/world/player/Player.java @@ -23,7 +23,7 @@ public Player(PlayerInformation playerInformation, PlayerNbt playerNbt) { } public String getPlayerName() { - return playerInformation.getNameOrUUID(); + return playerInformation.getNameOrElseUUID(); } public WorldIconImage getHead() { diff --git a/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java b/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java index 6c549d50a..937e09c1d 100644 --- a/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java +++ b/src/main/java/amidst/mojangapi/world/player/PlayerInformation.java @@ -1,13 +1,7 @@ package amidst.mojangapi.world.player; -import java.awt.image.BufferedImage; - import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.PlayerInformationRetriever; -import amidst.mojangapi.file.json.player.PlayerJson; -import amidst.mojangapi.file.service.PlayerSkinService; import amidst.mojangapi.world.icon.WorldIconImage; import amidst.mojangapi.world.icon.type.DefaultWorldIconTypes; @@ -19,64 +13,6 @@ public class PlayerInformation { "The Singleplayer Player", DEFAULT_HEAD); - @NotNull - public static PlayerInformation fromUUID(String uuid) { - PlayerJson player = PlayerInformationRetriever.tryGetPlayerJsonByUUID(uuid); - WorldIconImage head; - if (player != null) { - head = tryGetPlayerHeadBySkinUrl(player); - if (head != null) { - return new PlayerInformation(player.getId(), player.getName(), head); - } else { - return new PlayerInformation(player.getId(), player.getName(), DEFAULT_HEAD); - } - } else { - return new PlayerInformation(uuid, null, DEFAULT_HEAD); - } - } - - @NotNull - public static PlayerInformation fromName(String name) { - PlayerJson player = PlayerInformationRetriever.tryGetPlayerJsonByName(name); - WorldIconImage head; - if (player != null) { - head = tryGetPlayerHeadBySkinUrl(player); - if (head != null) { - return new PlayerInformation(player.getId(), player.getName(), head); - } else { - head = tryGetPlayerHeadByName(name); - if (head != null) { - return new PlayerInformation(player.getId(), player.getName(), head); - } else { - return new PlayerInformation(player.getId(), player.getName(), DEFAULT_HEAD); - } - } - } else { - head = tryGetPlayerHeadByName(name); - if (head != null) { - return new PlayerInformation(null, name, head); - } else { - return new PlayerInformation(null, name, DEFAULT_HEAD); - } - } - } - - private static WorldIconImage tryGetPlayerHeadBySkinUrl(PlayerJson player) { - BufferedImage head; - try { - head = PlayerInformationRetriever.tryGetPlayerHeadBySkinUrl(new PlayerSkinService().getSkinUrl(player)); - return head != null ? WorldIconImage.from(head) : null; - } catch (MojangApiParsingException e) { - return null; - } - } - - private static WorldIconImage tryGetPlayerHeadByName(String name) { - BufferedImage head; - head = PlayerInformationRetriever.tryGetPlayerHeadByName(name); - return head != null ? WorldIconImage.from(head) : null; - } - @NotNull public static PlayerInformation theSingleplayerPlayer() { return THE_SINGLEPLAYER_PLAYER; @@ -86,7 +22,7 @@ public static PlayerInformation theSingleplayerPlayer() { private final String name; private final WorldIconImage head; - private PlayerInformation(String uuid, String name, WorldIconImage head) { + public PlayerInformation(String uuid, String name, WorldIconImage head) { this.uuid = uuid; this.name = name; this.head = head; @@ -104,7 +40,7 @@ public WorldIconImage getHead() { return head; } - public String getNameOrUUID() { + public String getNameOrElseUUID() { if (name != null) { return name; } else { diff --git a/src/main/java/amidst/mojangapi/world/player/PlayerInformationCacheImpl.java b/src/main/java/amidst/mojangapi/world/player/PlayerInformationCacheImpl.java index bf833b865..2e850d155 100644 --- a/src/main/java/amidst/mojangapi/world/player/PlayerInformationCacheImpl.java +++ b/src/main/java/amidst/mojangapi/world/player/PlayerInformationCacheImpl.java @@ -6,6 +6,7 @@ import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.service.PlayerInformationService; /** * Even though this class is thread-safe, it is possible that the same player @@ -18,6 +19,7 @@ public class PlayerInformationCacheImpl implements PlayerInformationCache { private final Map byUUID = new ConcurrentHashMap<>(); private final Map byName = new ConcurrentHashMap<>(); + private final PlayerInformationService playerInformationService = new PlayerInformationService(); @NotNull @Override @@ -28,7 +30,7 @@ public PlayerInformation getByUUID(String uuid) { return result; } else { AmidstLogger.info("requesting player information for uuid: " + cleanUUID); - result = PlayerInformation.fromUUID(cleanUUID); + result = playerInformationService.fromUUID(cleanUUID); put(result); return result; } @@ -42,7 +44,7 @@ public PlayerInformation getByName(String name) { return result; } else { AmidstLogger.info("requesting player information for name: " + name); - result = PlayerInformation.fromName(name); + result = playerInformationService.fromName(name); put(result); return result; } From a4f5e571ee7f59763e7ebdf7e6a7b71420029f32 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 04:37:12 +0200 Subject: [PATCH 16/48] moved code to DotMinecraftDirectoryService --- .../profileselect/LocalProfileComponent.java | 8 ++- src/main/java/amidst/mojangapi/MojangApi.java | 20 +----- .../amidst/mojangapi/MojangApiBuilder.java | 22 ++---- .../file/directory/VersionDirectory.java | 2 + .../file/service/AmidstBackupService.java | 2 +- .../file/service/ClassLoaderService.java | 4 +- .../service/DotMinecraftDirectoryService.java | 68 +++++++++++++++---- .../file/service/DownloadService.java | 40 +++++------ 8 files changed, 93 insertions(+), 73 deletions(-) diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index db08b809b..fb3c3c0fe 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -57,8 +57,12 @@ private void initDirectoriesLater() { private boolean tryFind() { DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); try { - profileDirectory = dotMinecraftDirectoryService.createValidProfileDirectory(profile, mojangApi); - versionDirectory = dotMinecraftDirectoryService.createValidVersionDirectory(profile, mojangApi); + profileDirectory = dotMinecraftDirectoryService + .createValidProfileDirectory(profile, mojangApi.getDotMinecraftDirectory()); + versionDirectory = dotMinecraftDirectoryService.createValidVersionDirectory( + profile, + mojangApi.getVersionList(), + mojangApi.getDotMinecraftDirectory()); return true; } catch (FileNotFoundException e) { AmidstLogger.warn(e); diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 56a7cea50..8f31d3296 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -11,7 +11,6 @@ import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.file.service.SaveDirectoryService; import amidst.mojangapi.file.service.VersionListService; import amidst.mojangapi.minecraftinterface.MinecraftInterface; @@ -27,7 +26,6 @@ @ThreadSafe public class MojangApi { - private static final String UNKNOWN_VERSION_ID = "unknown"; private static final String UNKNOWN_PROFILE_NAME = "unknown"; private final WorldBuilder worldBuilder; @@ -81,22 +79,6 @@ public void set(String profileName, ProfileDirectory profileDirectory, VersionDi } } - public VersionDirectory createVersionDirectory(String versionId) { - File versions = dotMinecraftDirectory.getVersions(); - FilenameService filenameService = new FilenameService(); - File jar = filenameService.getClientJarFile(versions, versionId); - File json = filenameService.getClientJsonFile(versions, versionId); - return doCreateVersionDirectory(versionId, jar, json); - } - - public VersionDirectory createVersionDirectory(File jar, File json) { - return doCreateVersionDirectory(UNKNOWN_VERSION_ID, jar, json); - } - - private VersionDirectory doCreateVersionDirectory(String versionId, File jar, File json) { - return new VersionDirectory(versionId, jar, json); - } - public MojangApi createSilentPlayerlessCopy() { MojangApi result = new MojangApi(WorldBuilder.createSilentPlayerless(), dotMinecraftDirectory); try { @@ -162,7 +144,7 @@ public String getVersionId() { if (versionDirectory != null) { return versionDirectory.getVersionId(); } else { - return UNKNOWN_VERSION_ID; + return VersionDirectory.UNKNOWN_VERSION_ID; } } diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java index 40c16cfff..10659e64c 100644 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ b/src/main/java/amidst/mojangapi/MojangApiBuilder.java @@ -17,6 +17,7 @@ public class MojangApiBuilder { private final WorldBuilder worldBuilder; private final CommandLineParameters parameters; + private final DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); public MojangApiBuilder(WorldBuilder worldBuilder, CommandLineParameters parameters) { this.worldBuilder = worldBuilder; @@ -27,7 +28,8 @@ public MojangApiBuilder(WorldBuilder worldBuilder, CommandLineParameters paramet public MojangApi construct() throws DotMinecraftDirectoryNotFoundException, LocalMinecraftInterfaceCreationException { - DotMinecraftDirectory dotMinecraftDirectory = createDotMinecraftDirectory(); + DotMinecraftDirectory dotMinecraftDirectory = dotMinecraftDirectoryService + .createDotMinecraftDirectory(parameters.dotMinecraftDirectory, parameters.minecraftLibrariesDirectory); if (dotMinecraftDirectory.isValid()) { AmidstLogger.info( "using '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "', libraries: '" @@ -38,26 +40,16 @@ public MojangApi construct() + dotMinecraftDirectory.getLibraries() + "'"); } MojangApi result = new MojangApi(worldBuilder, dotMinecraftDirectory); - result.set(null, null, createVersionDirectory(result)); + result.set(null, null, createVersionDirectory()); return result; } - @NotNull - private DotMinecraftDirectory createDotMinecraftDirectory() { - File dotMinecraftDirectory = new DotMinecraftDirectoryService() - .createDotMinecraftDirectory(parameters.dotMinecraftDirectory); - if (parameters.minecraftLibrariesDirectory != null) { - return new DotMinecraftDirectory(dotMinecraftDirectory, new File(parameters.minecraftLibrariesDirectory)); - } else { - return new DotMinecraftDirectory(dotMinecraftDirectory); - } - } - - private VersionDirectory createVersionDirectory(MojangApi mojangApi) { + private VersionDirectory createVersionDirectory() { if (parameters.minecraftJarFile != null && parameters.minecraftJsonFile != null) { File jar = new File(parameters.minecraftJarFile); File json = new File(parameters.minecraftJsonFile); - VersionDirectory result = mojangApi.createVersionDirectory(jar, json); + VersionDirectory result = dotMinecraftDirectoryService + .createVersionDirectoryWithUnknownVersionId(jar, json); if (result.isValid()) { AmidstLogger.info( "using minecraft version directory. versionId: '" + result.getVersionId() + "', jar file: '" diff --git a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java index d6dd48f88..3d854998e 100644 --- a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java @@ -6,6 +6,8 @@ @Immutable public class VersionDirectory { + public static final String UNKNOWN_VERSION_ID = "unknown"; + private final String versionId; private final File jar; private final File json; diff --git a/src/main/java/amidst/mojangapi/file/service/AmidstBackupService.java b/src/main/java/amidst/mojangapi/file/service/AmidstBackupService.java index e3a1795c0..ddce2fbd8 100644 --- a/src/main/java/amidst/mojangapi/file/service/AmidstBackupService.java +++ b/src/main/java/amidst/mojangapi/file/service/AmidstBackupService.java @@ -39,7 +39,7 @@ private String millis() { .replace(".", "_"); } - public boolean tryBackup(File toDirectory, File from, File to) { + private boolean tryBackup(File toDirectory, File from, File to) { return ensureDirectoryExists(toDirectory) && tryCopy(from, to) && to.isFile(); } diff --git a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index 61db92614..db955b988 100644 --- a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -19,6 +19,8 @@ @Immutable public class ClassLoaderService { + private final LibraryService libraryService = new LibraryService(); + @NotNull public URLClassLoader createClassLoader( VersionDirectory versionDirectory, @@ -56,7 +58,7 @@ private List getAllLibraryUrls( DotMinecraftDirectory dotMinecraftDirectory) { File json = versionDirectory.getJson(); try { - return new LibraryService().getLibraryUrls( + return libraryService.getLibraryUrls( dotMinecraftDirectory.getLibraries(), JsonReader.readLocation(json, VersionJson.class).getLibraries()); } catch (IOException | MojangApiParsingException e) { diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index 20954fc41..2518824f0 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -8,7 +8,6 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; @@ -18,23 +17,40 @@ import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; +import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.util.OperatingSystemDetector; @Immutable public class DotMinecraftDirectoryService { + private final FilenameService filenameService = new FilenameService(); + + @NotNull + public DotMinecraftDirectory createDotMinecraftDirectory( + String preferredDotMinecraftDirectory, + String preferredLibrariesDirectory) { + File dotMinecraftDirectory = findDotMinecraftDirectory(preferredDotMinecraftDirectory); + if (preferredLibrariesDirectory != null) { + return new DotMinecraftDirectory(dotMinecraftDirectory, new File(preferredLibrariesDirectory)); + } else { + return new DotMinecraftDirectory(dotMinecraftDirectory); + } + } + @NotNull - public File createDotMinecraftDirectory(String dotMinecraftCMDParameter) { - if (dotMinecraftCMDParameter != null) { - File result = new File(dotMinecraftCMDParameter); + private File findDotMinecraftDirectory(String preferredDotMinecraftDirectory) { + if (preferredDotMinecraftDirectory != null) { + File result = new File(preferredDotMinecraftDirectory); if (result.isDirectory()) { return result; } else { AmidstLogger.warn( "Unable to set Minecraft directory to: " + result + " as that location does not exist or is not a folder."); + return getMinecraftDirectory(); } + } else { + return getMinecraftDirectory(); } - return getMinecraftDirectory(); } @NotNull @@ -59,8 +75,9 @@ public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMi } @NotNull - public ProfileDirectory createValidProfileDirectory(LauncherProfileJson launcherProfileJson, MojangApi mojangApi) - throws FileNotFoundException { + public ProfileDirectory createValidProfileDirectory( + LauncherProfileJson launcherProfileJson, + DotMinecraftDirectory dotMinecraftDirectory) throws FileNotFoundException { String gameDir = launcherProfileJson.getGameDir(); if (gameDir != null) { ProfileDirectory result = new ProfileDirectory(new File(gameDir)); @@ -72,25 +89,32 @@ public ProfileDirectory createValidProfileDirectory(LauncherProfileJson launcher + "': " + gameDir); } } else { - return new ProfileDirectory(mojangApi.getDotMinecraftDirectory().getRoot()); + return new ProfileDirectory(dotMinecraftDirectory.getRoot()); } } @NotNull - public VersionDirectory createValidVersionDirectory(LauncherProfileJson launcherProfileJson, MojangApi mojangApi) - throws FileNotFoundException { + public VersionDirectory createValidVersionDirectory( + LauncherProfileJson launcherProfileJson, + VersionListJson versionList, + DotMinecraftDirectory dotMinecraftDirectory) throws FileNotFoundException { String lastVersionId = launcherProfileJson.getLastVersionId(); if (lastVersionId != null) { - VersionDirectory result = mojangApi.createVersionDirectory(lastVersionId); + VersionDirectory result = createVersionDirectory(dotMinecraftDirectory, lastVersionId); if (result.isValid()) { return result; + } else { + // error } } else { VersionDirectory result = tryFindFirstValidVersionDirectory( launcherProfileJson.getAllowedReleaseTypes(), - mojangApi); + versionList, + dotMinecraftDirectory); if (result != null) { return result; + } else { + // error } } throw new FileNotFoundException( @@ -99,10 +123,11 @@ public VersionDirectory createValidVersionDirectory(LauncherProfileJson launcher private VersionDirectory tryFindFirstValidVersionDirectory( List allowedReleaseTypes, - MojangApi mojangApi) throws FileNotFoundException { - for (VersionListEntryJson version : mojangApi.getVersionList().getVersions()) { + VersionListJson versionList, + DotMinecraftDirectory dotMinecraftDirectory) { + for (VersionListEntryJson version : versionList.getVersions()) { if (allowedReleaseTypes.contains(version.getType())) { - VersionDirectory versionDirectory = mojangApi.createVersionDirectory(version.getId()); + VersionDirectory versionDirectory = createVersionDirectory(dotMinecraftDirectory, version.getId()); if (versionDirectory.isValid()) { return versionDirectory; } @@ -110,4 +135,17 @@ private VersionDirectory tryFindFirstValidVersionDirectory( } return null; } + + @NotNull + public VersionDirectory createVersionDirectory(DotMinecraftDirectory dotMinecraftDirectory, String versionId) { + File versions = dotMinecraftDirectory.getVersions(); + File jar = filenameService.getClientJarFile(versions, versionId); + File json = filenameService.getClientJsonFile(versions, versionId); + return new VersionDirectory(versionId, jar, json); + } + + @NotNull + public VersionDirectory createVersionDirectoryWithUnknownVersionId(File jar, File json) { + return new VersionDirectory(VersionDirectory.UNKNOWN_VERSION_ID, jar, json); + } } diff --git a/src/main/java/amidst/mojangapi/file/service/DownloadService.java b/src/main/java/amidst/mojangapi/file/service/DownloadService.java index b970f1e49..25e09d507 100644 --- a/src/main/java/amidst/mojangapi/file/service/DownloadService.java +++ b/src/main/java/amidst/mojangapi/file/service/DownloadService.java @@ -36,6 +36,26 @@ private static boolean exists(String location) { } } + public boolean tryDownloadServer(String prefix, VersionListEntryJson version) { + try { + downloadServer(prefix, version); + return true; + } catch (IOException e) { + AmidstLogger.warn(e, "unable to download server: " + version.getId()); + } + return false; + } + + public boolean tryDownloadClient(String prefix, VersionListEntryJson version) { + try { + downloadClient(prefix, version); + return true; + } catch (IOException e) { + AmidstLogger.warn(e, "unable to download client: " + version.getId()); + } + return false; + } + public void downloadServer(String prefix, VersionListEntryJson version) throws IOException { download( filenameService.getRemoteServerJar(version.getId()), @@ -65,24 +85,4 @@ private void download(URL from, Path to) throws IOException { Files.copy(in, part, StandardCopyOption.REPLACE_EXISTING); Files.move(part, to, StandardCopyOption.REPLACE_EXISTING); } - - public boolean tryDownloadServer(String prefix, VersionListEntryJson version) { - try { - downloadServer(prefix, version); - return true; - } catch (IOException e) { - AmidstLogger.warn(e, "unable to download server: " + version.getId()); - } - return false; - } - - public boolean tryDownloadClient(String prefix, VersionListEntryJson version) { - try { - downloadClient(prefix, version); - return true; - } catch (IOException e) { - AmidstLogger.warn(e, "unable to download client: " + version.getId()); - } - return false; - } } From 602c2513a89e36c8ce4361b797ac9645b7732e30 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 15:03:32 +0200 Subject: [PATCH 17/48] the JsonReader now throws the more generic FormatException ... ... instead of the MojangApiParsingException. This enables the usage of the JsonReader to parse json that was not provided by Mojang. --- .../mojangapi/file/FormatException.java | 16 +++++++++++++++ .../mojangapi/file/json/JsonReader.java | 20 +++++++++---------- .../file/service/ClassLoaderService.java | 4 ++-- .../service/DotMinecraftDirectoryService.java | 7 ++++++- .../service/PlayerInformationService.java | 13 ++++++------ .../file/service/VersionListService.java | 13 ++++++++++-- 6 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/FormatException.java diff --git a/src/main/java/amidst/mojangapi/file/FormatException.java b/src/main/java/amidst/mojangapi/file/FormatException.java new file mode 100644 index 000000000..a2e09701c --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/FormatException.java @@ -0,0 +1,16 @@ +package amidst.mojangapi.file; + +@SuppressWarnings("serial") +public class FormatException extends Exception { + public FormatException(String message) { + super(message); + } + + public FormatException(Throwable cause) { + super(cause); + } + + public FormatException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/amidst/mojangapi/file/json/JsonReader.java b/src/main/java/amidst/mojangapi/file/json/JsonReader.java index dc04ff7d1..0e6312e05 100644 --- a/src/main/java/amidst/mojangapi/file/json/JsonReader.java +++ b/src/main/java/amidst/mojangapi/file/json/JsonReader.java @@ -11,7 +11,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.URIUtils; /** @@ -26,47 +26,47 @@ public enum JsonReader { private static final Gson GSON = new Gson(); @NotNull - public static T readLocation(File location, Class clazz) throws MojangApiParsingException, IOException { + public static T readLocation(File location, Class clazz) throws FormatException, IOException { return readReader(URIUtils.newReader(location), clazz); } @NotNull - public static T readLocation(URL location, Class clazz) throws MojangApiParsingException, IOException { + public static T readLocation(URL location, Class clazz) throws FormatException, IOException { return readReader(URIUtils.newReader(location), clazz); } @NotNull - public static T readLocation(String location, Class clazz) throws MojangApiParsingException, IOException { + public static T readLocation(String location, Class clazz) throws FormatException, IOException { return readReader(URIUtils.newReader(location), clazz); } @NotNull - private static T readReader(Reader reader, Class clazz) throws MojangApiParsingException, IOException { + private static T readReader(Reader reader, Class clazz) throws FormatException, IOException { try (Reader theReader = reader) { T result = GSON.fromJson(theReader, clazz); if (result != null) { return result; } else { - throw new MojangApiParsingException("result was null"); + throw new FormatException("result was null"); } } catch (JsonSyntaxException e) { - throw new MojangApiParsingException(e); + throw new FormatException(e); } catch (JsonIOException e) { throw new IOException(e); } } @NotNull - public static T readString(String string, Class clazz) throws MojangApiParsingException { + public static T readString(String string, Class clazz) throws FormatException { try { T result = GSON.fromJson(string, clazz); if (result != null) { return result; } else { - throw new MojangApiParsingException("result was null"); + throw new FormatException("result was null"); } } catch (JsonSyntaxException e) { - throw new MojangApiParsingException(e); + throw new FormatException(e); } } } diff --git a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index db955b988..f827404e5 100644 --- a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -11,7 +11,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.JsonReader; @@ -61,7 +61,7 @@ private List getAllLibraryUrls( return libraryService.getLibraryUrls( dotMinecraftDirectory.getLibraries(), JsonReader.readLocation(json, VersionJson.class).getLibraries()); - } catch (IOException | MojangApiParsingException e) { + } catch (IOException | FormatException e) { AmidstLogger.warn("Invalid jar profile loaded. Library loading will be skipped. (Path: " + json + ")"); return new ArrayList<>(); } diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index 2518824f0..f4e34f4f1 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -8,6 +8,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; @@ -71,7 +72,11 @@ private File getMinecraftDirectory() { public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMinecraftDirectory) throws MojangApiParsingException, IOException { - return JsonReader.readLocation(dotMinecraftDirectory.getLauncherProfilesJson(), LauncherProfilesJson.class); + try { + return JsonReader.readLocation(dotMinecraftDirectory.getLauncherProfilesJson(), LauncherProfilesJson.class); + } catch (FormatException e) { + throw new MojangApiParsingException(e); + } } @NotNull diff --git a/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java index f99b6d25c..8e86af1dc 100644 --- a/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java +++ b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java @@ -14,6 +14,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.player.PlayerJson; @@ -95,7 +96,7 @@ private Optional tryReadTexturesProperty(PlayerJson player } } return Optional.empty(); - } catch (MojangApiParsingException e) { + } catch (FormatException | MojangApiParsingException e) { return Optional.empty(); } } @@ -125,7 +126,7 @@ private String getDecodedValue(PropertyJson propertyJson) throws MojangApiParsin private Optional tryGetPlayerJsonByName(String name) { try { return Optional.of(getPlayerJsonByName(name)); - } catch (IOException | MojangApiParsingException | NullPointerException e) { + } catch (IOException | FormatException | NullPointerException e) { AmidstLogger.warn("unable to load player information by name: " + name); return Optional.empty(); } @@ -135,24 +136,24 @@ private Optional tryGetPlayerJsonByName(String name) { private Optional tryGetPlayerJsonByUUID(String uuid) { try { return Optional.of(getPlayerJsonByUUID(uuid)); - } catch (IOException | MojangApiParsingException | NullPointerException e) { + } catch (IOException | FormatException | NullPointerException e) { AmidstLogger.warn("unable to load player information by uuid: " + uuid); return Optional.empty(); } } @NotNull - private PlayerJson getPlayerJsonByName(String name) throws MojangApiParsingException, IOException { + private PlayerJson getPlayerJsonByName(String name) throws FormatException, IOException { return getPlayerJsonByUUID(getUUIDByName(name).getId()); } @NotNull - private PlayerJson getPlayerJsonByUUID(String uuid) throws MojangApiParsingException, IOException { + private PlayerJson getPlayerJsonByUUID(String uuid) throws FormatException, IOException { return JsonReader.readLocation(UUID_TO_PROFILE + uuid, PlayerJson.class); } @NotNull - private SimplePlayerJson getUUIDByName(String name) throws MojangApiParsingException, IOException { + private SimplePlayerJson getUUIDByName(String name) throws FormatException, IOException { return JsonReader.readLocation(PLAYERNAME_TO_UUID + name, SimplePlayerJson.class); } diff --git a/src/main/java/amidst/mojangapi/file/service/VersionListService.java b/src/main/java/amidst/mojangapi/file/service/VersionListService.java index 33c5b2c91..10dc1780e 100644 --- a/src/main/java/amidst/mojangapi/file/service/VersionListService.java +++ b/src/main/java/amidst/mojangapi/file/service/VersionListService.java @@ -8,6 +8,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.versionlist.VersionListJson; @@ -47,11 +48,19 @@ public VersionListJson readRemoteOrLocalVersionList() throws FileNotFoundExcepti @NotNull public VersionListJson readRemoteVersionList() throws MojangApiParsingException, IOException { - return JsonReader.readLocation(REMOTE_VERSION_LIST, VersionListJson.class); + try { + return JsonReader.readLocation(REMOTE_VERSION_LIST, VersionListJson.class); + } catch (FormatException e) { + throw new MojangApiParsingException(e); + } } @NotNull public VersionListJson readLocalVersionListFromResource() throws MojangApiParsingException, IOException { - return JsonReader.readLocation(LOCAL_VERSION_LIST, VersionListJson.class); + try { + return JsonReader.readLocation(LOCAL_VERSION_LIST, VersionListJson.class); + } catch (FormatException e) { + throw new MojangApiParsingException(e); + } } } From f1302a13764bf6e206d5d74b4b395a7900045d1e Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 15:15:40 +0200 Subject: [PATCH 18/48] changed UpdateInformationRetriever to use the JsonReader --- .../gui/main/UpdateInformationRetriever.java | 22 ++++--------------- .../mojangapi/file/json/JsonReader.java | 5 ----- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/main/java/amidst/gui/main/UpdateInformationRetriever.java b/src/main/java/amidst/gui/main/UpdateInformationRetriever.java index 11bea5170..abf913dfb 100644 --- a/src/main/java/amidst/gui/main/UpdateInformationRetriever.java +++ b/src/main/java/amidst/gui/main/UpdateInformationRetriever.java @@ -1,34 +1,20 @@ package amidst.gui.main; import java.io.IOException; -import java.io.Reader; - -import com.google.gson.Gson; -import com.google.gson.JsonIOException; -import com.google.gson.JsonSyntaxException; import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.URIUtils; +import amidst.mojangapi.file.FormatException; +import amidst.mojangapi.file.json.JsonReader; @Immutable public enum UpdateInformationRetriever { ; private static final String UPDATE_INFORMATION_JSON_URL = "https://toolbox4minecraft.github.io/amidst/api/update-information.json"; - private static final Gson GSON = new Gson(); @NotNull - public static UpdateInformationJson retrieve() throws IOException { - try (Reader theReader = URIUtils.newReader(UPDATE_INFORMATION_JSON_URL)) { - UpdateInformationJson result = GSON.fromJson(theReader, UpdateInformationJson.class); - if (result != null) { - return result; - } else { - throw new IOException("result was null"); - } - } catch (JsonSyntaxException | JsonIOException e) { - throw new IOException(e); - } + public static UpdateInformationJson retrieve() throws FormatException, IOException { + return JsonReader.readLocation(UPDATE_INFORMATION_JSON_URL, UpdateInformationJson.class); } } diff --git a/src/main/java/amidst/mojangapi/file/json/JsonReader.java b/src/main/java/amidst/mojangapi/file/json/JsonReader.java index 0e6312e05..1796151ac 100644 --- a/src/main/java/amidst/mojangapi/file/json/JsonReader.java +++ b/src/main/java/amidst/mojangapi/file/json/JsonReader.java @@ -14,11 +14,6 @@ import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.URIUtils; -/** - * This is a utility class used to read JSON data. Please use this class only to - * read JSON data provided by Mojang, because it throws a - * MojangApiParsingException when an error occurs. - */ @Immutable public enum JsonReader { ; From f9db5a736aecd4b848c126ed4c0f01ae9bdb564d Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 15:19:11 +0200 Subject: [PATCH 19/48] moved JsonReader to new package --- src/main/java/amidst/gui/main/UpdateInformationRetriever.java | 4 ++-- .../amidst/mojangapi/file/service/ClassLoaderService.java | 4 ++-- .../mojangapi/file/service/DotMinecraftDirectoryService.java | 4 ++-- .../mojangapi/file/service/PlayerInformationService.java | 4 ++-- .../amidst/mojangapi/file/service/VersionListService.java | 4 ++-- .../amidst/{mojangapi/file => parsing}/FormatException.java | 2 +- .../amidst/{mojangapi/file => parsing}/json/JsonReader.java | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) rename src/main/java/amidst/{mojangapi/file => parsing}/FormatException.java (90%) rename src/main/java/amidst/{mojangapi/file => parsing}/json/JsonReader.java (95%) diff --git a/src/main/java/amidst/gui/main/UpdateInformationRetriever.java b/src/main/java/amidst/gui/main/UpdateInformationRetriever.java index abf913dfb..a8c5daca0 100644 --- a/src/main/java/amidst/gui/main/UpdateInformationRetriever.java +++ b/src/main/java/amidst/gui/main/UpdateInformationRetriever.java @@ -4,8 +4,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.FormatException; -import amidst.mojangapi.file.json.JsonReader; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; @Immutable public enum UpdateInformationRetriever { diff --git a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index f827404e5..6d2e01d40 100644 --- a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -11,11 +11,11 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.version.VersionJson; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; @Immutable public class ClassLoaderService { diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index f4e34f4f1..bc50e807b 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -8,17 +8,17 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; import amidst.util.OperatingSystemDetector; @Immutable diff --git a/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java index 8e86af1dc..b9df9f66a 100644 --- a/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java +++ b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java @@ -14,9 +14,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.player.PlayerJson; import amidst.mojangapi.file.json.player.PropertyJson; import amidst.mojangapi.file.json.player.SKINJson; @@ -26,6 +24,8 @@ import amidst.mojangapi.world.icon.WorldIconImage; import amidst.mojangapi.world.icon.type.DefaultWorldIconTypes; import amidst.mojangapi.world.player.PlayerInformation; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; @Immutable public class PlayerInformationService { diff --git a/src/main/java/amidst/mojangapi/file/service/VersionListService.java b/src/main/java/amidst/mojangapi/file/service/VersionListService.java index 10dc1780e..4c8e65e6b 100644 --- a/src/main/java/amidst/mojangapi/file/service/VersionListService.java +++ b/src/main/java/amidst/mojangapi/file/service/VersionListService.java @@ -8,10 +8,10 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.JsonReader; import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; @Immutable public class VersionListService { diff --git a/src/main/java/amidst/mojangapi/file/FormatException.java b/src/main/java/amidst/parsing/FormatException.java similarity index 90% rename from src/main/java/amidst/mojangapi/file/FormatException.java rename to src/main/java/amidst/parsing/FormatException.java index a2e09701c..a6af43d9a 100644 --- a/src/main/java/amidst/mojangapi/file/FormatException.java +++ b/src/main/java/amidst/parsing/FormatException.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.parsing; @SuppressWarnings("serial") public class FormatException extends Exception { diff --git a/src/main/java/amidst/mojangapi/file/json/JsonReader.java b/src/main/java/amidst/parsing/json/JsonReader.java similarity index 95% rename from src/main/java/amidst/mojangapi/file/json/JsonReader.java rename to src/main/java/amidst/parsing/json/JsonReader.java index 1796151ac..ff321931c 100644 --- a/src/main/java/amidst/mojangapi/file/json/JsonReader.java +++ b/src/main/java/amidst/parsing/json/JsonReader.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.json; +package amidst.parsing.json; import java.io.File; import java.io.IOException; @@ -11,8 +11,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.FormatException; import amidst.mojangapi.file.URIUtils; +import amidst.parsing.FormatException; @Immutable public enum JsonReader { From 1721b4b9cd96aa95b0b15bf0e764b3830f780ab8 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 15:27:20 +0200 Subject: [PATCH 20/48] switched remaining simple Gson usages to use the JsonReader --- .../json/filter/WorldFilterJson_MatchAll.java | 11 ++++------ .../biomeprofile/BiomeProfileDirectory.java | 22 ++++--------------- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/json/filter/WorldFilterJson_MatchAll.java b/src/main/java/amidst/mojangapi/file/json/filter/WorldFilterJson_MatchAll.java index 6eda53128..5704944d5 100644 --- a/src/main/java/amidst/mojangapi/file/json/filter/WorldFilterJson_MatchAll.java +++ b/src/main/java/amidst/mojangapi/file/json/filter/WorldFilterJson_MatchAll.java @@ -6,27 +6,24 @@ import java.util.List; import java.util.Optional; -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; - import amidst.documentation.GsonConstructor; import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; import amidst.mojangapi.world.filter.WorldFilter; import amidst.mojangapi.world.filter.WorldFilter_MatchAll; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; @Immutable public class WorldFilterJson_MatchAll { public static Optional from(String queryString) { try { - return Optional.ofNullable(GSON.fromJson(queryString, WorldFilterJson_MatchAll.class)); - } catch (JsonSyntaxException e) { + return Optional.of(JsonReader.readString(queryString, WorldFilterJson_MatchAll.class)); + } catch (FormatException e) { return Optional.empty(); } } - private static final Gson GSON = new Gson(); - private volatile List biomeFilters = Collections.emptyList(); private volatile List structureFilters = Collections.emptyList(); diff --git a/src/main/java/amidst/settings/biomeprofile/BiomeProfileDirectory.java b/src/main/java/amidst/settings/biomeprofile/BiomeProfileDirectory.java index 8052ec548..10178352b 100644 --- a/src/main/java/amidst/settings/biomeprofile/BiomeProfileDirectory.java +++ b/src/main/java/amidst/settings/biomeprofile/BiomeProfileDirectory.java @@ -1,16 +1,12 @@ package amidst.settings.biomeprofile; -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; -import com.google.gson.Gson; -import com.google.gson.JsonIOException; -import com.google.gson.JsonSyntaxException; - import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; @Immutable public class BiomeProfileDirectory { @@ -29,7 +25,6 @@ private static File getRoot(String root) { } private static final File DEFAULT_ROOT_DIRECTORY = new File("biome"); - private static final Gson GSON = new Gson(); private final File root; private final File defaultProfile; @@ -95,21 +90,12 @@ private BiomeProfile createFromFile(File file) { BiomeProfile profile = null; if (file.exists() && file.isFile()) { try { - profile = readProfile(file); - if (profile == null) { - throw new NullPointerException(); - } + profile = JsonReader.readLocation(file, BiomeProfile.class); profile.validate(); - } catch (JsonSyntaxException | JsonIOException | IOException | NullPointerException e) { + } catch (IOException | FormatException e) { AmidstLogger.warn(e, "Unable to load file: " + file); } } return profile; } - - private BiomeProfile readProfile(File file) throws IOException, JsonSyntaxException, JsonIOException { - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - return GSON.fromJson(reader, BiomeProfile.class); - } - } } From 93bf87e5903d441d6db94786398e908d167dd4d5 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Sun, 28 May 2017 15:54:40 +0200 Subject: [PATCH 21/48] added VersionListProvider --- .../amidst/mojangapi/VersionListProvider.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/amidst/mojangapi/VersionListProvider.java diff --git a/src/main/java/amidst/mojangapi/VersionListProvider.java b/src/main/java/amidst/mojangapi/VersionListProvider.java new file mode 100644 index 000000000..4d0c2cfe1 --- /dev/null +++ b/src/main/java/amidst/mojangapi/VersionListProvider.java @@ -0,0 +1,41 @@ +package amidst.mojangapi; + +import java.io.IOException; + +import amidst.documentation.AmidstThread; +import amidst.documentation.CalledOnlyBy; +import amidst.documentation.ThreadSafe; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.VersionListService; + +@ThreadSafe +public class VersionListProvider { + public static VersionListProvider create() throws MojangApiParsingException, IOException { + VersionListService versionListService = new VersionListService(); + return new VersionListProvider(versionListService, versionListService.readLocalVersionListFromResource()); + } + + private final VersionListService versionListService; + private final VersionListJson local; + private volatile VersionListJson remote; + + public VersionListProvider(VersionListService versionListService, VersionListJson local) { + this.versionListService = versionListService; + this.local = local; + } + + @CalledOnlyBy(AmidstThread.WORKER) + public void startDownload() throws MojangApiParsingException, IOException { + remote = versionListService.readRemoteVersionList(); + } + + public VersionListJson getRemoteOrElseLocal() { + VersionListJson remote = this.remote; + if (remote != null) { + return remote; + } else { + return local; + } + } +} From d7725a8de3f20cde3f15e687787840c796e81238 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Wed, 31 May 2017 19:08:14 +0200 Subject: [PATCH 22/48] the version .json file is now required ... ... not sure if it was implicitly required before --- .../file/service/ClassLoaderService.java | 50 +++---------------- .../local/LocalMinecraftInterfaceBuilder.java | 12 ++--- .../GenerateRecognisedVersionList.java | 7 +-- 3 files changed, 17 insertions(+), 52 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index 6d2e01d40..93668eee3 100644 --- a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -1,11 +1,8 @@ package amidst.mojangapi.file.service; -import java.io.File; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; import java.util.List; import amidst.documentation.Immutable; @@ -24,46 +21,13 @@ public class ClassLoaderService { @NotNull public URLClassLoader createClassLoader( VersionDirectory versionDirectory, - DotMinecraftDirectory dotMinecraftDirectory) throws MalformedURLException { - if (versionDirectory.getJson().isFile()) { - AmidstLogger.info("Loading libraries."); - return doCreateClassLoader( - getJarFileUrl(versionDirectory), - getAllLibraryUrls(versionDirectory, dotMinecraftDirectory)); - } else { - AmidstLogger - .info("Unable to find Minecraft library JSON at: " + versionDirectory.getJson() + ". Skipping."); - return doCreateClassLoader(getJarFileUrl(versionDirectory)); - } - } - - @NotNull - private URLClassLoader doCreateClassLoader(URL jarFileUrl, List libraries) { - libraries.add(jarFileUrl); + DotMinecraftDirectory dotMinecraftDirectory) throws FormatException, IOException { + AmidstLogger.info("Loading libraries."); + VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); + List libraries = libraryService + .getLibraryUrls(dotMinecraftDirectory.getLibraries(), versionJson.getLibraries()); + libraries.add(versionDirectory.getJar().toURI().toURL()); + AmidstLogger.info("Finished loading libraries."); return new URLClassLoader(libraries.toArray(new URL[libraries.size()])); } - - @NotNull - private URLClassLoader doCreateClassLoader(URL jarFileUrl) { - return new URLClassLoader(new URL[] { jarFileUrl }); - } - - @NotNull - private URL getJarFileUrl(VersionDirectory versionDirectory) throws MalformedURLException { - return versionDirectory.getJar().toURI().toURL(); - } - - private List getAllLibraryUrls( - VersionDirectory versionDirectory, - DotMinecraftDirectory dotMinecraftDirectory) { - File json = versionDirectory.getJson(); - try { - return libraryService.getLibraryUrls( - dotMinecraftDirectory.getLibraries(), - JsonReader.readLocation(json, VersionJson.class).getLibraries()); - } catch (IOException | FormatException e) { - AmidstLogger.warn("Invalid jar profile loaded. Library loading will be skipped. (Path: " + json + ")"); - return new ArrayList<>(); - } - } } diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java index 2eac9a4dd..6ec94dba5 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java @@ -1,7 +1,6 @@ package amidst.mojangapi.minecraftinterface.local; -import java.io.FileNotFoundException; -import java.net.MalformedURLException; +import java.io.IOException; import java.net.URLClassLoader; import java.util.Map; @@ -17,6 +16,7 @@ import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.service.ClassLoaderService; import amidst.mojangapi.minecraftinterface.RecognisedVersion; +import amidst.parsing.FormatException; @Immutable public class LocalMinecraftInterfaceBuilder { @@ -45,11 +45,11 @@ public LocalMinecraftInterface create( symbolicClassMap.get(SymbolicNames.CLASS_GEN_OPTIONS_FACTORY), recognisedVersion); } catch ( - MalformedURLException - | ClassNotFoundException - | FileNotFoundException + ClassNotFoundException | JarFileParsingException - | SymbolicClassGraphCreationException e) { + | SymbolicClassGraphCreationException + | FormatException + | IOException e) { throw new LocalMinecraftInterfaceCreationException("unable to create local minecraft interface", e); } } diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 589f203a7..3ea9aea47 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -1,7 +1,7 @@ package amidst.devtools; import java.io.File; -import java.net.MalformedURLException; +import java.io.IOException; import java.net.URLClassLoader; import java.util.LinkedList; import java.util.List; @@ -16,6 +16,7 @@ import amidst.mojangapi.file.service.DownloadService; import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.minecraftinterface.RecognisedVersion; +import amidst.parsing.FormatException; public class GenerateRecognisedVersionList { private final String prefix; @@ -50,7 +51,7 @@ private void process(VersionListEntryJson version) { if (new DownloadService().tryDownloadClient(prefix, version)) { try { process(versionId); - } catch (ClassNotFoundException | MalformedURLException | NoClassDefFoundError e) { + } catch (ClassNotFoundException | NoClassDefFoundError | FormatException | IOException e) { e.printStackTrace(); versionsWithError.add(versionId); } @@ -59,7 +60,7 @@ private void process(VersionListEntryJson version) { } } - private void process(String versionId) throws MalformedURLException, ClassNotFoundException { + private void process(String versionId) throws ClassNotFoundException, FormatException, IOException { AmidstLogger.info("version " + versionId); VersionDirectory versionDirectory = createVersionDirectory(versionId); URLClassLoader classLoader = new ClassLoaderService() From 83ab995d71252ab1c9aa4b9d1f68ab50391b8542 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Wed, 31 May 2017 19:56:56 +0200 Subject: [PATCH 23/48] refactored LibraryService --- .../file/service/ClassLoaderService.java | 3 - .../file/service/LibraryService.java | 143 +++++++++--------- 2 files changed, 69 insertions(+), 77 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index 93668eee3..eb7134886 100644 --- a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -7,7 +7,6 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.version.VersionJson; @@ -22,12 +21,10 @@ public class ClassLoaderService { public URLClassLoader createClassLoader( VersionDirectory versionDirectory, DotMinecraftDirectory dotMinecraftDirectory) throws FormatException, IOException { - AmidstLogger.info("Loading libraries."); VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); List libraries = libraryService .getLibraryUrls(dotMinecraftDirectory.getLibraries(), versionJson.getLibraries()); libraries.add(versionDirectory.getJar().toURI().toURL()); - AmidstLogger.info("Finished loading libraries."); return new URLClassLoader(libraries.toArray(new URL[libraries.size()])); } } diff --git a/src/main/java/amidst/mojangapi/file/service/LibraryService.java b/src/main/java/amidst/mojangapi/file/service/LibraryService.java index 6e4b3f453..276d1c9cf 100644 --- a/src/main/java/amidst/mojangapi/file/service/LibraryService.java +++ b/src/main/java/amidst/mojangapi/file/service/LibraryService.java @@ -4,7 +4,10 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.regex.Pattern; import amidst.documentation.Immutable; @@ -22,35 +25,34 @@ public class LibraryService { @NotNull public List getLibraryUrls(File librariesDirectory, List libraries) { List result = new ArrayList<>(); + AmidstLogger.info("Loading libraries."); for (LibraryJson library : libraries) { - File libraryFile = getLibraryFile(librariesDirectory, library); - if (libraryFile != null) { - try { - result.add(libraryFile.toURI().toURL()); - AmidstLogger.info("Found library: " + libraryFile); - } catch (MalformedURLException e) { - AmidstLogger.warn(e, "Unable to convert library file to URL: " + libraryFile); + if (isLibraryActive(library)) { + Optional libraryFile = getLibraryFile(librariesDirectory, library); + if (libraryFile.isPresent()) { + try { + URL libraryUrl = libraryFile.get().toURI().toURL(); + result.add(libraryUrl); + AmidstLogger.info("Found library " + library.getName() + " at " + libraryUrl); + } catch (MalformedURLException e) { + AmidstLogger.warn(e, "Skipping erroneous library " + library.getName()); + } + } else { + AmidstLogger.warn("Skipping missing library " + library.getName()); } } else { - AmidstLogger.info("Skipping library: " + library.getName()); + AmidstLogger.info("Skipping inactive library " + library.getName()); } } + AmidstLogger.info("Finished loading libraries."); return result; } - private File getLibraryFile(File librariesDirectory, LibraryJson library) { - try { - if (isLibraryActive(library, getOs(), OperatingSystemDetector.getVersion())) { - return getLibraryFile(getLibrarySearchPath(librariesDirectory, library.getName())); - } else { - return null; - } - } catch (NullPointerException e) { - return null; - } + private boolean isLibraryActive(LibraryJson library) { + return isLibraryActive(getOsName(), OperatingSystemDetector.getVersion(), library.getRules()); } - private String getOs() { + private String getOsName() { if (OperatingSystemDetector.isWindows()) { return "windows"; } else if (OperatingSystemDetector.isMac()) { @@ -60,81 +62,74 @@ private String getOs() { } } - private File getLibrarySearchPath(File librariesDirectory, String libraryName) { - String result = librariesDirectory.getAbsolutePath() + "/"; - String[] split = libraryName.split(":"); - split[0] = split[0].replace('.', '/'); - for (String element : split) { - result += element + "/"; - } - return new File(result); - } - - private File getLibraryFile(File librarySearchPath) { - if (librarySearchPath.exists()) { - File result = getFirstFileWithExtension(librarySearchPath.listFiles(), "jar"); - if (result != null && result.exists()) { - return result; - } else { - AmidstLogger.warn( - "Attempted to search for file at path: " + librarySearchPath + " but found nothing. Skipping."); - return null; - } - } else { - AmidstLogger.warn("Failed attempt to load library at: " + librarySearchPath); - return null; - } - } - - private File getFirstFileWithExtension(File[] files, String extension) { - for (File libraryFile : files) { - if (getFileExtension(libraryFile.getName()).equals(extension)) { - return libraryFile; - } - } - return null; - } - - private String getFileExtension(String fileName) { - String extension = ""; - int q = fileName.lastIndexOf('.'); - if (q > 0) { - extension = fileName.substring(q + 1); - } - return extension; - } - /** * Note, that multiple rules might be applicable. We take the last * applicable rule. However, this might be wrong so we need to take the most * specific rule? For now this works fine. */ - private boolean isLibraryActive(LibraryJson libraryJson, String os, String version) { - List rules = libraryJson.getRules(); + private boolean isLibraryActive(String osName, String osVersion, List rules) { if (rules.isEmpty()) { return true; } boolean result = false; for (LibraryRuleJson rule : rules) { - if (isApplicable(os, version, rule)) { + if (isApplicable(osName, osVersion, rule)) { result = isAllowed(rule); } } return result; } - private boolean isApplicable(String os, String version, LibraryRuleJson rule) { + private boolean isApplicable(String osName, String osVersion, LibraryRuleJson rule) { LibraryRuleOsJson osRule = rule.getOs(); - return osRule == null || isApplicable(os, version, osRule); + return osRule == null || Objects.equals(osRule.getName(), osName) + && (osRule.getVersion() == null || Pattern.matches(osRule.getVersion(), osVersion)); } - private boolean isApplicable(String os, String version, LibraryRuleOsJson osRule) { - String nameInJson = osRule.getName(); - String versionInJson = osRule.getVersion(); - return nameInJson.equals(os) && (versionInJson == null || Pattern.matches(versionInJson, version)); + private boolean isAllowed(LibraryRuleJson rule) { + return Objects.equals(rule.getAction(), ACTION_ALLOW); } - private boolean isAllowed(LibraryRuleJson rule) { - return rule.getAction().equals(ACTION_ALLOW); + private Optional getLibraryFile(File librariesDirectory, LibraryJson library) { + return Arrays + .stream(getLibrarySearchFiles(librariesDirectory, library)) + .filter(f -> hasFileExtension(f, "jar")) + .findFirst() + .filter(File::exists); + } + + private File[] getLibrarySearchFiles(File librariesDirectory, LibraryJson library) { + return getLibrarySearchFiles(getLibrarySearchPath(librariesDirectory.getAbsolutePath(), library.getName())); + } + + private File getLibrarySearchPath(String librariesDirectory, String libraryName) { + String result = librariesDirectory + "/"; + String[] split = libraryName.split(":"); + split[0] = split[0].replace('.', '/'); + for (String element : split) { + result += element + "/"; + } + return new File(result); + } + + private File[] getLibrarySearchFiles(File librarySearchPath) { + if (librarySearchPath.isDirectory()) { + return librarySearchPath.listFiles(); + } else { + return new File[0]; + } + } + + private boolean hasFileExtension(File file, String extension) { + return getFileExtension(file.getName()).equals(extension); + } + + private String getFileExtension(String fileName) { + int index = fileName.lastIndexOf('.'); + if (index > 0) { + return fileName.substring(index + 1); + } else { + return ""; + } } } From 213a9560d53bbef2da9ead5b503c620935d4e607 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Wed, 31 May 2017 21:52:11 +0200 Subject: [PATCH 24/48] refactored LevelDatNbt --- .../mojangapi/file/nbt/LevelDatNbt.java | 83 ++++++++++++------- .../file/service/SaveDirectoryService.java | 2 +- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java b/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java index 7030676f6..f6ea237ed 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java @@ -9,66 +9,91 @@ @Immutable public class LevelDatNbt { - private final long seed; - private final CoordinatesInWorld worldSpawn; - private final WorldType worldType; - private final String generatorOptions; - private final boolean hasPlayer; - - public LevelDatNbt(CompoundTag root) throws MojangApiParsingException { + public static LevelDatNbt from(CompoundTag root) throws MojangApiParsingException { try { CompoundTag dataTag = readDataTag(root); - this.seed = readRandomSeed(dataTag); - this.worldSpawn = CoordinatesInWorld.from(readSpawnX(dataTag), readSpawnZ(dataTag)); - if (hasGeneratorName(dataTag)) { - this.worldType = WorldType.from(readGeneratorName(dataTag)); - if (worldType == WorldType.CUSTOMIZED) { - this.generatorOptions = readGeneratorOptions(dataTag); - } else { - this.generatorOptions = ""; - } - } else { - this.worldType = WorldType.DEFAULT; - this.generatorOptions = ""; - } - this.hasPlayer = hasPlayerTag(dataTag); + long seed = readRandomSeed(dataTag); + CoordinatesInWorld worldSpawn = readWorldSpawn(dataTag); + WorldType worldType = readWorldType(dataTag); + String generatorOptions = readGeneratorOptions(dataTag, worldType); + boolean hasPlayer = hasPlayerTag(dataTag); + return new LevelDatNbt(seed, worldSpawn, worldType, generatorOptions, hasPlayer); } catch (NullPointerException e) { throw new MojangApiParsingException("cannot read level.dat", e); } } - private CompoundTag readDataTag(CompoundTag root) { + private static CompoundTag readDataTag(CompoundTag root) { return (CompoundTag) root.getValue().get(NBTTagKeys.TAG_KEY_DATA); } - private long readRandomSeed(CompoundTag dataTag) { + private static long readRandomSeed(CompoundTag dataTag) { return NBTUtils.getLongValue(dataTag.getValue().get(NBTTagKeys.TAG_KEY_RANDOM_SEED)); } - private long readSpawnX(CompoundTag dataTag) { + private static CoordinatesInWorld readWorldSpawn(CompoundTag dataTag) { + return CoordinatesInWorld.from(readSpawnX(dataTag), readSpawnZ(dataTag)); + } + + private static long readSpawnX(CompoundTag dataTag) { return NBTUtils.getLongValue(dataTag.getValue().get(NBTTagKeys.TAG_KEY_SPAWN_X)); } - private long readSpawnZ(CompoundTag dataTag) { + private static long readSpawnZ(CompoundTag dataTag) { return NBTUtils.getLongValue(dataTag.getValue().get(NBTTagKeys.TAG_KEY_SPAWN_Z)); } - private boolean hasGeneratorName(CompoundTag dataTag) { + private static WorldType readWorldType(CompoundTag dataTag) { + if (hasGeneratorName(dataTag)) { + return WorldType.from(readGeneratorName(dataTag)); + } else { + return WorldType.DEFAULT; + } + } + + private static boolean hasGeneratorName(CompoundTag dataTag) { return dataTag.getValue().get(NBTTagKeys.TAG_KEY_GENERATOR_NAME) != null; } - private String readGeneratorName(CompoundTag dataTag) { + private static String readGeneratorOptions(CompoundTag dataTag, WorldType worldType) { + if (worldType == WorldType.CUSTOMIZED) { + return readGeneratorOptions(dataTag); + } else { + return ""; + } + } + + private static String readGeneratorName(CompoundTag dataTag) { return (String) dataTag.getValue().get(NBTTagKeys.TAG_KEY_GENERATOR_NAME).getValue(); } - private String readGeneratorOptions(CompoundTag dataTag) { + private static String readGeneratorOptions(CompoundTag dataTag) { return (String) dataTag.getValue().get(NBTTagKeys.TAG_KEY_GENERATOR_OPTIONS).getValue(); } - private boolean hasPlayerTag(CompoundTag dataTag) { + private static boolean hasPlayerTag(CompoundTag dataTag) { return dataTag.getValue().containsKey(NBTTagKeys.TAG_KEY_PLAYER); } + private final long seed; + private final CoordinatesInWorld worldSpawn; + private final WorldType worldType; + private final String generatorOptions; + private final boolean hasPlayer; + + public LevelDatNbt( + long seed, + CoordinatesInWorld worldSpawn, + WorldType worldType, + String generatorOptions, + boolean hasPlayer) { + this.seed = seed; + this.worldSpawn = worldSpawn; + this.worldType = worldType; + this.generatorOptions = generatorOptions; + this.hasPlayer = hasPlayer; + } + public long getSeed() { return seed; } diff --git a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java index e88234b60..1897af417 100644 --- a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java @@ -62,7 +62,7 @@ private SaveDirectory createValidSaveDirectory(File currentFile) { } public LevelDatNbt createLevelDat(SaveDirectory saveDirectory) throws IOException, MojangApiParsingException { - return new LevelDatNbt(NBTUtils.readTagFromFile(saveDirectory.getLevelDat())); + return LevelDatNbt.from(NBTUtils.readTagFromFile(saveDirectory.getLevelDat())); } /** From b34ae7c925b80538139ef1fd21972b56a428166c Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Wed, 31 May 2017 22:14:07 +0200 Subject: [PATCH 25/48] removed dependency from PlayerNbt --- .../mojangapi/file/nbt/player/LevelDatPlayerNbt.java | 9 ++++----- .../java/amidst/mojangapi/file/nbt/player/PlayerNbt.java | 9 ++++++--- .../mojangapi/file/nbt/player/PlayerdataPlayerNbt.java | 8 ++++---- .../mojangapi/file/nbt/player/PlayersPlayerNbt.java | 8 ++++---- .../amidst/mojangapi/world/player/MovablePlayerList.java | 5 ++++- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java index 054e58ac1..ae4858f7c 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java @@ -1,16 +1,15 @@ package amidst.mojangapi.file.nbt.player; import java.io.IOException; +import java.util.function.Function; +import java.util.function.Supplier; import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.file.service.AmidstBackupService; -import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; -import amidst.mojangapi.world.player.PlayerInformation; -import amidst.mojangapi.world.player.PlayerInformationCache; @Immutable public class LevelDatPlayerNbt extends PlayerNbt { @@ -36,7 +35,7 @@ public PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingE } @Override - public Player createPlayer(PlayerInformationCache cache) { - return new Player(PlayerInformation.theSingleplayerPlayer(), this); + public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { + return ifIsLevelDat.get(); } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java index 354141fb2..2656d8fea 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java @@ -1,12 +1,12 @@ package amidst.mojangapi.file.nbt.player; import java.io.IOException; +import java.util.function.Function; +import java.util.function.Supplier; import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; -import amidst.mojangapi.world.player.PlayerInformationCache; @Immutable public abstract class PlayerNbt { @@ -25,5 +25,8 @@ public boolean tryWriteCoordinates(PlayerCoordinates coordinates) throws MojangA public abstract PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingException; - public abstract Player createPlayer(PlayerInformationCache cache); + public abstract R map( + Supplier ifIsLevelDat, + Function ifIsPlayerdata, + Function ifIsPlayers); } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java index f7c3f7230..c2b7e4627 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java @@ -1,15 +1,15 @@ package amidst.mojangapi.file.nbt.player; import java.io.IOException; +import java.util.function.Function; +import java.util.function.Supplier; import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.file.service.AmidstBackupService; -import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; -import amidst.mojangapi.world.player.PlayerInformationCache; @Immutable public class PlayerdataPlayerNbt extends PlayerNbt { @@ -38,7 +38,7 @@ public PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingE } @Override - public Player createPlayer(PlayerInformationCache cache) { - return new Player(cache.getByUUID(playerUUID), this); + public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { + return ifIsPlayerdata.apply(playerUUID); } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java index 8e4abec61..7c0d32190 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java @@ -1,15 +1,15 @@ package amidst.mojangapi.file.nbt.player; import java.io.IOException; +import java.util.function.Function; +import java.util.function.Supplier; import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.file.service.AmidstBackupService; -import amidst.mojangapi.world.player.Player; import amidst.mojangapi.world.player.PlayerCoordinates; -import amidst.mojangapi.world.player.PlayerInformationCache; @Immutable public class PlayersPlayerNbt extends PlayerNbt { @@ -38,7 +38,7 @@ public PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingE } @Override - public Player createPlayer(PlayerInformationCache cache) { - return new Player(cache.getByName(playerName), this); + public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { + return ifIsPlayers.apply(playerName); } } diff --git a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java index 2bc47ccd8..fc5c46295 100644 --- a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java +++ b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java @@ -77,7 +77,10 @@ private void loadPlayers( @CalledOnlyBy(AmidstThread.WORKER) private void loadPlayer(ConcurrentLinkedQueue players, PlayerNbt playerNbt) { - Player player = playerNbt.createPlayer(playerInformationCache); + Player player = playerNbt.map( + () -> new Player(PlayerInformation.theSingleplayerPlayer(), playerNbt), + playerUUID -> new Player(playerInformationCache.getByUUID(playerUUID), playerNbt), + playerName -> new Player(playerInformationCache.getByName(playerName), playerNbt)); if (player.tryLoadLocation()) { players.offer(player); } From ff7a905beee01b58dbcd6fecb4d137e20fe4d661 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Wed, 31 May 2017 22:56:34 +0200 Subject: [PATCH 26/48] removed the -mclibs command line parameter --- .../java/amidst/CommandLineParameters.java | 3 -- .../amidst/mojangapi/MojangApiBuilder.java | 16 +++------ .../file/directory/DotMinecraftDirectory.java | 30 +++++++++++++--- .../file/facade/MinecraftInstallation.java | 36 +++++++++++++++++++ .../service/DotMinecraftDirectoryService.java | 31 ++++++++++++---- .../GenerateRecognisedVersionList.java | 9 +++-- .../devtools/GenerateWorldTestData.java | 9 +++-- 7 files changed, 104 insertions(+), 30 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java diff --git a/src/main/java/amidst/CommandLineParameters.java b/src/main/java/amidst/CommandLineParameters.java index 559c9e32d..f889052cd 100644 --- a/src/main/java/amidst/CommandLineParameters.java +++ b/src/main/java/amidst/CommandLineParameters.java @@ -14,9 +14,6 @@ public class CommandLineParameters { @Option(name = "-mcpath", usage = "location of the '.minecraft' directory.", metaVar = "") public volatile String dotMinecraftDirectory; - @Option(name = "-mclibs", usage = "location of the '.minecraft/libraries' directory", metaVar = "") - public volatile String minecraftLibrariesDirectory; - @Option(name = "-mcjar", usage = "location of the minecraft jar file", metaVar = "", depends = { "-mcjson" }) public volatile String minecraftJarFile; diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java index 10659e64c..7e520d34f 100644 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ b/src/main/java/amidst/mojangapi/MojangApiBuilder.java @@ -9,6 +9,7 @@ import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.file.service.DotMinecraftDirectoryService; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.WorldBuilder; @@ -28,17 +29,10 @@ public MojangApiBuilder(WorldBuilder worldBuilder, CommandLineParameters paramet public MojangApi construct() throws DotMinecraftDirectoryNotFoundException, LocalMinecraftInterfaceCreationException { - DotMinecraftDirectory dotMinecraftDirectory = dotMinecraftDirectoryService - .createDotMinecraftDirectory(parameters.dotMinecraftDirectory, parameters.minecraftLibrariesDirectory); - if (dotMinecraftDirectory.isValid()) { - AmidstLogger.info( - "using '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "', libraries: '" - + dotMinecraftDirectory.getLibraries() + "'"); - } else { - throw new DotMinecraftDirectoryNotFoundException( - "invalid '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "', libraries: '" - + dotMinecraftDirectory.getLibraries() + "'"); - } + DotMinecraftDirectory dotMinecraftDirectory = MinecraftInstallation + .newLocalMinecraftInstallation(parameters.dotMinecraftDirectory) + .getDotMinecraftDirectory(); + AmidstLogger.info("using '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "'"); MojangApi result = new MojangApi(worldBuilder, dotMinecraftDirectory); result.set(null, null, createVersionDirectory()); return result; diff --git a/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java b/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java index 157f05c9a..7e148443f 100644 --- a/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java @@ -1,11 +1,31 @@ package amidst.mojangapi.file.directory; import java.io.File; +import java.util.Objects; import amidst.documentation.Immutable; @Immutable public class DotMinecraftDirectory { + /** + * Allows to customize all parts of the .minecraft directory, mainly for + * testing and the dev tools. Pass null to use default values. + */ + public static DotMinecraftDirectory newCustom( + File root, + File libraries, + File saves, + File versions, + File launcherProfilesJson) { + Objects.requireNonNull(root); + return new DotMinecraftDirectory( + root, + libraries != null ? libraries : new File(root, "libraries"), + saves != null ? saves : new File(root, "saves"), + versions != null ? versions : new File(root, "versions"), + launcherProfilesJson != null ? launcherProfilesJson : new File(root, "launcher_profiles.json")); + } + private final File root; private final File libraries; private final File saves; @@ -20,16 +40,16 @@ public DotMinecraftDirectory(File root) { this.launcherProfilesJson = new File(root, "launcher_profiles.json"); } - public DotMinecraftDirectory(File root, File libraries) { + private DotMinecraftDirectory(File root, File libraries, File saves, File versions, File launcherProfilesJson) { this.root = root; this.libraries = libraries; - this.saves = new File(root, "saves"); - this.versions = new File(root, "versions"); - this.launcherProfilesJson = new File(root, "launcher_profiles.json"); + this.saves = saves; + this.versions = versions; + this.launcherProfilesJson = launcherProfilesJson; } public boolean isValid() { - return root.isDirectory() && libraries.isDirectory() && launcherProfilesJson.isFile(); + return root.isDirectory() && libraries.isDirectory() && versions.isDirectory() && launcherProfilesJson.isFile(); } public File getRoot() { diff --git a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java new file mode 100644 index 000000000..8c99849fa --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java @@ -0,0 +1,36 @@ +package amidst.mojangapi.file.facade; + +import java.io.File; + +import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.directory.DotMinecraftDirectory; +import amidst.mojangapi.file.service.DotMinecraftDirectoryService; + +public class MinecraftInstallation { + public static MinecraftInstallation newCustomMinecraftInstallation( + File libraries, + File saves, + File versions, + File launcherProfilesJson) throws DotMinecraftDirectoryNotFoundException { + DotMinecraftDirectory dotMinecraftDirectory = new DotMinecraftDirectoryService() + .createCustomDotMinecraftDirectory(libraries, saves, versions, launcherProfilesJson); + return new MinecraftInstallation(dotMinecraftDirectory); + } + + public static MinecraftInstallation newLocalMinecraftInstallation(String preferredDotMinecraftDirectory) + throws DotMinecraftDirectoryNotFoundException { + DotMinecraftDirectory dotMinecraftDirectory = new DotMinecraftDirectoryService() + .createDotMinecraftDirectory(preferredDotMinecraftDirectory); + return new MinecraftInstallation(dotMinecraftDirectory); + } + + private final DotMinecraftDirectory dotMinecraftDirectory; + + public MinecraftInstallation(DotMinecraftDirectory dotMinecraftDirectory) { + this.dotMinecraftDirectory = dotMinecraftDirectory; + } + + public DotMinecraftDirectory getDotMinecraftDirectory() { + return dotMinecraftDirectory; + } +} diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index bc50e807b..d3b17a280 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -8,6 +8,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; @@ -26,14 +27,30 @@ public class DotMinecraftDirectoryService { private final FilenameService filenameService = new FilenameService(); @NotNull - public DotMinecraftDirectory createDotMinecraftDirectory( - String preferredDotMinecraftDirectory, - String preferredLibrariesDirectory) { - File dotMinecraftDirectory = findDotMinecraftDirectory(preferredDotMinecraftDirectory); - if (preferredLibrariesDirectory != null) { - return new DotMinecraftDirectory(dotMinecraftDirectory, new File(preferredLibrariesDirectory)); + public DotMinecraftDirectory createCustomDotMinecraftDirectory( + File libraries, + File saves, + File versions, + File launcherProfilesJson) throws DotMinecraftDirectoryNotFoundException { + return validate( + DotMinecraftDirectory + .newCustom(getMinecraftDirectory(), libraries, saves, versions, launcherProfilesJson)); + } + + @NotNull + public DotMinecraftDirectory createDotMinecraftDirectory(String preferredDotMinecraftDirectory) + throws DotMinecraftDirectoryNotFoundException { + return validate(new DotMinecraftDirectory(findDotMinecraftDirectory(preferredDotMinecraftDirectory))); + } + + @NotNull + private DotMinecraftDirectory validate(DotMinecraftDirectory dotMinecraftDirectory) + throws DotMinecraftDirectoryNotFoundException { + if (dotMinecraftDirectory.isValid()) { + return dotMinecraftDirectory; } else { - return new DotMinecraftDirectory(dotMinecraftDirectory); + throw new DotMinecraftDirectoryNotFoundException( + "invalid '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "'"); } } diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 3ea9aea47..a5013f760 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -8,8 +8,10 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.file.service.ClassLoaderService; @@ -27,11 +29,14 @@ public class GenerateRecognisedVersionList { private final List downloadFailed = new LinkedList<>(); private final RecognisedVersionEnumBuilder builder = RecognisedVersionEnumBuilder.createPopulated(); - public GenerateRecognisedVersionList(String prefix, String libraries, VersionListJson versionList) { + public GenerateRecognisedVersionList(String prefix, String libraries, VersionListJson versionList) + throws DotMinecraftDirectoryNotFoundException { this.prefix = prefix; this.versionList = versionList; this.versions = new File(prefix); - this.dotMinecraftDirectory = new DotMinecraftDirectory(null, new File(libraries)); + this.dotMinecraftDirectory = MinecraftInstallation + .newCustomMinecraftInstallation(new File(libraries), null, null, null) + .getDotMinecraftDirectory(); } public void run() { diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 82aa4bcae..80d9bc0ef 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -6,8 +6,10 @@ import java.util.List; import amidst.clazz.translator.ClassTranslator; +import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.file.service.DownloadService; @@ -28,12 +30,15 @@ public class GenerateWorldTestData { private final List failed = new LinkedList<>(); private final List successful = new LinkedList<>(); - public GenerateWorldTestData(String prefix, String libraries, VersionListJson versionList) { + public GenerateWorldTestData(String prefix, String libraries, VersionListJson versionList) + throws DotMinecraftDirectoryNotFoundException { this.prefix = prefix; this.libraries = new File(libraries); this.versionList = versionList; this.versions = new File(prefix); - this.dotMinecraftDirectory = new DotMinecraftDirectory(null, this.libraries); + this.dotMinecraftDirectory = MinecraftInstallation + .newCustomMinecraftInstallation(this.libraries, null, null, null) + .getDotMinecraftDirectory(); } public void run() { From 4c1a9b1048f072c0ba981ec28262f7f6f00932fa Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 00:47:12 +0200 Subject: [PATCH 27/48] introduced facade classes MinecraftInstallation, LauncherProfile and UnresolvedLauncherProfile --- .../amidst/gui/main/MainWindowDialogs.java | 4 +- .../profileselect/LocalProfileComponent.java | 34 ++++----- .../profileselect/ProfileSelectWindow.java | 26 ++++--- src/main/java/amidst/mojangapi/MojangApi.java | 69 ++++++++----------- .../amidst/mojangapi/MojangApiBuilder.java | 44 ++++-------- .../file/directory/DotMinecraftDirectory.java | 4 ++ .../file/directory/VersionDirectory.java | 10 +-- .../file/facade/LauncherProfile.java | 61 ++++++++++++++++ .../file/facade/MinecraftInstallation.java | 50 ++++++++++++++ .../facade/UnresolvedLauncherProfile.java | 51 ++++++++++++++ .../file/json/version/VersionJson.java | 10 +++ .../file/service/ClassLoaderService.java | 30 -------- .../service/DotMinecraftDirectoryService.java | 54 ++++++++++----- .../file/service/LibraryService.java | 10 +++ .../file/service/SaveDirectoryService.java | 2 +- .../local/LocalMinecraftInterface.java | 11 ++- .../local/LocalMinecraftInterfaceBuilder.java | 16 ++--- .../GenerateRecognisedVersionList.java | 30 ++------ .../devtools/GenerateWorldTestData.java | 35 ++++------ 19 files changed, 324 insertions(+), 227 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/facade/LauncherProfile.java create mode 100644 src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java delete mode 100644 src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java diff --git a/src/main/java/amidst/gui/main/MainWindowDialogs.java b/src/main/java/amidst/gui/main/MainWindowDialogs.java index 9b4754c3c..c5063f6ae 100644 --- a/src/main/java/amidst/gui/main/MainWindowDialogs.java +++ b/src/main/java/amidst/gui/main/MainWindowDialogs.java @@ -13,6 +13,7 @@ import amidst.documentation.NotThreadSafe; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.facade.LauncherProfile; import amidst.mojangapi.world.WorldSeed; import amidst.mojangapi.world.WorldType; import amidst.mojangapi.world.export.WorldExporterConfiguration; @@ -52,7 +53,8 @@ public File askForSaveGame() { @CalledOnlyBy(AmidstThread.EDT) private JFileChooser createSaveGameFileChooser() { - JFileChooser result = new JFileChooser(mojangApi.getSaves()); + JFileChooser result = new JFileChooser( + mojangApi.getLauncherProfile().map(LauncherProfile::getSaves).orElse(null)); result.setFileFilter(new LevelFileFilter()); result.setAcceptAllFileFilterUsed(false); result.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index fb3c3c0fe..d6b2f3e8c 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -1,6 +1,6 @@ package amidst.gui.profileselect; -import java.io.FileNotFoundException; +import java.io.IOException; import java.util.Locale; import java.util.regex.Pattern; @@ -11,10 +11,9 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.directory.ProfileDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; -import amidst.mojangapi.file.service.DotMinecraftDirectoryService; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.facade.LauncherProfile; +import amidst.mojangapi.file.facade.UnresolvedLauncherProfile; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.threading.WorkerExecutor; @@ -23,25 +22,24 @@ public class LocalProfileComponent extends ProfileComponent { private final Application application; private final WorkerExecutor workerExecutor; private final MojangApi mojangApi; - private final LauncherProfileJson profile; + private final UnresolvedLauncherProfile unresolvedProfile; private volatile boolean isSearching = false; private volatile boolean failedSearching = false; private volatile boolean isLoading = false; private volatile boolean failedLoading = false; - private volatile VersionDirectory versionDirectory; - private volatile ProfileDirectory profileDirectory; + private volatile LauncherProfile resolvedProfile; @CalledOnlyBy(AmidstThread.EDT) public LocalProfileComponent( Application application, WorkerExecutor workerExecutor, MojangApi mojangApi, - LauncherProfileJson profile) { + UnresolvedLauncherProfile unresolvedProfile) { this.application = application; this.mojangApi = mojangApi; this.workerExecutor = workerExecutor; - this.profile = profile; + this.unresolvedProfile = unresolvedProfile; initComponent(); initDirectoriesLater(); } @@ -55,16 +53,10 @@ private void initDirectoriesLater() { @CalledOnlyBy(AmidstThread.WORKER) private boolean tryFind() { - DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); try { - profileDirectory = dotMinecraftDirectoryService - .createValidProfileDirectory(profile, mojangApi.getDotMinecraftDirectory()); - versionDirectory = dotMinecraftDirectoryService.createValidVersionDirectory( - profile, - mojangApi.getVersionList(), - mojangApi.getDotMinecraftDirectory()); + resolvedProfile = unresolvedProfile.resolve(mojangApi.getVersionList()); return true; - } catch (FileNotFoundException e) { + } catch (IOException | MojangApiParsingException e) { AmidstLogger.warn(e); return false; } @@ -103,7 +95,7 @@ private boolean tryLoad() { return false; } - mojangApi.set(getProfileName(), profileDirectory, versionDirectory); + mojangApi.setLauncherProfile(resolvedProfile); return true; } catch (LocalMinecraftInterfaceCreationException e) { AmidstLogger.error(e); @@ -155,14 +147,14 @@ protected boolean isReadyToLoad() { @CalledOnlyBy(AmidstThread.EDT) @Override protected String getProfileName() { - return profile.getName(); + return unresolvedProfile.getName(); } @CalledOnlyBy(AmidstThread.EDT) @Override protected String getVersionName() { if (isReadyToLoad()) { - return versionDirectory.getVersionId(); + return resolvedProfile.getVersionId(); } else { return ""; } diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index b930380f2..e645e9fd6 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -4,6 +4,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; +import java.util.List; import javax.swing.JFrame; import javax.swing.JLabel; @@ -21,9 +22,7 @@ import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; -import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; -import amidst.mojangapi.file.service.DotMinecraftDirectoryService; +import amidst.mojangapi.file.facade.UnresolvedLauncherProfile; import amidst.threading.WorkerExecutor; import net.miginfocom.swing.MigLayout; @@ -113,34 +112,33 @@ private void scanAndLoadProfilesLater() { } @CalledOnlyBy(AmidstThread.WORKER) - private LauncherProfilesJson scanAndLoadProfiles() throws MojangApiParsingException, IOException { + private List scanAndLoadProfiles() throws MojangApiParsingException, IOException { AmidstLogger.info("Scanning for profiles."); - LauncherProfilesJson launcherProfile = new DotMinecraftDirectoryService() - .readLauncherProfilesFrom(mojangApi.getDotMinecraftDirectory()); + List launcherProfiles = mojangApi.getMinecraftInstallation().readLauncherProfiles(); AmidstLogger.info("Successfully loaded profile list."); - return launcherProfile; + return launcherProfiles; } @CalledOnlyBy(AmidstThread.EDT) - private void displayProfiles(LauncherProfilesJson launcherProfile) { - createProfileComponentsIfNecessary(launcherProfile); + private void displayProfiles(List launcherProfiles) { + createProfileComponentsIfNecessary(launcherProfiles); restoreSelection(); frame.pack(); } @CalledOnlyBy(AmidstThread.EDT) - private void createProfileComponentsIfNecessary(LauncherProfilesJson launcherProfile) { - if (launcherProfile.getProfiles().values().isEmpty()) { + private void createProfileComponentsIfNecessary(List launcherProfiles) { + if (launcherProfiles.isEmpty()) { AmidstLogger.warn("No profiles found in launcher_profiles.json"); profileSelectPanel.setEmptyMessage("No profiles found"); } else { - createProfileComponents(launcherProfile); + createProfileComponents(launcherProfiles); } } @CalledOnlyBy(AmidstThread.EDT) - private void createProfileComponents(LauncherProfilesJson launcherProfile) { - for (LauncherProfileJson profile : launcherProfile.getProfiles().values()) { + private void createProfileComponents(List launcherProfiles) { + for (UnresolvedLauncherProfile profile : launcherProfiles) { profileSelectPanel.addProfile(new LocalProfileComponent(application, workerExecutor, mojangApi, profile)); } } diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 8f31d3296..a98f6c6f2 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -3,13 +3,14 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.Optional; import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; +import amidst.logging.AmidstLogger; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.directory.DotMinecraftDirectory; -import amidst.mojangapi.file.directory.ProfileDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.facade.LauncherProfile; +import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.file.service.SaveDirectoryService; import amidst.mojangapi.file.service.VersionListService; @@ -27,23 +28,26 @@ @ThreadSafe public class MojangApi { private static final String UNKNOWN_PROFILE_NAME = "unknown"; + public static final String UNKNOWN_VERSION_ID = "unknown"; private final WorldBuilder worldBuilder; - private final DotMinecraftDirectory dotMinecraftDirectory; + private final MinecraftInstallation minecraftInstallation; private volatile VersionListJson versionList; - private volatile ProfileDirectory profileDirectory; - private volatile VersionDirectory versionDirectory; private volatile MinecraftInterface minecraftInterface; - private volatile String profileName; + private volatile LauncherProfile launcherProfile; - public MojangApi(WorldBuilder worldBuilder, DotMinecraftDirectory dotMinecraftDirectory) { + public MojangApi(WorldBuilder worldBuilder, MinecraftInstallation minecraftInstallation) { this.worldBuilder = worldBuilder; - this.dotMinecraftDirectory = dotMinecraftDirectory; + this.minecraftInstallation = minecraftInstallation; } - public DotMinecraftDirectory getDotMinecraftDirectory() { - return dotMinecraftDirectory; + public MinecraftInstallation getMinecraftInstallation() { + return minecraftInstallation; + } + + public Optional getLauncherProfile() { + return Optional.ofNullable(launcherProfile); } @NotNull @@ -61,15 +65,15 @@ public VersionListJson getVersionList() throws FileNotFoundException { return versionList; } - public void set(String profileName, ProfileDirectory profileDirectory, VersionDirectory versionDirectory) - throws LocalMinecraftInterfaceCreationException { - this.profileName = profileName; - this.profileDirectory = profileDirectory; - this.versionDirectory = versionDirectory; - if (versionDirectory != null) { + public void setLauncherProfile(LauncherProfile launcherProfile) throws LocalMinecraftInterfaceCreationException { + this.launcherProfile = launcherProfile; + if (launcherProfile != null) { + AmidstLogger.info( + "using launcher profile. version id: '" + launcherProfile.getVersionId() + "', profile name: '" + + launcherProfile.getProfileName() + "', jar file: '" + launcherProfile.getJar() + "'"); try { this.minecraftInterface = LocalMinecraftInterface - .create(DefaultClassTranslator.INSTANCE.get(), versionDirectory, dotMinecraftDirectory); + .create(DefaultClassTranslator.INSTANCE.get(), launcherProfile); } catch (LocalMinecraftInterfaceCreationException e) { this.minecraftInterface = null; throw e; @@ -80,9 +84,9 @@ public void set(String profileName, ProfileDirectory profileDirectory, VersionDi } public MojangApi createSilentPlayerlessCopy() { - MojangApi result = new MojangApi(WorldBuilder.createSilentPlayerless(), dotMinecraftDirectory); + MojangApi result = new MojangApi(WorldBuilder.createSilentPlayerless(), minecraftInstallation); try { - result.set(profileName, profileDirectory, versionDirectory); + result.setLauncherProfile(launcherProfile); } catch (LocalMinecraftInterfaceCreationException e) { // This will not happen normally, because we already successfully // created the same LocalMinecraftInterface once before. @@ -91,15 +95,6 @@ public MojangApi createSilentPlayerlessCopy() { return result; } - public File getSaves() { - ProfileDirectory profileDirectory = this.profileDirectory; - if (profileDirectory != null) { - return profileDirectory.getSaves(); - } else { - return dotMinecraftDirectory.getSaves(); - } - } - public boolean canCreateWorld() { return minecraftInterface != null; } @@ -133,19 +128,14 @@ public World createWorldFromSaveGame(File file) MojangApiParsingException { MinecraftInterface minecraftInterface = this.minecraftInterface; if (minecraftInterface != null) { - return worldBuilder.fromSaveGame(minecraftInterface, new SaveDirectoryService().from(file)); + return worldBuilder.fromSaveGame(minecraftInterface, new SaveDirectoryService().newSaveDirectory(file)); } else { throw new IllegalStateException("cannot create a world without a minecraft interface"); } } public String getVersionId() { - VersionDirectory versionDirectory = this.versionDirectory; - if (versionDirectory != null) { - return versionDirectory.getVersionId(); - } else { - return VersionDirectory.UNKNOWN_VERSION_ID; - } + return getLauncherProfile().map(LauncherProfile::getVersionId).orElse(UNKNOWN_VERSION_ID); } public String getRecognisedVersionName() { @@ -158,11 +148,6 @@ public String getRecognisedVersionName() { } public String getProfileName() { - String profileName = this.profileName; - if (profileName != null) { - return profileName; - } else { - return UNKNOWN_PROFILE_NAME; - } + return getLauncherProfile().map(LauncherProfile::getProfileName).orElse(UNKNOWN_PROFILE_NAME); } } diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java index 7e520d34f..cdf964b40 100644 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ b/src/main/java/amidst/mojangapi/MojangApiBuilder.java @@ -1,16 +1,14 @@ package amidst.mojangapi; import java.io.File; +import java.io.IOException; import amidst.CommandLineParameters; import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.directory.DotMinecraftDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.facade.MinecraftInstallation; -import amidst.mojangapi.file.service.DotMinecraftDirectoryService; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.WorldBuilder; @@ -18,7 +16,6 @@ public class MojangApiBuilder { private final WorldBuilder worldBuilder; private final CommandLineParameters parameters; - private final DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); public MojangApiBuilder(WorldBuilder worldBuilder, CommandLineParameters parameters) { this.worldBuilder = worldBuilder; @@ -29,32 +26,21 @@ public MojangApiBuilder(WorldBuilder worldBuilder, CommandLineParameters paramet public MojangApi construct() throws DotMinecraftDirectoryNotFoundException, LocalMinecraftInterfaceCreationException { - DotMinecraftDirectory dotMinecraftDirectory = MinecraftInstallation - .newLocalMinecraftInstallation(parameters.dotMinecraftDirectory) - .getDotMinecraftDirectory(); - AmidstLogger.info("using '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "'"); - MojangApi result = new MojangApi(worldBuilder, dotMinecraftDirectory); - result.set(null, null, createVersionDirectory()); - return result; - } - - private VersionDirectory createVersionDirectory() { + MinecraftInstallation minecraftInstallation = MinecraftInstallation + .newLocalMinecraftInstallation(parameters.dotMinecraftDirectory); + MojangApi result = new MojangApi(worldBuilder, minecraftInstallation); if (parameters.minecraftJarFile != null && parameters.minecraftJsonFile != null) { - File jar = new File(parameters.minecraftJarFile); - File json = new File(parameters.minecraftJsonFile); - VersionDirectory result = dotMinecraftDirectoryService - .createVersionDirectoryWithUnknownVersionId(jar, json); - if (result.isValid()) { - AmidstLogger.info( - "using minecraft version directory. versionId: '" + result.getVersionId() + "', jar file: '" - + result.getJar() + "', json file: '" + result.getJson() + "'"); - return result; - } else { - AmidstLogger.warn( - "invalid minecraft version directory. versionId: '" + result.getVersionId() + "', jar file: '" - + result.getJar() + "', json file: '" + result.getJson() + "'"); + try { + result.setLauncherProfile( + minecraftInstallation.newLauncherProfile( + new File(parameters.minecraftJarFile), + new File(parameters.minecraftJsonFile))); + } catch (MojangApiParsingException | IOException e) { + result.setLauncherProfile(null); } + } else { + result.setLauncherProfile(null); } - return null; + return result; } } diff --git a/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java b/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java index 7e148443f..ee46fa5ce 100644 --- a/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/DotMinecraftDirectory.java @@ -52,6 +52,10 @@ public boolean isValid() { return root.isDirectory() && libraries.isDirectory() && versions.isDirectory() && launcherProfilesJson.isFile(); } + public ProfileDirectory asProfileDirectory() { + return new ProfileDirectory(root); + } + public File getRoot() { return root; } diff --git a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java index 3d854998e..851f99040 100644 --- a/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java +++ b/src/main/java/amidst/mojangapi/file/directory/VersionDirectory.java @@ -6,14 +6,10 @@ @Immutable public class VersionDirectory { - public static final String UNKNOWN_VERSION_ID = "unknown"; - - private final String versionId; private final File jar; private final File json; - public VersionDirectory(String versionId, File jar, File json) { - this.versionId = versionId; + public VersionDirectory(File jar, File json) { this.jar = jar; this.json = json; } @@ -22,10 +18,6 @@ public boolean isValid() { return jar.isFile() && json.isFile(); } - public String getVersionId() { - return versionId; - } - public File getJar() { return jar; } diff --git a/src/main/java/amidst/mojangapi/file/facade/LauncherProfile.java b/src/main/java/amidst/mojangapi/file/facade/LauncherProfile.java new file mode 100644 index 000000000..5596351ac --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/LauncherProfile.java @@ -0,0 +1,61 @@ +package amidst.mojangapi.file.facade; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.List; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.directory.DotMinecraftDirectory; +import amidst.mojangapi.file.directory.ProfileDirectory; +import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.version.VersionJson; +import amidst.mojangapi.file.service.LibraryService; + +@Immutable +public class LauncherProfile { + private final DotMinecraftDirectory dotMinecraftDirectory; + private final ProfileDirectory profileDirectory; + private final VersionDirectory versionDirectory; + private final VersionJson versionJson; + private final String profileName; + + public LauncherProfile( + DotMinecraftDirectory dotMinecraftDirectory, + ProfileDirectory profileDirectory, + VersionDirectory versionDirectory, + VersionJson versionJson, + String profileName) { + this.dotMinecraftDirectory = dotMinecraftDirectory; + this.profileDirectory = profileDirectory; + this.versionDirectory = versionDirectory; + this.versionJson = versionJson; + this.profileName = profileName; + } + + public String getVersionId() { + return versionJson.getId(); + } + + public String getProfileName() { + return profileName; + } + + public File getJar() { + return versionDirectory.getJar(); + } + + public File getSaves() { + return profileDirectory.getSaves(); + } + + public URLClassLoader newClassLoader() throws MalformedURLException { + LibraryService libraryService = new LibraryService(); + List classLoaderUrls = libraryService.getAllClassLoaderUrls( + dotMinecraftDirectory.getLibraries(), + versionJson.getLibraries(), + versionDirectory.getJar()); + return new URLClassLoader(classLoaderUrls.toArray(new URL[classLoaderUrls.size()])); + } +} diff --git a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java index 8c99849fa..d7f7a212b 100644 --- a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java @@ -1,11 +1,22 @@ package amidst.mojangapi.file.facade; import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; +import amidst.documentation.Immutable; +import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; +import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.version.VersionJson; import amidst.mojangapi.file.service.DotMinecraftDirectoryService; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; +@Immutable public class MinecraftInstallation { public static MinecraftInstallation newCustomMinecraftInstallation( File libraries, @@ -14,6 +25,7 @@ public static MinecraftInstallation newCustomMinecraftInstallation( File launcherProfilesJson) throws DotMinecraftDirectoryNotFoundException { DotMinecraftDirectory dotMinecraftDirectory = new DotMinecraftDirectoryService() .createCustomDotMinecraftDirectory(libraries, saves, versions, launcherProfilesJson); + AmidstLogger.info("using '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "'"); return new MinecraftInstallation(dotMinecraftDirectory); } @@ -21,16 +33,54 @@ public static MinecraftInstallation newLocalMinecraftInstallation(String preferr throws DotMinecraftDirectoryNotFoundException { DotMinecraftDirectory dotMinecraftDirectory = new DotMinecraftDirectoryService() .createDotMinecraftDirectory(preferredDotMinecraftDirectory); + AmidstLogger.info("using '.minecraft' directory at: '" + dotMinecraftDirectory.getRoot() + "'"); return new MinecraftInstallation(dotMinecraftDirectory); } + private final DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); private final DotMinecraftDirectory dotMinecraftDirectory; public MinecraftInstallation(DotMinecraftDirectory dotMinecraftDirectory) { this.dotMinecraftDirectory = dotMinecraftDirectory; } + @Deprecated public DotMinecraftDirectory getDotMinecraftDirectory() { return dotMinecraftDirectory; } + + public List readLauncherProfiles() throws MojangApiParsingException, IOException { + return dotMinecraftDirectoryService + .readLauncherProfilesFrom(dotMinecraftDirectory) + .getProfiles() + .values() + .stream() + .map(p -> new UnresolvedLauncherProfile(dotMinecraftDirectory, p)) + .collect(Collectors.toList()); + } + + public LauncherProfile newLauncherProfile(String versionId) throws MojangApiParsingException, IOException { + return newLauncherProfile( + dotMinecraftDirectoryService.createValidVersionDirectory(dotMinecraftDirectory, versionId)); + } + + public LauncherProfile newLauncherProfile(File jar, File json) throws MojangApiParsingException, IOException { + return newLauncherProfile(dotMinecraftDirectoryService.createValidVersionDirectory(jar, json)); + } + + private LauncherProfile newLauncherProfile(VersionDirectory versionDirectory) + throws IOException, + MojangApiParsingException { + try { + VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); + return new LauncherProfile( + dotMinecraftDirectory, + dotMinecraftDirectory.asProfileDirectory(), + versionDirectory, + versionJson, + versionJson.getId()); + } catch (FormatException e) { + throw new MojangApiParsingException(e); + } + } } diff --git a/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java b/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java new file mode 100644 index 000000000..e0194f772 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java @@ -0,0 +1,51 @@ +package amidst.mojangapi.file.facade; + +import java.io.IOException; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.directory.DotMinecraftDirectory; +import amidst.mojangapi.file.directory.ProfileDirectory; +import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; +import amidst.mojangapi.file.json.version.VersionJson; +import amidst.mojangapi.file.json.versionlist.VersionListJson; +import amidst.mojangapi.file.service.DotMinecraftDirectoryService; +import amidst.parsing.FormatException; +import amidst.parsing.json.JsonReader; + +@Immutable +public class UnresolvedLauncherProfile { + private final DotMinecraftDirectory dotMinecraftDirectory; + private final LauncherProfileJson launcherProfileJson; + + public UnresolvedLauncherProfile( + DotMinecraftDirectory dotMinecraftDirectory, + LauncherProfileJson launcherProfileJson) { + this.dotMinecraftDirectory = dotMinecraftDirectory; + this.launcherProfileJson = launcherProfileJson; + } + + public String getName() { + return launcherProfileJson.getName(); + } + + public LauncherProfile resolve(VersionListJson versionList) throws MojangApiParsingException, IOException { + DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); + ProfileDirectory profileDirectory = dotMinecraftDirectoryService + .createValidProfileDirectory(launcherProfileJson, dotMinecraftDirectory); + VersionDirectory versionDirectory = dotMinecraftDirectoryService + .createValidVersionDirectory(launcherProfileJson, versionList, dotMinecraftDirectory); + try { + VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); + return new LauncherProfile( + dotMinecraftDirectory, + profileDirectory, + versionDirectory, + versionJson, + launcherProfileJson.getName()); + } catch (FormatException e) { + throw new MojangApiParsingException(e); + } + } +} diff --git a/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java b/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java index 9d3bea385..56ad5cb75 100644 --- a/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java +++ b/src/main/java/amidst/mojangapi/file/json/version/VersionJson.java @@ -8,12 +8,22 @@ @Immutable public class VersionJson { + private volatile String id; + private volatile String inheritsFrom; private volatile List libraries = Collections.emptyList(); @GsonConstructor public VersionJson() { } + public String getId() { + return id; + } + + public String getInheritsFrom() { + return inheritsFrom; + } + public List getLibraries() { return libraries; } diff --git a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java deleted file mode 100644 index eb7134886..000000000 --- a/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java +++ /dev/null @@ -1,30 +0,0 @@ -package amidst.mojangapi.file.service; - -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.List; - -import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.file.directory.DotMinecraftDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.json.version.VersionJson; -import amidst.parsing.FormatException; -import amidst.parsing.json.JsonReader; - -@Immutable -public class ClassLoaderService { - private final LibraryService libraryService = new LibraryService(); - - @NotNull - public URLClassLoader createClassLoader( - VersionDirectory versionDirectory, - DotMinecraftDirectory dotMinecraftDirectory) throws FormatException, IOException { - VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); - List libraries = libraryService - .getLibraryUrls(dotMinecraftDirectory.getLibraries(), versionJson.getLibraries()); - libraries.add(versionDirectory.getJar().toURI().toURL()); - return new URLClassLoader(libraries.toArray(new URL[libraries.size()])); - } -} diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index d3b17a280..0b4440d3a 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -101,17 +101,22 @@ public ProfileDirectory createValidProfileDirectory( LauncherProfileJson launcherProfileJson, DotMinecraftDirectory dotMinecraftDirectory) throws FileNotFoundException { String gameDir = launcherProfileJson.getGameDir(); + ProfileDirectory result = createProfileDirectory(dotMinecraftDirectory, gameDir); + if (result.isValid()) { + return result; + } else { + throw new FileNotFoundException( + "cannot find valid profile directory for launcher profile '" + launcherProfileJson.getName() + "': " + + gameDir); + } + } + + @NotNull + private ProfileDirectory createProfileDirectory(DotMinecraftDirectory dotMinecraftDirectory, String gameDir) { if (gameDir != null) { - ProfileDirectory result = new ProfileDirectory(new File(gameDir)); - if (result.isValid()) { - return result; - } else { - throw new FileNotFoundException( - "cannot find valid profile directory for launcher profile '" + launcherProfileJson.getName() - + "': " + gameDir); - } + return new ProfileDirectory(new File(gameDir)); } else { - return new ProfileDirectory(dotMinecraftDirectory.getRoot()); + return dotMinecraftDirectory.asProfileDirectory(); } } @@ -159,15 +164,32 @@ private VersionDirectory tryFindFirstValidVersionDirectory( } @NotNull - public VersionDirectory createVersionDirectory(DotMinecraftDirectory dotMinecraftDirectory, String versionId) { - File versions = dotMinecraftDirectory.getVersions(); - File jar = filenameService.getClientJarFile(versions, versionId); - File json = filenameService.getClientJsonFile(versions, versionId); - return new VersionDirectory(versionId, jar, json); + public VersionDirectory createValidVersionDirectory(File jar, File json) throws FileNotFoundException { + VersionDirectory versionDirectory = new VersionDirectory(jar, json); + if (versionDirectory.isValid()) { + return versionDirectory; + } else { + throw new FileNotFoundException( + "cannot find valid version directory for jar: '" + jar + "', json: '" + json + "'"); + } } @NotNull - public VersionDirectory createVersionDirectoryWithUnknownVersionId(File jar, File json) { - return new VersionDirectory(VersionDirectory.UNKNOWN_VERSION_ID, jar, json); + public VersionDirectory createValidVersionDirectory(DotMinecraftDirectory dotMinecraftDirectory, String versionId) + throws FileNotFoundException { + VersionDirectory versionDirectory = createVersionDirectory(dotMinecraftDirectory, versionId); + if (versionDirectory.isValid()) { + return versionDirectory; + } else { + throw new FileNotFoundException("cannot find valid version directory for version id '" + versionId + "'"); + } + } + + @NotNull + private VersionDirectory createVersionDirectory(DotMinecraftDirectory dotMinecraftDirectory, String versionId) { + File versions = dotMinecraftDirectory.getVersions(); + File jar = filenameService.getClientJarFile(versions, versionId); + File json = filenameService.getClientJsonFile(versions, versionId); + return new VersionDirectory(jar, json); } } diff --git a/src/main/java/amidst/mojangapi/file/service/LibraryService.java b/src/main/java/amidst/mojangapi/file/service/LibraryService.java index 276d1c9cf..dd16e1ef1 100644 --- a/src/main/java/amidst/mojangapi/file/service/LibraryService.java +++ b/src/main/java/amidst/mojangapi/file/service/LibraryService.java @@ -5,6 +5,8 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -22,6 +24,14 @@ public class LibraryService { private static final String ACTION_ALLOW = "allow"; + @NotNull + public List getAllClassLoaderUrls(File librariesDirectory, List libraries, File versionJarFile) + throws MalformedURLException { + List result = new LinkedList<>(getLibraryUrls(librariesDirectory, libraries)); + result.add(versionJarFile.toURI().toURL()); + return Collections.unmodifiableList(result); + } + @NotNull public List getLibraryUrls(File librariesDirectory, List libraries) { List result = new ArrayList<>(); diff --git a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java index 1897af417..b41fa8ea8 100644 --- a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java @@ -27,7 +27,7 @@ public class SaveDirectoryService { * that is also not valid it will throw a FileNotFoundException. */ @NotNull - public SaveDirectory from(File file) throws FileNotFoundException { + public SaveDirectory newSaveDirectory(File file) throws FileNotFoundException { File currentFile = file; SaveDirectory result = null; if (currentFile == null) { diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java index 072f86f75..b7f4eb22b 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java @@ -7,8 +7,7 @@ import amidst.clazz.translator.ClassTranslator; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.directory.DotMinecraftDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.facade.LauncherProfile; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -16,11 +15,9 @@ @ThreadSafe public class LocalMinecraftInterface implements MinecraftInterface { - public static LocalMinecraftInterface create( - ClassTranslator translator, - VersionDirectory versionDirectory, - DotMinecraftDirectory dotMinecraftDirectory) throws LocalMinecraftInterfaceCreationException { - return new LocalMinecraftInterfaceBuilder(translator).create(versionDirectory, dotMinecraftDirectory); + public static LocalMinecraftInterface create(ClassTranslator translator, LauncherProfile launcherProfile) + throws LocalMinecraftInterfaceCreationException { + return new LocalMinecraftInterfaceBuilder(translator).create(launcherProfile); } /** diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java index 6ec94dba5..41c65e9bf 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java @@ -12,11 +12,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.directory.DotMinecraftDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.service.ClassLoaderService; +import amidst.mojangapi.file.facade.LauncherProfile; import amidst.mojangapi.minecraftinterface.RecognisedVersion; -import amidst.parsing.FormatException; @Immutable public class LocalMinecraftInterfaceBuilder { @@ -27,15 +24,13 @@ public LocalMinecraftInterfaceBuilder(ClassTranslator translator) { } @NotNull - public LocalMinecraftInterface create( - VersionDirectory versionDirectory, - DotMinecraftDirectory dotMinecraftDirectory) throws LocalMinecraftInterfaceCreationException { + public LocalMinecraftInterface create(LauncherProfile launcherProfile) + throws LocalMinecraftInterfaceCreationException { try { - URLClassLoader classLoader = new ClassLoaderService() - .createClassLoader(versionDirectory, dotMinecraftDirectory); + URLClassLoader classLoader = launcherProfile.newClassLoader(); RecognisedVersion recognisedVersion = RecognisedVersion.from(classLoader); Map symbolicClassMap = Classes - .createSymbolicClassMap(versionDirectory.getJar(), classLoader, translator); + .createSymbolicClassMap(launcherProfile.getJar(), classLoader, translator); AmidstLogger.info("Minecraft load complete."); return new LocalMinecraftInterface( symbolicClassMap.get(SymbolicNames.CLASS_INT_CACHE), @@ -48,7 +43,6 @@ public LocalMinecraftInterface create( ClassNotFoundException | JarFileParsingException | SymbolicClassGraphCreationException - | FormatException | IOException e) { throw new LocalMinecraftInterfaceCreationException("unable to create local minecraft interface", e); } diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index a5013f760..58ea04c4d 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -9,22 +9,17 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.directory.DotMinecraftDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.ClassLoaderService; import amidst.mojangapi.file.service.DownloadService; -import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.minecraftinterface.RecognisedVersion; -import amidst.parsing.FormatException; public class GenerateRecognisedVersionList { private final String prefix; private final VersionListJson versionList; - private final File versions; - private final DotMinecraftDirectory dotMinecraftDirectory; + private final MinecraftInstallation minecraftInstallation; private final List versionsWithError = new LinkedList<>(); private final List downloadFailed = new LinkedList<>(); private final RecognisedVersionEnumBuilder builder = RecognisedVersionEnumBuilder.createPopulated(); @@ -33,10 +28,8 @@ public GenerateRecognisedVersionList(String prefix, String libraries, VersionLis throws DotMinecraftDirectoryNotFoundException { this.prefix = prefix; this.versionList = versionList; - this.versions = new File(prefix); - this.dotMinecraftDirectory = MinecraftInstallation - .newCustomMinecraftInstallation(new File(libraries), null, null, null) - .getDotMinecraftDirectory(); + this.minecraftInstallation = MinecraftInstallation + .newCustomMinecraftInstallation(new File(libraries), null, new File(prefix), null); } public void run() { @@ -56,7 +49,7 @@ private void process(VersionListEntryJson version) { if (new DownloadService().tryDownloadClient(prefix, version)) { try { process(versionId); - } catch (ClassNotFoundException | NoClassDefFoundError | FormatException | IOException e) { + } catch (ClassNotFoundException | NoClassDefFoundError | MojangApiParsingException | IOException e) { e.printStackTrace(); versionsWithError.add(versionId); } @@ -65,22 +58,13 @@ private void process(VersionListEntryJson version) { } } - private void process(String versionId) throws ClassNotFoundException, FormatException, IOException { + private void process(String versionId) throws ClassNotFoundException, MojangApiParsingException, IOException { AmidstLogger.info("version " + versionId); - VersionDirectory versionDirectory = createVersionDirectory(versionId); - URLClassLoader classLoader = new ClassLoaderService() - .createClassLoader(versionDirectory, dotMinecraftDirectory); + URLClassLoader classLoader = minecraftInstallation.newLauncherProfile(versionId).newClassLoader(); String magicString = RecognisedVersion.generateMagicString(classLoader); builder.addLauncherVersionId(versionId, magicString); } - private VersionDirectory createVersionDirectory(String versionId) { - FilenameService filenameService = new FilenameService(); - File jar = filenameService.getClientJarFile(versions, versionId); - File json = filenameService.getClientJsonFile(versions, versionId); - return new VersionDirectory(versionId, jar, json); - } - private void print() { System.out.println(); System.out.println(); diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 80d9bc0ef..54313d7f5 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -7,13 +7,12 @@ import amidst.clazz.translator.ClassTranslator; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.directory.DotMinecraftDirectory; -import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.facade.LauncherProfile; import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.file.service.DownloadService; -import amidst.mojangapi.file.service.FilenameService; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; @@ -23,22 +22,17 @@ public class GenerateWorldTestData { private final String prefix; - private final File libraries; private final VersionListJson versionList; - private final File versions; - private final DotMinecraftDirectory dotMinecraftDirectory; + private final MinecraftInstallation minecraftInstallation; private final List failed = new LinkedList<>(); private final List successful = new LinkedList<>(); public GenerateWorldTestData(String prefix, String libraries, VersionListJson versionList) throws DotMinecraftDirectoryNotFoundException { this.prefix = prefix; - this.libraries = new File(libraries); this.versionList = versionList; - this.versions = new File(prefix); - this.dotMinecraftDirectory = MinecraftInstallation - .newCustomMinecraftInstallation(this.libraries, null, null, null) - .getDotMinecraftDirectory(); + this.minecraftInstallation = MinecraftInstallation + .newCustomMinecraftInstallation(new File(libraries), null, new File(prefix), null); } public void run() { @@ -58,12 +52,14 @@ private void generate(TestWorldDeclaration declaration, VersionListEntryJson ver if (new DownloadService().tryDownloadClient(prefix, version)) { try { ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); - VersionDirectory versionDirectory = createVersionDirectory(versionId); - TestWorldCache.createAndPut( - declaration, - LocalMinecraftInterface.create(translator, versionDirectory, dotMinecraftDirectory)); + LauncherProfile launcherProfile = minecraftInstallation.newLauncherProfile(versionId); + TestWorldCache.createAndPut(declaration, LocalMinecraftInterface.create(translator, launcherProfile)); successful.add(versionId); - } catch (LocalMinecraftInterfaceCreationException | MinecraftInterfaceException | IOException e) { + } catch ( + LocalMinecraftInterfaceCreationException + | MinecraftInterfaceException + | IOException + | MojangApiParsingException e) { e.printStackTrace(); failed.add(versionId); } @@ -72,13 +68,6 @@ private void generate(TestWorldDeclaration declaration, VersionListEntryJson ver } } - private VersionDirectory createVersionDirectory(String versionId) { - FilenameService filenameService = new FilenameService(); - File jar = filenameService.getClientJarFile(versions, versionId); - File json = filenameService.getClientJsonFile(versions, versionId); - return new VersionDirectory(versionId, jar, json); - } - private void print(String title, Iterable lines) { System.out.println(title); for (String line : lines) { From cf3f7c7bf19cd16033bc9c698c7d7b1a293cedde Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 13:37:56 +0200 Subject: [PATCH 28/48] introduced new facade class SaveGame --- src/main/java/amidst/mojangapi/MojangApi.java | 3 +- .../file/facade/MinecraftInstallation.java | 8 + .../mojangapi/file/facade/SaveGame.java | 71 ++++++ .../mojangapi/file/facade/SaveGamePlayer.java | 35 +++ .../file/nbt/player/LevelDatPlayerNbt.java | 41 ---- .../file/nbt/player/PlayerLocationLoader.java | 18 +- .../file/nbt/player/PlayerLocationSaver.java | 15 +- .../mojangapi/file/nbt/player/PlayerNbt.java | 21 +- .../file/nbt/player/PlayerdataPlayerNbt.java | 44 ---- .../file/nbt/player/PlayersPlayerNbt.java | 44 ---- .../file/service/SaveDirectoryService.java | 202 ++++++++++++++---- .../amidst/mojangapi/world/WorldBuilder.java | 19 +- .../world/player/MovablePlayerList.java | 31 ++- .../amidst/mojangapi/world/player/Player.java | 49 +---- .../world/player/WorldPlayerType.java | 28 ++- 15 files changed, 349 insertions(+), 280 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/facade/SaveGame.java create mode 100644 src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java delete mode 100644 src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java delete mode 100644 src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java delete mode 100644 src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index a98f6c6f2..662cfc1dd 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -12,7 +12,6 @@ import amidst.mojangapi.file.facade.LauncherProfile; import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.SaveDirectoryService; import amidst.mojangapi.file.service.VersionListService; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; @@ -128,7 +127,7 @@ public World createWorldFromSaveGame(File file) MojangApiParsingException { MinecraftInterface minecraftInterface = this.minecraftInterface; if (minecraftInterface != null) { - return worldBuilder.fromSaveGame(minecraftInterface, new SaveDirectoryService().newSaveDirectory(file)); + return worldBuilder.fromSaveGame(minecraftInterface, minecraftInstallation.newSaveGame(file)); } else { throw new IllegalStateException("cannot create a world without a minecraft interface"); } diff --git a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java index d7f7a212b..aace4d0b8 100644 --- a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java @@ -10,9 +10,11 @@ import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; +import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.version.VersionJson; import amidst.mojangapi.file.service.DotMinecraftDirectoryService; +import amidst.mojangapi.file.service.SaveDirectoryService; import amidst.parsing.FormatException; import amidst.parsing.json.JsonReader; @@ -83,4 +85,10 @@ private LauncherProfile newLauncherProfile(VersionDirectory versionDirectory) throw new MojangApiParsingException(e); } } + + public SaveGame newSaveGame(File location) throws IOException, MojangApiParsingException { + SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); + SaveDirectory saveDirectory = saveDirectoryService.newSaveDirectory(location); + return new SaveGame(saveDirectory, saveDirectoryService.createLevelDat(saveDirectory)); + } } diff --git a/src/main/java/amidst/mojangapi/file/facade/SaveGame.java b/src/main/java/amidst/mojangapi/file/facade/SaveGame.java new file mode 100644 index 000000000..c014eda72 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/SaveGame.java @@ -0,0 +1,71 @@ +package amidst.mojangapi.file.facade; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.directory.SaveDirectory; +import amidst.mojangapi.file.nbt.LevelDatNbt; +import amidst.mojangapi.file.service.SaveDirectoryService; +import amidst.mojangapi.world.WorldType; +import amidst.mojangapi.world.coordinates.CoordinatesInWorld; + +@Immutable +public class SaveGame { + private final SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); + private final SaveDirectory saveDirectory; + private final LevelDatNbt levelDatNbt; + + public SaveGame(SaveDirectory saveDirectory, LevelDatNbt levelDatNbt) { + this.saveDirectory = saveDirectory; + this.levelDatNbt = levelDatNbt; + } + + public long getSeed() { + return levelDatNbt.getSeed(); + } + + public CoordinatesInWorld getWorldSpawn() { + return levelDatNbt.getWorldSpawn(); + } + + public WorldType getWorldType() { + return levelDatNbt.getWorldType(); + } + + public String getGeneratorOptions() { + return levelDatNbt.getGeneratorOptions(); + } + + public boolean hasSingleplayerPlayer() { + return levelDatNbt.hasPlayer(); + } + + public boolean hasMultiplayerPlayers() { + return saveDirectory.hasMultiplayerPlayers(); + } + + public Optional tryReadSingleplayerPlayer() { + return saveDirectoryService + .tryReadSingleplayerPlayerNbt(saveDirectory) + .map(p -> new SaveGamePlayer(saveDirectory, p)); + } + + public List tryReadMultiplayerPlayers() { + return saveDirectoryService + .tryReadMultiplayerPlayerNbts(saveDirectory) + .stream() + .map(p -> new SaveGamePlayer(saveDirectory, p)) + .collect(Collectors.toList()); + } + + public List tryReadAllPlayers() { + List result = new LinkedList<>(); + result.addAll(tryReadSingleplayerPlayer().map(Collections::singletonList).orElseGet(Collections::emptyList)); + result.addAll(tryReadMultiplayerPlayers()); + return result; + } +} diff --git a/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java b/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java new file mode 100644 index 000000000..63b00210d --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java @@ -0,0 +1,35 @@ +package amidst.mojangapi.file.facade; + +import java.util.function.Function; +import java.util.function.Supplier; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.directory.SaveDirectory; +import amidst.mojangapi.file.nbt.player.PlayerNbt; +import amidst.mojangapi.file.service.SaveDirectoryService; +import amidst.mojangapi.world.player.PlayerCoordinates; + +@Immutable +public class SaveGamePlayer { + private final SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); + private final SaveDirectory saveDirectory; + private final PlayerNbt playerNbt; + + public SaveGamePlayer(SaveDirectory saveDirectory, PlayerNbt playerNbt) { + this.saveDirectory = saveDirectory; + this.playerNbt = playerNbt; + } + + public PlayerCoordinates getPlayerCoordinates() { + return playerNbt.getPlayerCoordinates(); + } + + public boolean tryBackupAndWritePlayerCoordinates(PlayerCoordinates coordinates) { + return saveDirectoryService.tryBackup(saveDirectory, playerNbt) + && saveDirectoryService.tryWriteCoordinates(saveDirectory, playerNbt, coordinates); + } + + public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { + return playerNbt.map(ifIsLevelDat, ifIsPlayerdata, ifIsPlayers); + } +} diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java deleted file mode 100644 index ae4858f7c..000000000 --- a/src/main/java/amidst/mojangapi/file/nbt/player/LevelDatPlayerNbt.java +++ /dev/null @@ -1,41 +0,0 @@ -package amidst.mojangapi.file.nbt.player; - -import java.io.IOException; -import java.util.function.Function; -import java.util.function.Supplier; - -import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.directory.SaveDirectory; -import amidst.mojangapi.file.nbt.NBTUtils; -import amidst.mojangapi.file.service.AmidstBackupService; -import amidst.mojangapi.world.player.PlayerCoordinates; - -@Immutable -public class LevelDatPlayerNbt extends PlayerNbt { - private final SaveDirectory saveDirectory; - - public LevelDatPlayerNbt(SaveDirectory saveDirectory) { - this.saveDirectory = saveDirectory; - } - - @Override - protected boolean tryBackup() { - return new AmidstBackupService().tryBackupLevelDat(saveDirectory); - } - - @Override - protected void doWriteCoordinates(PlayerCoordinates coordinates) throws MojangApiParsingException { - PlayerLocationSaver.writeToLevelDat(coordinates, saveDirectory.getLevelDat()); - } - - @Override - public PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingException { - return PlayerLocationLoader.readFromLevelDat(NBTUtils.readTagFromFile(saveDirectory.getLevelDat())); - } - - @Override - public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { - return ifIsLevelDat.get(); - } -} diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java index f2514d11a..9c5a1c497 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java @@ -1,6 +1,9 @@ package amidst.mojangapi.file.nbt.player; +import java.io.File; +import java.io.IOException; import java.util.List; +import java.util.Optional; import org.jnbt.CompoundTag; import org.jnbt.IntTag; @@ -8,27 +11,28 @@ import org.jnbt.Tag; import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.nbt.NBTTagKeys; +import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.world.player.PlayerCoordinates; @Immutable public enum PlayerLocationLoader { ; - public static PlayerCoordinates readFromPlayerFile(CompoundTag file) throws MojangApiParsingException { + public static Optional tryReadFromPlayerFile(File file) throws IOException { try { - return readPlayerCoordinates(file); + return Optional.of(readPlayerCoordinates(NBTUtils.readTagFromFile(file))); } catch (NullPointerException e) { - throw new MojangApiParsingException("cannot read player coordinates", e); + return Optional.empty(); } } - public static PlayerCoordinates readFromLevelDat(CompoundTag file) throws MojangApiParsingException { + public static Optional tryReadFromLevelDat(File file) throws IOException { try { - return readPlayerCoordinates(getSinglePlayerPlayerTag(getTagRootTag(file))); + return Optional + .of(readPlayerCoordinates(getSinglePlayerPlayerTag(getTagRootTag(NBTUtils.readTagFromFile(file))))); } catch (NullPointerException e) { - throw new MojangApiParsingException("cannot read player coordinates", e); + return Optional.empty(); } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java index 2dd30c5d5..374f60e8f 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java @@ -13,7 +13,6 @@ import org.jnbt.Tag; import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.nbt.NBTTagKeys; import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.world.player.PlayerCoordinates; @@ -22,23 +21,25 @@ public enum PlayerLocationSaver { ; - public static void writeToPlayerFile(PlayerCoordinates coordinates, File file) throws MojangApiParsingException { + public static boolean tryWriteToPlayerFile(PlayerCoordinates coordinates, File file) throws IOException { try { CompoundTag dataTag = NBTUtils.readTagFromFile(file); CompoundTag modifiedDataTag = modifyPositionInDataTagMultiPlayer(dataTag, coordinates); NBTUtils.writeTagToFile(file, modifiedDataTag); - } catch (IOException | NullPointerException e) { - throw new MojangApiParsingException("cannot write player coordinates", e); + return true; + } catch (NullPointerException e) { + return false; } } - public static void writeToLevelDat(PlayerCoordinates coordinates, File file) throws MojangApiParsingException { + public static boolean tryWriteToLevelDat(PlayerCoordinates coordinates, File file) throws IOException { try { CompoundTag baseTag = NBTUtils.readTagFromFile(file); CompoundTag modifiedBaseTag = modifyPositionInBaseTagSinglePlayer(baseTag, coordinates); NBTUtils.writeTagToFile(file, modifiedBaseTag); - } catch (IOException | NullPointerException e) { - throw new MojangApiParsingException("cannot write player coordinates", e); + return true; + } catch (NullPointerException e) { + return false; } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java index 2656d8fea..9b62690ee 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerNbt.java @@ -1,29 +1,22 @@ package amidst.mojangapi.file.nbt.player; -import java.io.IOException; import java.util.function.Function; import java.util.function.Supplier; import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.world.player.PlayerCoordinates; @Immutable public abstract class PlayerNbt { - public boolean tryWriteCoordinates(PlayerCoordinates coordinates) throws MojangApiParsingException { - if (tryBackup()) { - doWriteCoordinates(coordinates); - return true; - } else { - return false; - } - } - - protected abstract boolean tryBackup(); + private final PlayerCoordinates playerCoordinates; - protected abstract void doWriteCoordinates(PlayerCoordinates coordinates) throws MojangApiParsingException; + public PlayerNbt(PlayerCoordinates playerCoordinates) { + this.playerCoordinates = playerCoordinates; + } - public abstract PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingException; + public PlayerCoordinates getPlayerCoordinates() { + return playerCoordinates; + } public abstract R map( Supplier ifIsLevelDat, diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java deleted file mode 100644 index c2b7e4627..000000000 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerdataPlayerNbt.java +++ /dev/null @@ -1,44 +0,0 @@ -package amidst.mojangapi.file.nbt.player; - -import java.io.IOException; -import java.util.function.Function; -import java.util.function.Supplier; - -import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.directory.SaveDirectory; -import amidst.mojangapi.file.nbt.NBTUtils; -import amidst.mojangapi.file.service.AmidstBackupService; -import amidst.mojangapi.world.player.PlayerCoordinates; - -@Immutable -public class PlayerdataPlayerNbt extends PlayerNbt { - private final SaveDirectory saveDirectory; - private final String playerUUID; - - public PlayerdataPlayerNbt(SaveDirectory saveDirectory, String playerUUID) { - this.saveDirectory = saveDirectory; - this.playerUUID = playerUUID; - } - - @Override - protected boolean tryBackup() { - return new AmidstBackupService().tryBackupPlayerdataFile(saveDirectory, playerUUID); - } - - @Override - protected void doWriteCoordinates(PlayerCoordinates coordinates) throws MojangApiParsingException { - PlayerLocationSaver.writeToPlayerFile(coordinates, saveDirectory.getPlayerdataFile(playerUUID)); - } - - @Override - public PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingException { - return PlayerLocationLoader - .readFromPlayerFile(NBTUtils.readTagFromFile(saveDirectory.getPlayerdataFile(playerUUID))); - } - - @Override - public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { - return ifIsPlayerdata.apply(playerUUID); - } -} diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java deleted file mode 100644 index 7c0d32190..000000000 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayersPlayerNbt.java +++ /dev/null @@ -1,44 +0,0 @@ -package amidst.mojangapi.file.nbt.player; - -import java.io.IOException; -import java.util.function.Function; -import java.util.function.Supplier; - -import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.directory.SaveDirectory; -import amidst.mojangapi.file.nbt.NBTUtils; -import amidst.mojangapi.file.service.AmidstBackupService; -import amidst.mojangapi.world.player.PlayerCoordinates; - -@Immutable -public class PlayersPlayerNbt extends PlayerNbt { - private final SaveDirectory saveDirectory; - private final String playerName; - - public PlayersPlayerNbt(SaveDirectory saveDirectory, String playerName) { - this.saveDirectory = saveDirectory; - this.playerName = playerName; - } - - @Override - protected boolean tryBackup() { - return new AmidstBackupService().tryBackupPlayersFile(saveDirectory, playerName); - } - - @Override - protected void doWriteCoordinates(PlayerCoordinates coordinates) throws MojangApiParsingException { - PlayerLocationSaver.writeToPlayerFile(coordinates, saveDirectory.getPlayersFile(playerName)); - } - - @Override - public PlayerCoordinates readCoordinates() throws IOException, MojangApiParsingException { - return PlayerLocationLoader - .readFromPlayerFile(NBTUtils.readTagFromFile(saveDirectory.getPlayersFile(playerName))); - } - - @Override - public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { - return ifIsPlayers.apply(playerName); - } -} diff --git a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java index b41fa8ea8..3773c5e69 100644 --- a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java @@ -3,9 +3,13 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; import amidst.documentation.Immutable; import amidst.documentation.NotNull; @@ -14,13 +18,15 @@ import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.LevelDatNbt; import amidst.mojangapi.file.nbt.NBTUtils; -import amidst.mojangapi.file.nbt.player.LevelDatPlayerNbt; +import amidst.mojangapi.file.nbt.player.PlayerLocationLoader; +import amidst.mojangapi.file.nbt.player.PlayerLocationSaver; import amidst.mojangapi.file.nbt.player.PlayerNbt; -import amidst.mojangapi.file.nbt.player.PlayerdataPlayerNbt; -import amidst.mojangapi.file.nbt.player.PlayersPlayerNbt; +import amidst.mojangapi.world.player.PlayerCoordinates; @Immutable public class SaveDirectoryService { + private final AmidstBackupService amidstBackupService = new AmidstBackupService(); + /** * Returns a new valid instance of the class SaveDirectory. It tries to use * the given file. If that is not valid it tires to use its parent file. If @@ -78,9 +84,9 @@ public LevelDatNbt createLevelDat(SaveDirectory saveDirectory) throws IOExceptio * the map is used as singleplayer map. */ @NotNull - public List createSingleplayerPlayerNbts(SaveDirectory saveDirectory) { + public Optional tryReadSingleplayerPlayerNbt(SaveDirectory saveDirectory) { AmidstLogger.info("using player from level.dat"); - return Arrays.asList(new LevelDatPlayerNbt(saveDirectory)); + return tryReadCoordinatesFromLevelDat(saveDirectory).map(this::createLevelDatPlayerNbt); } /** @@ -88,53 +94,175 @@ public List createSingleplayerPlayerNbts(SaveDirectory saveDirectory) * and uses the player uuid as filename. */ @NotNull - public List createMultiplayerPlayerNbts(SaveDirectory saveDirectory) { - List result = new ArrayList<>(); - for (File playerdataFile : getPlayerdataFiles(saveDirectory)) { - if (playerdataFile.isFile()) { - result.add(new PlayerdataPlayerNbt(saveDirectory, getPlayerUUIDFromPlayerdataFile(playerdataFile))); - } - } - if (!result.isEmpty()) { + public List tryReadMultiplayerPlayerNbts(SaveDirectory saveDirectory) { + List playerdataPlayers = listFiles(saveDirectory.getPlayerdata()) + .stream() + .filter(File::isFile) + .map(f -> createPlayerdataPlayerNbt(saveDirectory, f)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + if (!playerdataPlayers.isEmpty()) { AmidstLogger.info("using players from the playerdata directory"); - return result; - } - for (File playersFile : getPlayersFiles(saveDirectory)) { - if (playersFile.isFile()) { - result.add(new PlayersPlayerNbt(saveDirectory, getPlayerNameFromPlayersFile(playersFile))); + return playerdataPlayers; + } else { + List playersPlayers = listFiles(saveDirectory.getPlayers()) + .stream() + .filter(File::isFile) + .map(f -> createPlayersPlayerNbt(saveDirectory, f)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + if (!playersPlayers.isEmpty()) { + AmidstLogger.info("using players from the players directory"); + return playersPlayers; + } else { + AmidstLogger.info("no multiplayer players found"); + return Collections.emptyList(); } } - if (!result.isEmpty()) { - AmidstLogger.info("using players from the players directory"); - return result; - } - AmidstLogger.info("no multiplayer players found"); - return result; } - private File[] getPlayerdataFiles(SaveDirectory saveDirectory) { - File[] files = saveDirectory.getPlayerdata().listFiles(); - if (files == null) { - return new File[0]; + private List listFiles(File file) { + File[] files = file.listFiles(); + if (files != null) { + return Arrays.asList(files); } else { - return files; + return Collections.emptyList(); } } - private File[] getPlayersFiles(SaveDirectory saveDirectory) { - File[] files = saveDirectory.getPlayers().listFiles(); - if (files == null) { - return new File[0]; - } else { - return files; - } + private Optional createPlayerdataPlayerNbt(SaveDirectory saveDirectory, File playerdataFile) { + String playerUUID = getPlayerUUIDFromPlayerdataFile(playerdataFile); + return tryReadCoordinatesFromPlayerdata(saveDirectory, playerUUID) + .map(c -> createPlayerdataPlayerNbt(playerUUID, c)); } private String getPlayerUUIDFromPlayerdataFile(File playerdataFile) { return playerdataFile.getName().split("\\.")[0]; } + private Optional createPlayersPlayerNbt(SaveDirectory saveDirectory, File playersFile) { + String playerName = getPlayerNameFromPlayersFile(playersFile); + return tryReadCoordinatesFromPlayers(saveDirectory, playerName).map(c -> createPlayersPlayerNbt(playerName, c)); + } + private String getPlayerNameFromPlayersFile(File playersFile) { return playersFile.getName().split("\\.")[0]; } + + private PlayerNbt createLevelDatPlayerNbt(PlayerCoordinates playerCoordinates) { + return new PlayerNbt(playerCoordinates) { + @Override + public R map( + Supplier ifIsLevelDat, + Function ifIsPlayerdata, + Function ifIsPlayers) { + return ifIsLevelDat.get(); + } + }; + } + + private PlayerNbt createPlayerdataPlayerNbt(String playerUUID, PlayerCoordinates playerCoordinates) { + return new PlayerNbt(playerCoordinates) { + @Override + public R map( + Supplier ifIsLevelDat, + Function ifIsPlayerdata, + Function ifIsPlayers) { + return ifIsPlayerdata.apply(playerUUID); + } + }; + } + + private PlayerNbt createPlayersPlayerNbt(String playerName, PlayerCoordinates playerCoordinates) { + return new PlayerNbt(playerCoordinates) { + @Override + public R map( + Supplier ifIsLevelDat, + Function ifIsPlayerdata, + Function ifIsPlayers) { + return ifIsPlayers.apply(playerName); + } + }; + } + + private Optional tryReadCoordinatesFromLevelDat(SaveDirectory saveDirectory) { + try { + return PlayerLocationLoader.tryReadFromLevelDat(saveDirectory.getLevelDat()); + } catch (IOException e) { + AmidstLogger.warn(e, "error while reading player coordinates from level.dat"); + return Optional.empty(); + } + } + + private Optional tryReadCoordinatesFromPlayerdata( + SaveDirectory saveDirectory, + String playerUUID) { + try { + return PlayerLocationLoader.tryReadFromPlayerFile(saveDirectory.getPlayerdataFile(playerUUID)); + } catch (IOException e) { + AmidstLogger.warn(e, "error while reading player coordinates for player " + playerUUID); + return Optional.empty(); + } + } + + private Optional tryReadCoordinatesFromPlayers(SaveDirectory saveDirectory, String playerName) { + try { + return PlayerLocationLoader.tryReadFromPlayerFile(saveDirectory.getPlayersFile(playerName)); + } catch (IOException e) { + AmidstLogger.warn(e, "error while reading player coordinates for player " + playerName); + return Optional.empty(); + } + } + + public boolean tryBackup(SaveDirectory saveDirectory, PlayerNbt playerNbt) { + return playerNbt.map( + () -> amidstBackupService.tryBackupLevelDat(saveDirectory), + playerUUID -> amidstBackupService.tryBackupPlayerdataFile(saveDirectory, playerUUID), + playerName -> amidstBackupService.tryBackupPlayersFile(saveDirectory, playerName)); + } + + public boolean tryWriteCoordinates( + SaveDirectory saveDirectory, + PlayerNbt playerNbt, + PlayerCoordinates coordinates) { + return playerNbt.map( + () -> tryWriteCoordinatesToLevelDat(saveDirectory, coordinates), + playerUUID -> tryWriteCoordinatesToPlayerdata(saveDirectory, playerUUID, coordinates), + playerName -> tryWriteCoordinatesToPlayers(saveDirectory, playerName, coordinates)); + } + + private boolean tryWriteCoordinatesToLevelDat(SaveDirectory saveDirectory, PlayerCoordinates coordinates) { + try { + return PlayerLocationSaver.tryWriteToLevelDat(coordinates, saveDirectory.getLevelDat()); + } catch (IOException e) { + AmidstLogger.warn(e, "error while writing player coordinates to level.dat"); + return false; + } + } + + private boolean tryWriteCoordinatesToPlayerdata( + SaveDirectory saveDirectory, + String playerUUID, + PlayerCoordinates coordinates) { + try { + return PlayerLocationSaver.tryWriteToPlayerFile(coordinates, saveDirectory.getPlayerdataFile(playerUUID)); + } catch (IOException e) { + AmidstLogger.warn(e, "error while writing player coordinates for player " + playerUUID); + return false; + } + } + + private boolean tryWriteCoordinatesToPlayers( + SaveDirectory saveDirectory, + String playerName, + PlayerCoordinates coordinates) { + try { + return PlayerLocationSaver.tryWriteToPlayerFile(coordinates, saveDirectory.getPlayersFile(playerName)); + } catch (IOException e) { + AmidstLogger.warn(e, "error while writing player coordinates for player " + playerName); + return false; + } + } } diff --git a/src/main/java/amidst/mojangapi/world/WorldBuilder.java b/src/main/java/amidst/mojangapi/world/WorldBuilder.java index 25daa34ec..933730586 100644 --- a/src/main/java/amidst/mojangapi/world/WorldBuilder.java +++ b/src/main/java/amidst/mojangapi/world/WorldBuilder.java @@ -4,9 +4,7 @@ import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.directory.SaveDirectory; -import amidst.mojangapi.file.nbt.LevelDatNbt; -import amidst.mojangapi.file.service.SaveDirectoryService; +import amidst.mojangapi.file.facade.SaveGame; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -74,26 +72,25 @@ public World fromSeed(MinecraftInterface minecraftInterface, WorldSeed worldSeed versionFeatures.getValidBiomesForStructure_Spawn())); } - public World fromSaveGame(MinecraftInterface minecraftInterface, SaveDirectory saveDirectory) + public World fromSaveGame(MinecraftInterface minecraftInterface, SaveGame saveGame) throws IOException, MinecraftInterfaceException, MojangApiParsingException { VersionFeatures versionFeatures = DefaultVersionFeatures.create(minecraftInterface.getRecognisedVersion()); - LevelDatNbt levelDat = new SaveDirectoryService().createLevelDat(saveDirectory); MovablePlayerList movablePlayerList = new MovablePlayerList( playerInformationCache, - saveDirectory, + saveGame, true, - WorldPlayerType.from(saveDirectory, levelDat)); + WorldPlayerType.from(saveGame)); return create( minecraftInterface, - WorldSeed.fromSaveGame(levelDat.getSeed()), - levelDat.getWorldType(), - levelDat.getGeneratorOptions(), + WorldSeed.fromSaveGame(saveGame.getSeed()), + saveGame.getWorldType(), + saveGame.getGeneratorOptions(), movablePlayerList, versionFeatures, new BiomeDataOracle(minecraftInterface), - new ImmutableWorldSpawnOracle(levelDat.getWorldSpawn())); + new ImmutableWorldSpawnOracle(saveGame.getWorldSpawn())); } private World create( diff --git a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java index fc5c46295..59c737307 100644 --- a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java +++ b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java @@ -7,8 +7,8 @@ import amidst.documentation.CalledOnlyBy; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.directory.SaveDirectory; -import amidst.mojangapi.file.nbt.player.PlayerNbt; +import amidst.mojangapi.file.facade.SaveGame; +import amidst.mojangapi.file.facade.SaveGamePlayer; import amidst.threading.WorkerExecutor; @ThreadSafe @@ -20,7 +20,7 @@ public static MovablePlayerList dummy() { } private final PlayerInformationCache playerInformationCache; - private final SaveDirectory saveDirectory; + private final SaveGame saveGame; private final boolean isSaveEnabled; private volatile WorldPlayerType worldPlayerType; @@ -28,11 +28,11 @@ public static MovablePlayerList dummy() { public MovablePlayerList( PlayerInformationCache playerInformationCache, - SaveDirectory saveDirectory, + SaveGame saveGame, boolean isSaveEnabled, WorldPlayerType worldPlayerType) { this.playerInformationCache = playerInformationCache; - this.saveDirectory = saveDirectory; + this.saveGame = saveGame; this.isSaveEnabled = isSaveEnabled; this.worldPlayerType = worldPlayerType; } @@ -46,11 +46,11 @@ public void setWorldPlayerType(WorldPlayerType worldPlayerType) { } public boolean canLoad() { - return saveDirectory != null; + return saveGame != null; } public void load(WorkerExecutor workerExecutor, Runnable onPlayerFinishedLoading) { - if (saveDirectory != null) { + if (saveGame != null) { AmidstLogger.info("loading player locations"); ConcurrentLinkedQueue players = new ConcurrentLinkedQueue<>(); this.players = players; @@ -70,20 +70,17 @@ private void loadPlayers( WorkerExecutor workerExecutor, ConcurrentLinkedQueue players, Runnable onPlayerFinishedLoading) { - for (PlayerNbt playerNbt : worldPlayerType.createPlayerNbts(saveDirectory)) { - workerExecutor.run(() -> loadPlayer(players, playerNbt), onPlayerFinishedLoading); + for (SaveGamePlayer saveGamePlayer : worldPlayerType.tryReadPlayers(saveGame)) { + workerExecutor.run(() -> loadPlayer(players, saveGamePlayer), onPlayerFinishedLoading); } } @CalledOnlyBy(AmidstThread.WORKER) - private void loadPlayer(ConcurrentLinkedQueue players, PlayerNbt playerNbt) { - Player player = playerNbt.map( - () -> new Player(PlayerInformation.theSingleplayerPlayer(), playerNbt), - playerUUID -> new Player(playerInformationCache.getByUUID(playerUUID), playerNbt), - playerName -> new Player(playerInformationCache.getByName(playerName), playerNbt)); - if (player.tryLoadLocation()) { - players.offer(player); - } + private void loadPlayer(ConcurrentLinkedQueue players, SaveGamePlayer saveGamePlayer) { + players.offer(saveGamePlayer.map( + () -> new Player(PlayerInformation.theSingleplayerPlayer(), saveGamePlayer), + playerUUID -> new Player(playerInformationCache.getByUUID(playerUUID), saveGamePlayer), + playerName -> new Player(playerInformationCache.getByName(playerName), saveGamePlayer))); } public boolean canSave() { diff --git a/src/main/java/amidst/mojangapi/world/player/Player.java b/src/main/java/amidst/mojangapi/world/player/Player.java index 7c44fc174..4c40fc8c0 100644 --- a/src/main/java/amidst/mojangapi/world/player/Player.java +++ b/src/main/java/amidst/mojangapi/world/player/Player.java @@ -1,11 +1,8 @@ package amidst.mojangapi.world.player; -import java.io.IOException; - import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.nbt.player.PlayerNbt; +import amidst.mojangapi.file.facade.SaveGamePlayer; import amidst.mojangapi.world.Dimension; import amidst.mojangapi.world.coordinates.CoordinatesInWorld; import amidst.mojangapi.world.icon.WorldIconImage; @@ -13,13 +10,15 @@ @ThreadSafe public class Player { private final PlayerInformation playerInformation; - private final PlayerNbt playerNbt; + private final SaveGamePlayer saveGamePlayer; private volatile PlayerCoordinates savedCoordinates; private volatile PlayerCoordinates currentCoordinates; - public Player(PlayerInformation playerInformation, PlayerNbt playerNbt) { + public Player(PlayerInformation playerInformation, SaveGamePlayer saveGamePlayer) { this.playerInformation = playerInformation; - this.playerNbt = playerNbt; + this.saveGamePlayer = saveGamePlayer; + this.savedCoordinates = saveGamePlayer.getPlayerCoordinates(); + this.currentCoordinates = savedCoordinates; } public String getPlayerName() { @@ -38,52 +37,22 @@ public void moveTo(CoordinatesInWorld coordinates, long height, Dimension dimens this.currentCoordinates = new PlayerCoordinates(coordinates, height, dimension); } - public boolean trySaveLocation() { - try { - if (saveLocation()) { - return true; - } else { - AmidstLogger.warn( - "skipping to save player location, because the backup file cannot be created for player: " - + getPlayerName()); - return false; - } - } catch (MojangApiParsingException e) { - AmidstLogger.warn(e, "error while writing player location for player: " + getPlayerName()); - return false; - } - } - /** * Returns true if the player was not moved or the new location was * successfully saved. */ - public synchronized boolean saveLocation() throws MojangApiParsingException { + public synchronized boolean trySaveLocation() { PlayerCoordinates currentCoordinates = this.currentCoordinates; if (savedCoordinates != currentCoordinates) { - if (playerNbt.tryWriteCoordinates(currentCoordinates)) { + if (saveGamePlayer.tryBackupAndWritePlayerCoordinates(currentCoordinates)) { savedCoordinates = currentCoordinates; return true; } else { + AmidstLogger.warn("error while writing player location for player: " + getPlayerName()); return false; } } else { return true; } } - - public boolean tryLoadLocation() { - try { - loadLocation(); - return true; - } catch (IOException | MojangApiParsingException e) { - AmidstLogger.warn(e, "error while reading player location for player: " + getPlayerName()); - return false; - } - } - - public synchronized void loadLocation() throws IOException, MojangApiParsingException { - this.savedCoordinates = playerNbt.readCoordinates(); - this.currentCoordinates = savedCoordinates; - } } diff --git a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java index 9e0ecec61..557b0a8ac 100644 --- a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java +++ b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java @@ -1,16 +1,13 @@ package amidst.mojangapi.world.player; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.directory.SaveDirectory; -import amidst.mojangapi.file.nbt.LevelDatNbt; -import amidst.mojangapi.file.nbt.player.PlayerNbt; -import amidst.mojangapi.file.service.SaveDirectoryService; +import amidst.mojangapi.file.facade.SaveGame; +import amidst.mojangapi.file.facade.SaveGamePlayer; @Immutable public enum WorldPlayerType { @@ -27,9 +24,9 @@ public static List getSelectable() { return SELECTABLE; } - public static WorldPlayerType from(SaveDirectory saveDirectory, LevelDatNbt levelDat) { - boolean hasSingleplayerPlayer = levelDat.hasPlayer(); - boolean hasMultiplayerPlayers = saveDirectory.hasMultiplayerPlayers(); + public static WorldPlayerType from(SaveGame saveGame) { + boolean hasSingleplayerPlayer = saveGame.hasSingleplayerPlayer(); + boolean hasMultiplayerPlayers = saveGame.hasMultiplayerPlayers(); if (hasSingleplayerPlayer && hasMultiplayerPlayers) { return BOTH; } else if (hasSingleplayerPlayer) { @@ -52,17 +49,16 @@ public String getName() { } @NotNull - public List createPlayerNbts(SaveDirectory saveDirectory) { - SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); + public List tryReadPlayers(SaveGame saveGame) { if (this == BOTH) { - List result = new ArrayList<>(); - result.addAll(saveDirectoryService.createSingleplayerPlayerNbts(saveDirectory)); - result.addAll(saveDirectoryService.createMultiplayerPlayerNbts(saveDirectory)); - return result; + return saveGame.tryReadAllPlayers(); } else if (this == SINGLEPLAYER) { - return saveDirectoryService.createSingleplayerPlayerNbts(saveDirectory); + return saveGame + .tryReadSingleplayerPlayer() + .map(Collections::singletonList) + .orElseGet(Collections::emptyList); } else if (this == MULTIPLAYER) { - return saveDirectoryService.createMultiplayerPlayerNbts(saveDirectory); + return saveGame.tryReadMultiplayerPlayers(); } else { return Collections.emptyList(); } From bc895dc975d4942d3dd8848fc34b05e4a878cb5c Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 19:07:53 +0200 Subject: [PATCH 29/48] introduced facade interface PlayerInformationProvider --- .../java/amidst/PerApplicationInjector.java | 10 +++---- .../ImmutablePlayerInformationProvider.java | 26 +++++++++++++++++++ .../facade/PlayerInformationCache.java} | 17 ++++++------ .../facade/PlayerInformationProvider.java | 14 ++++++++++ .../mojangapi/file/facade/SaveGamePlayer.java | 11 ++++---- .../amidst/mojangapi/world/WorldBuilder.java | 14 +++++----- .../ImmutablePlayerInformationCache.java | 25 ------------------ .../world/player/MovablePlayerList.java | 12 ++++----- .../world/player/PlayerInformationCache.java | 13 ---------- 9 files changed, 72 insertions(+), 70 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/facade/ImmutablePlayerInformationProvider.java rename src/main/java/amidst/mojangapi/{world/player/PlayerInformationCacheImpl.java => file/facade/PlayerInformationCache.java} (78%) create mode 100644 src/main/java/amidst/mojangapi/file/facade/PlayerInformationProvider.java delete mode 100644 src/main/java/amidst/mojangapi/world/player/ImmutablePlayerInformationCache.java delete mode 100644 src/main/java/amidst/mojangapi/world/player/PlayerInformationCache.java diff --git a/src/main/java/amidst/PerApplicationInjector.java b/src/main/java/amidst/PerApplicationInjector.java index ee16c0012..306a28c74 100644 --- a/src/main/java/amidst/PerApplicationInjector.java +++ b/src/main/java/amidst/PerApplicationInjector.java @@ -19,12 +19,12 @@ import amidst.mojangapi.MojangApi; import amidst.mojangapi.MojangApiBuilder; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.facade.PlayerInformationCache; +import amidst.mojangapi.file.facade.PlayerInformationProvider; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.SeedHistoryLogger; import amidst.mojangapi.world.World; import amidst.mojangapi.world.WorldBuilder; -import amidst.mojangapi.world.player.PlayerInformationCache; -import amidst.mojangapi.world.player.PlayerInformationCacheImpl; import amidst.settings.biomeprofile.BiomeProfileDirectory; import amidst.threading.ThreadMaster; @@ -32,7 +32,7 @@ public class PerApplicationInjector { private final AmidstMetaData metadata; private final AmidstSettings settings; - private final PlayerInformationCache playerInformationCache; + private final PlayerInformationProvider playerInformationProvider; private final SeedHistoryLogger seedHistoryLogger; private final WorldBuilder worldBuilder; private final MojangApi mojangApi; @@ -50,9 +50,9 @@ public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData m LocalMinecraftInterfaceCreationException { this.metadata = metadata; this.settings = settings; - this.playerInformationCache = new PlayerInformationCacheImpl(); + this.playerInformationProvider = new PlayerInformationCache(); this.seedHistoryLogger = SeedHistoryLogger.from(parameters.seedHistoryFile); - this.worldBuilder = new WorldBuilder(playerInformationCache, seedHistoryLogger); + this.worldBuilder = new WorldBuilder(playerInformationProvider, seedHistoryLogger); this.mojangApi = new MojangApiBuilder(worldBuilder, parameters).construct(); this.biomeProfileDirectory = BiomeProfileDirectory.create(parameters.biomeProfilesDirectory); this.threadMaster = new ThreadMaster(); diff --git a/src/main/java/amidst/mojangapi/file/facade/ImmutablePlayerInformationProvider.java b/src/main/java/amidst/mojangapi/file/facade/ImmutablePlayerInformationProvider.java new file mode 100644 index 000000000..77a847a14 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/ImmutablePlayerInformationProvider.java @@ -0,0 +1,26 @@ +package amidst.mojangapi.file.facade; + +import amidst.documentation.Immutable; +import amidst.documentation.NotNull; +import amidst.mojangapi.world.player.PlayerInformation; + +@Immutable +public class ImmutablePlayerInformationProvider implements PlayerInformationProvider { + private final PlayerInformation playerInformation; + + public ImmutablePlayerInformationProvider(PlayerInformation playerInformation) { + this.playerInformation = playerInformation; + } + + @NotNull + @Override + public PlayerInformation getByPlayerUUID(String playerUUID) { + return playerInformation; + } + + @NotNull + @Override + public PlayerInformation getByPlayerName(String playerName) { + return playerInformation; + } +} diff --git a/src/main/java/amidst/mojangapi/world/player/PlayerInformationCacheImpl.java b/src/main/java/amidst/mojangapi/file/facade/PlayerInformationCache.java similarity index 78% rename from src/main/java/amidst/mojangapi/world/player/PlayerInformationCacheImpl.java rename to src/main/java/amidst/mojangapi/file/facade/PlayerInformationCache.java index 2e850d155..d90a6ae04 100644 --- a/src/main/java/amidst/mojangapi/world/player/PlayerInformationCacheImpl.java +++ b/src/main/java/amidst/mojangapi/file/facade/PlayerInformationCache.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.world.player; +package amidst.mojangapi.file.facade; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -7,6 +7,7 @@ import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.service.PlayerInformationService; +import amidst.mojangapi.world.player.PlayerInformation; /** * Even though this class is thread-safe, it is possible that the same player @@ -16,15 +17,15 @@ * problem. */ @ThreadSafe -public class PlayerInformationCacheImpl implements PlayerInformationCache { +public class PlayerInformationCache implements PlayerInformationProvider { private final Map byUUID = new ConcurrentHashMap<>(); private final Map byName = new ConcurrentHashMap<>(); private final PlayerInformationService playerInformationService = new PlayerInformationService(); @NotNull @Override - public PlayerInformation getByUUID(String uuid) { - String cleanUUID = getCleanUUID(uuid); + public PlayerInformation getByPlayerUUID(String playerUUID) { + String cleanUUID = getCleanUUID(playerUUID); PlayerInformation result = byUUID.get(cleanUUID); if (result != null) { return result; @@ -38,13 +39,13 @@ public PlayerInformation getByUUID(String uuid) { @NotNull @Override - public PlayerInformation getByName(String name) { - PlayerInformation result = byName.get(name); + public PlayerInformation getByPlayerName(String playerName) { + PlayerInformation result = byName.get(playerName); if (result != null) { return result; } else { - AmidstLogger.info("requesting player information for name: " + name); - result = playerInformationService.fromName(name); + AmidstLogger.info("requesting player information for name: " + playerName); + result = playerInformationService.fromName(playerName); put(result); return result; } diff --git a/src/main/java/amidst/mojangapi/file/facade/PlayerInformationProvider.java b/src/main/java/amidst/mojangapi/file/facade/PlayerInformationProvider.java new file mode 100644 index 000000000..63c649747 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/PlayerInformationProvider.java @@ -0,0 +1,14 @@ +package amidst.mojangapi.file.facade; + +import amidst.documentation.NotNull; +import amidst.documentation.ThreadSafe; +import amidst.mojangapi.world.player.PlayerInformation; + +@ThreadSafe +public interface PlayerInformationProvider { + @NotNull + PlayerInformation getByPlayerUUID(String playerUUID); + + @NotNull + PlayerInformation getByPlayerName(String playerName); +} diff --git a/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java b/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java index 63b00210d..59d3f70fa 100644 --- a/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java +++ b/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java @@ -1,13 +1,11 @@ package amidst.mojangapi.file.facade; -import java.util.function.Function; -import java.util.function.Supplier; - import amidst.documentation.Immutable; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.player.PlayerNbt; import amidst.mojangapi.file.service.SaveDirectoryService; import amidst.mojangapi.world.player.PlayerCoordinates; +import amidst.mojangapi.world.player.PlayerInformation; @Immutable public class SaveGamePlayer { @@ -29,7 +27,10 @@ public boolean tryBackupAndWritePlayerCoordinates(PlayerCoordinates coordinates) && saveDirectoryService.tryWriteCoordinates(saveDirectory, playerNbt, coordinates); } - public R map(Supplier ifIsLevelDat, Function ifIsPlayerdata, Function ifIsPlayers) { - return playerNbt.map(ifIsLevelDat, ifIsPlayerdata, ifIsPlayers); + public PlayerInformation getPlayerInformation(PlayerInformationProvider playerInformationProvider) { + return playerNbt.map( + () -> PlayerInformation.theSingleplayerPlayer(), + playerUUID -> playerInformationProvider.getByPlayerUUID(playerUUID), + playerName -> playerInformationProvider.getByPlayerName(playerName)); } } diff --git a/src/main/java/amidst/mojangapi/world/WorldBuilder.java b/src/main/java/amidst/mojangapi/world/WorldBuilder.java index 933730586..ae6ab481a 100644 --- a/src/main/java/amidst/mojangapi/world/WorldBuilder.java +++ b/src/main/java/amidst/mojangapi/world/WorldBuilder.java @@ -4,6 +4,8 @@ import amidst.documentation.Immutable; import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.facade.ImmutablePlayerInformationProvider; +import amidst.mojangapi.file.facade.PlayerInformationProvider; import amidst.mojangapi.file.facade.SaveGame; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; @@ -26,10 +28,8 @@ import amidst.mojangapi.world.oracle.ImmutableWorldSpawnOracle; import amidst.mojangapi.world.oracle.SlimeChunkOracle; import amidst.mojangapi.world.oracle.WorldSpawnOracle; -import amidst.mojangapi.world.player.ImmutablePlayerInformationCache; import amidst.mojangapi.world.player.MovablePlayerList; import amidst.mojangapi.world.player.PlayerInformation; -import amidst.mojangapi.world.player.PlayerInformationCache; import amidst.mojangapi.world.player.WorldPlayerType; import amidst.mojangapi.world.versionfeatures.DefaultVersionFeatures; import amidst.mojangapi.world.versionfeatures.VersionFeatures; @@ -42,15 +42,15 @@ public class WorldBuilder { */ public static WorldBuilder createSilentPlayerless() { return new WorldBuilder( - new ImmutablePlayerInformationCache(PlayerInformation.theSingleplayerPlayer()), + new ImmutablePlayerInformationProvider(PlayerInformation.theSingleplayerPlayer()), SeedHistoryLogger.createDisabled()); } - private final PlayerInformationCache playerInformationCache; + private final PlayerInformationProvider playerInformationProvider; private final SeedHistoryLogger seedHistoryLogger; - public WorldBuilder(PlayerInformationCache playerInformationCache, SeedHistoryLogger seedHistoryLogger) { - this.playerInformationCache = playerInformationCache; + public WorldBuilder(PlayerInformationProvider playerInformationProvider, SeedHistoryLogger seedHistoryLogger) { + this.playerInformationProvider = playerInformationProvider; this.seedHistoryLogger = seedHistoryLogger; } @@ -78,7 +78,7 @@ public World fromSaveGame(MinecraftInterface minecraftInterface, SaveGame saveGa MojangApiParsingException { VersionFeatures versionFeatures = DefaultVersionFeatures.create(minecraftInterface.getRecognisedVersion()); MovablePlayerList movablePlayerList = new MovablePlayerList( - playerInformationCache, + playerInformationProvider, saveGame, true, WorldPlayerType.from(saveGame)); diff --git a/src/main/java/amidst/mojangapi/world/player/ImmutablePlayerInformationCache.java b/src/main/java/amidst/mojangapi/world/player/ImmutablePlayerInformationCache.java deleted file mode 100644 index d4b854ab2..000000000 --- a/src/main/java/amidst/mojangapi/world/player/ImmutablePlayerInformationCache.java +++ /dev/null @@ -1,25 +0,0 @@ -package amidst.mojangapi.world.player; - -import amidst.documentation.Immutable; -import amidst.documentation.NotNull; - -@Immutable -public class ImmutablePlayerInformationCache implements PlayerInformationCache { - private final PlayerInformation playerInformation; - - public ImmutablePlayerInformationCache(PlayerInformation playerInformation) { - this.playerInformation = playerInformation; - } - - @NotNull - @Override - public PlayerInformation getByUUID(String uuid) { - return playerInformation; - } - - @NotNull - @Override - public PlayerInformation getByName(String name) { - return playerInformation; - } -} diff --git a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java index 59c737307..dea1ada5e 100644 --- a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java +++ b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java @@ -7,6 +7,7 @@ import amidst.documentation.CalledOnlyBy; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.facade.PlayerInformationProvider; import amidst.mojangapi.file.facade.SaveGame; import amidst.mojangapi.file.facade.SaveGamePlayer; import amidst.threading.WorkerExecutor; @@ -19,7 +20,7 @@ public static MovablePlayerList dummy() { return DUMMY; } - private final PlayerInformationCache playerInformationCache; + private final PlayerInformationProvider playerInformationProvider; private final SaveGame saveGame; private final boolean isSaveEnabled; @@ -27,11 +28,11 @@ public static MovablePlayerList dummy() { private volatile ConcurrentLinkedQueue players = new ConcurrentLinkedQueue<>(); public MovablePlayerList( - PlayerInformationCache playerInformationCache, + PlayerInformationProvider playerInformationProvider, SaveGame saveGame, boolean isSaveEnabled, WorldPlayerType worldPlayerType) { - this.playerInformationCache = playerInformationCache; + this.playerInformationProvider = playerInformationProvider; this.saveGame = saveGame; this.isSaveEnabled = isSaveEnabled; this.worldPlayerType = worldPlayerType; @@ -77,10 +78,7 @@ private void loadPlayers( @CalledOnlyBy(AmidstThread.WORKER) private void loadPlayer(ConcurrentLinkedQueue players, SaveGamePlayer saveGamePlayer) { - players.offer(saveGamePlayer.map( - () -> new Player(PlayerInformation.theSingleplayerPlayer(), saveGamePlayer), - playerUUID -> new Player(playerInformationCache.getByUUID(playerUUID), saveGamePlayer), - playerName -> new Player(playerInformationCache.getByName(playerName), saveGamePlayer))); + players.offer(new Player(saveGamePlayer.getPlayerInformation(playerInformationProvider), saveGamePlayer)); } public boolean canSave() { diff --git a/src/main/java/amidst/mojangapi/world/player/PlayerInformationCache.java b/src/main/java/amidst/mojangapi/world/player/PlayerInformationCache.java deleted file mode 100644 index e52aeed2a..000000000 --- a/src/main/java/amidst/mojangapi/world/player/PlayerInformationCache.java +++ /dev/null @@ -1,13 +0,0 @@ -package amidst.mojangapi.world.player; - -import amidst.documentation.NotNull; -import amidst.documentation.ThreadSafe; - -@ThreadSafe -public interface PlayerInformationCache { - @NotNull - PlayerInformation getByUUID(String uuid); - - @NotNull - PlayerInformation getByName(String name); -} From 6c2002aa3778a4d144cd1114c5e24cec406d64fe Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 19:17:34 +0200 Subject: [PATCH 30/48] moved facade class VersionListProvider --- .../amidst/mojangapi/{ => file/facade}/VersionListProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/amidst/mojangapi/{ => file/facade}/VersionListProvider.java (97%) diff --git a/src/main/java/amidst/mojangapi/VersionListProvider.java b/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java similarity index 97% rename from src/main/java/amidst/mojangapi/VersionListProvider.java rename to src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java index 4d0c2cfe1..79439a965 100644 --- a/src/main/java/amidst/mojangapi/VersionListProvider.java +++ b/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java @@ -1,4 +1,4 @@ -package amidst.mojangapi; +package amidst.mojangapi.file.facade; import java.io.IOException; From 88cf1bebe5304233c5ab0478fc9dcd21781b9825 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 19:19:42 +0200 Subject: [PATCH 31/48] removed unused method --- .../amidst/mojangapi/file/facade/MinecraftInstallation.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java index aace4d0b8..ed8ab0ce9 100644 --- a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java @@ -46,11 +46,6 @@ public MinecraftInstallation(DotMinecraftDirectory dotMinecraftDirectory) { this.dotMinecraftDirectory = dotMinecraftDirectory; } - @Deprecated - public DotMinecraftDirectory getDotMinecraftDirectory() { - return dotMinecraftDirectory; - } - public List readLauncherProfiles() throws MojangApiParsingException, IOException { return dotMinecraftDirectoryService .readLauncherProfilesFrom(dotMinecraftDirectory) From eff42d1e2eb6446f691e2512357e6c2a80f0c5cd Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 20:27:54 +0200 Subject: [PATCH 32/48] introduced new facade classes VersionList and Version --- src/main/java/amidst/mojangapi/MojangApi.java | 11 ++-- .../facade/UnresolvedLauncherProfile.java | 3 +- .../amidst/mojangapi/file/facade/Version.java | 61 +++++++++++++++++++ .../mojangapi/file/facade/VersionList.java | 54 ++++++++++++++++ .../file/facade/VersionListProvider.java | 19 +++--- .../service/DotMinecraftDirectoryService.java | 10 +-- .../file/service/DownloadService.java | 37 +++++------ .../java/amidst/devtools/DevToolRunner.java | 7 +-- .../GenerateRecognisedVersionList.java | 22 +++---- .../devtools/GenerateWorldTestData.java | 24 ++++---- ...necraftJarDownloadAvailabilityChecker.java | 16 +++-- .../devtools/MinecraftJarDownloader.java | 16 +++-- .../MinecraftVersionCompatibilityChecker.java | 26 ++++---- .../devtools/utils/VersionStateRenderer.java | 4 +- 14 files changed, 200 insertions(+), 110 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/file/facade/Version.java create mode 100644 src/main/java/amidst/mojangapi/file/facade/VersionList.java diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 662cfc1dd..9da685328 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -11,8 +11,7 @@ import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.facade.LauncherProfile; import amidst.mojangapi.file.facade.MinecraftInstallation; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.VersionListService; +import amidst.mojangapi.file.facade.VersionList; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -32,7 +31,7 @@ public class MojangApi { private final WorldBuilder worldBuilder; private final MinecraftInstallation minecraftInstallation; - private volatile VersionListJson versionList; + private volatile VersionList versionList; private volatile MinecraftInterface minecraftInterface; private volatile LauncherProfile launcherProfile; @@ -50,13 +49,13 @@ public Optional getLauncherProfile() { } @NotNull - public VersionListJson getVersionList() throws FileNotFoundException { - VersionListJson versionList = this.versionList; + public VersionList getVersionList() throws FileNotFoundException { + VersionList versionList = this.versionList; if (versionList == null) { synchronized (this) { versionList = this.versionList; if (versionList == null) { - versionList = new VersionListService().readRemoteOrLocalVersionList(); + versionList = VersionList.newRemoteOrLocalVersionList(); this.versionList = versionList; } } diff --git a/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java b/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java index e0194f772..cc5ad584b 100644 --- a/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java +++ b/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java @@ -9,7 +9,6 @@ import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.version.VersionJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.mojangapi.file.service.DotMinecraftDirectoryService; import amidst.parsing.FormatException; import amidst.parsing.json.JsonReader; @@ -30,7 +29,7 @@ public String getName() { return launcherProfileJson.getName(); } - public LauncherProfile resolve(VersionListJson versionList) throws MojangApiParsingException, IOException { + public LauncherProfile resolve(VersionList versionList) throws MojangApiParsingException, IOException { DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); ProfileDirectory profileDirectory = dotMinecraftDirectoryService .createValidProfileDirectory(launcherProfileJson, dotMinecraftDirectory); diff --git a/src/main/java/amidst/mojangapi/file/facade/Version.java b/src/main/java/amidst/mojangapi/file/facade/Version.java new file mode 100644 index 000000000..48492db06 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/Version.java @@ -0,0 +1,61 @@ +package amidst.mojangapi.file.facade; + +import java.io.File; +import java.io.IOException; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.json.ReleaseType; +import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; +import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.service.FilenameService; + +@Immutable +public class Version { + private final FilenameService filenameService = new FilenameService(); + private final DownloadService downloadService = new DownloadService(); + private final VersionListEntryJson versionListEntryJson; + + public Version(VersionListEntryJson versionListEntryJson) { + this.versionListEntryJson = versionListEntryJson; + } + + public String getId() { + return versionListEntryJson.getId(); + } + + public ReleaseType getType() { + return versionListEntryJson.getType(); + } + + public boolean hasServer() { + return downloadService.hasServer(versionListEntryJson.getId()); + } + + public boolean hasClient() { + return downloadService.hasClient(versionListEntryJson.getId()); + } + + public boolean tryDownloadServer(String prefix) { + return downloadService.tryDownloadServer(prefix, versionListEntryJson.getId()); + } + + public boolean tryDownloadClient(String prefix) { + return downloadService.tryDownloadClient(prefix, versionListEntryJson.getId()); + } + + public void downloadServer(String prefix) throws IOException { + downloadService.downloadServer(prefix, versionListEntryJson.getId()); + } + + public void downloadClient(String prefix) throws IOException { + downloadService.downloadClient(prefix, versionListEntryJson.getId()); + } + + public File getClientJarFile(File prefix) { + return filenameService.getClientJarFile(prefix, versionListEntryJson.getId()); + } + + public File getClientJsonFile(File prefix) { + return filenameService.getClientJsonFile(prefix, versionListEntryJson.getId()); + } +} diff --git a/src/main/java/amidst/mojangapi/file/facade/VersionList.java b/src/main/java/amidst/mojangapi/file/facade/VersionList.java new file mode 100644 index 000000000..8f9c14e94 --- /dev/null +++ b/src/main/java/amidst/mojangapi/file/facade/VersionList.java @@ -0,0 +1,54 @@ +package amidst.mojangapi.file.facade; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.service.VersionListService; + +@Immutable +public class VersionList { + @Deprecated + public static VersionList newRemoteOrLocalVersionList() throws FileNotFoundException { + return new VersionList( + new VersionListService() + .readRemoteOrLocalVersionList() + .getVersions() + .stream() + .map(v -> new Version(v)) + .collect(Collectors.toList())); + } + + public static VersionList newRemoteVersionList() throws MojangApiParsingException, IOException { + return new VersionList( + new VersionListService() + .readRemoteVersionList() + .getVersions() + .stream() + .map(v -> new Version(v)) + .collect(Collectors.toList())); + } + + public static VersionList newLocalVersionList() throws MojangApiParsingException, IOException { + return new VersionList( + new VersionListService() + .readLocalVersionListFromResource() + .getVersions() + .stream() + .map(v -> new Version(v)) + .collect(Collectors.toList())); + } + + private final List versions; + + public VersionList(List versions) { + this.versions = versions; + } + + public List getVersions() { + return versions; + } +} diff --git a/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java b/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java index 79439a965..80c1047a3 100644 --- a/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java +++ b/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java @@ -6,32 +6,27 @@ import amidst.documentation.CalledOnlyBy; import amidst.documentation.ThreadSafe; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.VersionListService; @ThreadSafe public class VersionListProvider { public static VersionListProvider create() throws MojangApiParsingException, IOException { - VersionListService versionListService = new VersionListService(); - return new VersionListProvider(versionListService, versionListService.readLocalVersionListFromResource()); + return new VersionListProvider(VersionList.newLocalVersionList()); } - private final VersionListService versionListService; - private final VersionListJson local; - private volatile VersionListJson remote; + private final VersionList local; + private volatile VersionList remote; - public VersionListProvider(VersionListService versionListService, VersionListJson local) { - this.versionListService = versionListService; + public VersionListProvider(VersionList local) { this.local = local; } @CalledOnlyBy(AmidstThread.WORKER) public void startDownload() throws MojangApiParsingException, IOException { - remote = versionListService.readRemoteVersionList(); + remote = VersionList.newRemoteVersionList(); } - public VersionListJson getRemoteOrElseLocal() { - VersionListJson remote = this.remote; + public VersionList getRemoteOrElseLocal() { + VersionList remote = this.remote; if (remote != null) { return remote; } else { diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index 0b4440d3a..8348d1d9e 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -13,11 +13,11 @@ import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; +import amidst.mojangapi.file.facade.Version; +import amidst.mojangapi.file.facade.VersionList; import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.parsing.FormatException; import amidst.parsing.json.JsonReader; import amidst.util.OperatingSystemDetector; @@ -123,7 +123,7 @@ private ProfileDirectory createProfileDirectory(DotMinecraftDirectory dotMinecra @NotNull public VersionDirectory createValidVersionDirectory( LauncherProfileJson launcherProfileJson, - VersionListJson versionList, + VersionList versionList, DotMinecraftDirectory dotMinecraftDirectory) throws FileNotFoundException { String lastVersionId = launcherProfileJson.getLastVersionId(); if (lastVersionId != null) { @@ -150,9 +150,9 @@ public VersionDirectory createValidVersionDirectory( private VersionDirectory tryFindFirstValidVersionDirectory( List allowedReleaseTypes, - VersionListJson versionList, + VersionList versionList, DotMinecraftDirectory dotMinecraftDirectory) { - for (VersionListEntryJson version : versionList.getVersions()) { + for (Version version : versionList.getVersions()) { if (allowedReleaseTypes.contains(version.getType())) { VersionDirectory versionDirectory = createVersionDirectory(dotMinecraftDirectory, version.getId()); if (versionDirectory.isValid()) { diff --git a/src/main/java/amidst/mojangapi/file/service/DownloadService.java b/src/main/java/amidst/mojangapi/file/service/DownloadService.java index 25e09d507..08b1cc1a5 100644 --- a/src/main/java/amidst/mojangapi/file/service/DownloadService.java +++ b/src/main/java/amidst/mojangapi/file/service/DownloadService.java @@ -12,18 +12,17 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.URIUtils; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; @Immutable public class DownloadService { private final FilenameService filenameService = new FilenameService(); - public boolean hasServer(VersionListEntryJson version) { - return exists(filenameService.getRemoteServerJar(version.getId())); + public boolean hasServer(String versionId) { + return exists(filenameService.getRemoteServerJar(versionId)); } - public boolean hasClient(VersionListEntryJson version) { - return exists(filenameService.getRemoteClientJar(version.getId())); + public boolean hasClient(String versionId) { + return exists(filenameService.getRemoteClientJar(versionId)); } private static boolean exists(String location) { @@ -36,39 +35,33 @@ private static boolean exists(String location) { } } - public boolean tryDownloadServer(String prefix, VersionListEntryJson version) { + public boolean tryDownloadServer(String prefix, String versionId) { try { - downloadServer(prefix, version); + downloadServer(prefix, versionId); return true; } catch (IOException e) { - AmidstLogger.warn(e, "unable to download server: " + version.getId()); + AmidstLogger.warn(e, "unable to download server: " + versionId); } return false; } - public boolean tryDownloadClient(String prefix, VersionListEntryJson version) { + public boolean tryDownloadClient(String prefix, String versionId) { try { - downloadClient(prefix, version); + downloadClient(prefix, versionId); return true; } catch (IOException e) { - AmidstLogger.warn(e, "unable to download client: " + version.getId()); + AmidstLogger.warn(e, "unable to download client: " + versionId); } return false; } - public void downloadServer(String prefix, VersionListEntryJson version) throws IOException { - download( - filenameService.getRemoteServerJar(version.getId()), - filenameService.getServerJar(prefix, version.getId())); + public void downloadServer(String prefix, String versionId) throws IOException { + download(filenameService.getRemoteServerJar(versionId), filenameService.getServerJar(prefix, versionId)); } - public void downloadClient(String prefix, VersionListEntryJson version) throws IOException { - download( - filenameService.getRemoteClientJar(version.getId()), - filenameService.getClientJar(prefix, version.getId())); - download( - filenameService.getRemoteClientJson(version.getId()), - filenameService.getClientJson(prefix, version.getId())); + public void downloadClient(String prefix, String versionId) throws IOException { + download(filenameService.getRemoteClientJar(versionId), filenameService.getClientJar(prefix, versionId)); + download(filenameService.getRemoteClientJson(versionId), filenameService.getClientJson(prefix, versionId)); } private void download(String from, String to) throws IOException { diff --git a/src/test/java/amidst/devtools/DevToolRunner.java b/src/test/java/amidst/devtools/DevToolRunner.java index 23ea6a40f..a984f9eb2 100644 --- a/src/test/java/amidst/devtools/DevToolRunner.java +++ b/src/test/java/amidst/devtools/DevToolRunner.java @@ -10,8 +10,7 @@ import amidst.ResourceLoader; import amidst.devtools.settings.DevToolSettings; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.VersionListService; +import amidst.mojangapi.file.facade.VersionList; import amidst.mojangapi.world.biome.Biome; /** @@ -62,8 +61,8 @@ public void generateBiomeColorImages() throws IOException { new GenerateBiomeColorImages(Biome.allBiomes(), new File(biomeColorImagesDirectory())).run(); } - private VersionListJson versionList() throws IOException, MojangApiParsingException { - return new VersionListService().readRemoteVersionList(); + private VersionList versionList() throws IOException, MojangApiParsingException { + return VersionList.newRemoteVersionList(); } private String librariesDirectory() { diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 58ea04c4d..f04b0ea81 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -11,20 +11,19 @@ import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.facade.MinecraftInstallation; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.facade.Version; +import amidst.mojangapi.file.facade.VersionList; import amidst.mojangapi.minecraftinterface.RecognisedVersion; public class GenerateRecognisedVersionList { private final String prefix; - private final VersionListJson versionList; + private final VersionList versionList; private final MinecraftInstallation minecraftInstallation; private final List versionsWithError = new LinkedList<>(); private final List downloadFailed = new LinkedList<>(); private final RecognisedVersionEnumBuilder builder = RecognisedVersionEnumBuilder.createPopulated(); - public GenerateRecognisedVersionList(String prefix, String libraries, VersionListJson versionList) + public GenerateRecognisedVersionList(String prefix, String libraries, VersionList versionList) throws DotMinecraftDirectoryNotFoundException { this.prefix = prefix; this.versionList = versionList; @@ -38,23 +37,22 @@ public void run() { } private void populate() { - for (VersionListEntryJson version : versionList.getVersions()) { + for (Version version : versionList.getVersions()) { process(version); } builder.calculateMaxLength(); } - private void process(VersionListEntryJson version) { - String versionId = version.getId(); - if (new DownloadService().tryDownloadClient(prefix, version)) { + private void process(Version version) { + if (version.tryDownloadClient(prefix)) { try { - process(versionId); + process(version.getId()); } catch (ClassNotFoundException | NoClassDefFoundError | MojangApiParsingException | IOException e) { e.printStackTrace(); - versionsWithError.add(versionId); + versionsWithError.add(version.getId()); } } else { - downloadFailed.add(versionId); + downloadFailed.add(version.getId()); } } diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 54313d7f5..fe81785f2 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -10,9 +10,8 @@ import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.facade.LauncherProfile; import amidst.mojangapi.file.facade.MinecraftInstallation; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.facade.Version; +import amidst.mojangapi.file.facade.VersionList; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; @@ -22,12 +21,12 @@ public class GenerateWorldTestData { private final String prefix; - private final VersionListJson versionList; + private final VersionList versionList; private final MinecraftInstallation minecraftInstallation; private final List failed = new LinkedList<>(); private final List successful = new LinkedList<>(); - public GenerateWorldTestData(String prefix, String libraries, VersionListJson versionList) + public GenerateWorldTestData(String prefix, String libraries, VersionList versionList) throws DotMinecraftDirectoryNotFoundException { this.prefix = prefix; this.versionList = versionList; @@ -36,7 +35,7 @@ public GenerateWorldTestData(String prefix, String libraries, VersionListJson ve } public void run() { - for (VersionListEntryJson version : versionList.getVersions()) { + for (Version version : versionList.getVersions()) { for (TestWorldDeclaration declaration : TestWorldDeclaration.values()) { if (declaration.getRecognisedVersion().getName().equals(version.getId())) { generate(declaration, version); @@ -47,24 +46,23 @@ public void run() { print("============== Failed ==============", failed); } - private void generate(TestWorldDeclaration declaration, VersionListEntryJson version) { - String versionId = version.getId(); - if (new DownloadService().tryDownloadClient(prefix, version)) { + private void generate(TestWorldDeclaration declaration, Version version) { + if (version.tryDownloadClient(prefix)) { try { ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); - LauncherProfile launcherProfile = minecraftInstallation.newLauncherProfile(versionId); + LauncherProfile launcherProfile = minecraftInstallation.newLauncherProfile(version.getId()); TestWorldCache.createAndPut(declaration, LocalMinecraftInterface.create(translator, launcherProfile)); - successful.add(versionId); + successful.add(version.getId()); } catch ( LocalMinecraftInterfaceCreationException | MinecraftInterfaceException | IOException | MojangApiParsingException e) { e.printStackTrace(); - failed.add(versionId); + failed.add(version.getId()); } } else { - failed.add(versionId); + failed.add(version.getId()); } } diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java index 3ea45734e..0d59807a9 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java @@ -1,23 +1,21 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.facade.Version; +import amidst.mojangapi.file.facade.VersionList; public class MinecraftJarDownloadAvailabilityChecker { private VersionStateRenderer renderer = new VersionStateRenderer(); - private VersionListJson versionList; + private VersionList versionList; - public MinecraftJarDownloadAvailabilityChecker(VersionListJson versionList) { + public MinecraftJarDownloadAvailabilityChecker(VersionList versionList) { this.versionList = versionList; } public void run() { - DownloadService downloadService = new DownloadService(); - for (VersionListEntryJson version : versionList.getVersions()) { - boolean hasServer = downloadService.hasServer(version); - boolean hasClient = downloadService.hasClient(version); + for (Version version : versionList.getVersions()) { + boolean hasServer = version.hasServer(); + boolean hasClient = version.hasClient(); System.out.println(renderer.render(version, hasServer, hasClient)); } } diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloader.java b/src/test/java/amidst/devtools/MinecraftJarDownloader.java index 5c75155ea..d30e85d39 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloader.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloader.java @@ -1,25 +1,23 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.DownloadService; +import amidst.mojangapi.file.facade.Version; +import amidst.mojangapi.file.facade.VersionList; public class MinecraftJarDownloader { private VersionStateRenderer renderer = new VersionStateRenderer(); private String prefix; - private VersionListJson versionList; + private VersionList versionList; - public MinecraftJarDownloader(String prefix, VersionListJson versionList) { + public MinecraftJarDownloader(String prefix, VersionList versionList) { this.prefix = prefix; this.versionList = versionList; } public void run() { - DownloadService downloadService = new DownloadService(); - for (VersionListEntryJson version : versionList.getVersions()) { - boolean hasServer = downloadService.tryDownloadServer(prefix, version); - boolean hasClient = downloadService.tryDownloadClient(prefix, version); + for (Version version : versionList.getVersions()) { + boolean hasServer = version.tryDownloadServer(prefix); + boolean hasClient = version.tryDownloadClient(prefix); System.out.println(renderer.render(version, hasServer, hasClient)); } } diff --git a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java index d76066ac5..40de2af73 100644 --- a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java @@ -11,10 +11,8 @@ import amidst.clazz.real.JarFileParsingException; import amidst.clazz.symbolic.declaration.SymbolicClassDeclaration; import amidst.clazz.translator.ClassTranslator; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; -import amidst.mojangapi.file.json.versionlist.VersionListJson; -import amidst.mojangapi.file.service.DownloadService; -import amidst.mojangapi.file.service.FilenameService; +import amidst.mojangapi.file.facade.Version; +import amidst.mojangapi.file.facade.VersionList; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; /** @@ -25,17 +23,17 @@ */ public class MinecraftVersionCompatibilityChecker { private String prefix; - private VersionListJson versionList; + private VersionList versionList; - public MinecraftVersionCompatibilityChecker(String prefix, VersionListJson versionList) { + public MinecraftVersionCompatibilityChecker(String prefix, VersionList versionList) { this.prefix = prefix; this.versionList = versionList; } public void run() { - List supported = new ArrayList<>(); - List unsupported = new ArrayList<>(); - for (VersionListEntryJson version : versionList.getVersions()) { + List supported = new ArrayList<>(); + List unsupported = new ArrayList<>(); + for (Version version : versionList.getVersions()) { if (checkOne(version)) { supported.add(version); } else { @@ -46,10 +44,10 @@ public void run() { displayVersionList(unsupported, "================ UNSUPPORTED VERSIONS ================"); } - private boolean checkOne(VersionListEntryJson version) { - if (new DownloadService().tryDownloadClient(prefix, version)) { + private boolean checkOne(Version version) { + if (version.tryDownloadClient(prefix)) { try { - File jarFile = new File(new FilenameService().getClientJar(prefix, version.getId())); + File jarFile = version.getClientJarFile(new File(prefix)); ClassTranslator translator = DefaultClassTranslator.INSTANCE.get(); return isSupported(Classes.countMatches(jarFile, translator)); } catch (FileNotFoundException | JarFileParsingException e) { @@ -70,10 +68,10 @@ private boolean isSupported(Map matchesMap) { return true; } - private void displayVersionList(List supported, String message) { + private void displayVersionList(List versions, String message) { System.out.println(); System.out.println(message); - for (VersionListEntryJson version : supported) { + for (Version version : versions) { System.out.println(version.getId()); } } diff --git a/src/test/java/amidst/devtools/utils/VersionStateRenderer.java b/src/test/java/amidst/devtools/utils/VersionStateRenderer.java index 81ed359a9..5a46ec7d5 100644 --- a/src/test/java/amidst/devtools/utils/VersionStateRenderer.java +++ b/src/test/java/amidst/devtools/utils/VersionStateRenderer.java @@ -1,9 +1,9 @@ package amidst.devtools.utils; -import amidst.mojangapi.file.json.versionlist.VersionListEntryJson; +import amidst.mojangapi.file.facade.Version; public class VersionStateRenderer { - public String render(VersionListEntryJson version, boolean hasServer, boolean hasClient) { + public String render(Version version, boolean hasServer, boolean hasClient) { return toBox(hasServer, 'S') + " " + toBox(hasClient, 'C') + " " + version.getType().getTypeChar() + " " + version.getId(); } From 91ec0588ce6cd9824c4d999a14dbbb93571bfbaa Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 20:56:03 +0200 Subject: [PATCH 33/48] moved facade classes --- src/main/java/amidst/PerApplicationInjector.java | 4 ++-- src/main/java/amidst/gui/main/MainWindowDialogs.java | 2 +- .../amidst/gui/profileselect/LocalProfileComponent.java | 4 ++-- .../amidst/gui/profileselect/ProfileSelectWindow.java | 2 +- src/main/java/amidst/mojangapi/MojangApi.java | 6 +++--- src/main/java/amidst/mojangapi/MojangApiBuilder.java | 2 +- .../{facade => }/ImmutablePlayerInformationProvider.java | 2 +- .../mojangapi/file/{facade => }/LauncherProfile.java | 2 +- .../file/{facade => }/MinecraftInstallation.java | 4 +--- .../file/{facade => }/PlayerInformationCache.java | 2 +- .../file/{facade => }/PlayerInformationProvider.java | 2 +- .../java/amidst/mojangapi/file/{facade => }/SaveGame.java | 2 +- .../mojangapi/file/{facade => }/SaveGamePlayer.java | 2 +- .../file/{facade => }/UnresolvedLauncherProfile.java | 3 +-- .../java/amidst/mojangapi/file/{facade => }/Version.java | 2 +- .../amidst/mojangapi/file/{facade => }/VersionList.java | 3 +-- .../mojangapi/file/{facade => }/VersionListProvider.java | 3 +-- .../file/service/DotMinecraftDirectoryService.java | 4 ++-- .../minecraftinterface/local/LocalMinecraftInterface.java | 2 +- .../local/LocalMinecraftInterfaceBuilder.java | 2 +- src/main/java/amidst/mojangapi/world/WorldBuilder.java | 6 +++--- .../amidst/mojangapi/world/player/MovablePlayerList.java | 6 +++--- src/main/java/amidst/mojangapi/world/player/Player.java | 2 +- .../amidst/mojangapi/world/player/WorldPlayerType.java | 4 ++-- src/test/java/amidst/devtools/DevToolRunner.java | 2 +- .../amidst/devtools/GenerateRecognisedVersionList.java | 6 +++--- src/test/java/amidst/devtools/GenerateWorldTestData.java | 8 ++++---- .../devtools/MinecraftJarDownloadAvailabilityChecker.java | 4 ++-- src/test/java/amidst/devtools/MinecraftJarDownloader.java | 4 ++-- .../devtools/MinecraftVersionCompatibilityChecker.java | 4 ++-- .../java/amidst/devtools/utils/VersionStateRenderer.java | 2 +- 31 files changed, 49 insertions(+), 54 deletions(-) rename src/main/java/amidst/mojangapi/file/{facade => }/ImmutablePlayerInformationProvider.java (94%) rename src/main/java/amidst/mojangapi/file/{facade => }/LauncherProfile.java (97%) rename src/main/java/amidst/mojangapi/file/{facade => }/MinecraftInstallation.java (95%) rename src/main/java/amidst/mojangapi/file/{facade => }/PlayerInformationCache.java (98%) rename src/main/java/amidst/mojangapi/file/{facade => }/PlayerInformationProvider.java (89%) rename src/main/java/amidst/mojangapi/file/{facade => }/SaveGame.java (98%) rename src/main/java/amidst/mojangapi/file/{facade => }/SaveGamePlayer.java (97%) rename src/main/java/amidst/mojangapi/file/{facade => }/UnresolvedLauncherProfile.java (95%) rename src/main/java/amidst/mojangapi/file/{facade => }/Version.java (97%) rename src/main/java/amidst/mojangapi/file/{facade => }/VersionList.java (93%) rename src/main/java/amidst/mojangapi/file/{facade => }/VersionListProvider.java (89%) diff --git a/src/main/java/amidst/PerApplicationInjector.java b/src/main/java/amidst/PerApplicationInjector.java index 306a28c74..8643a730e 100644 --- a/src/main/java/amidst/PerApplicationInjector.java +++ b/src/main/java/amidst/PerApplicationInjector.java @@ -19,8 +19,8 @@ import amidst.mojangapi.MojangApi; import amidst.mojangapi.MojangApiBuilder; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.facade.PlayerInformationCache; -import amidst.mojangapi.file.facade.PlayerInformationProvider; +import amidst.mojangapi.file.PlayerInformationCache; +import amidst.mojangapi.file.PlayerInformationProvider; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.SeedHistoryLogger; import amidst.mojangapi.world.World; diff --git a/src/main/java/amidst/gui/main/MainWindowDialogs.java b/src/main/java/amidst/gui/main/MainWindowDialogs.java index c5063f6ae..ee5b23c30 100644 --- a/src/main/java/amidst/gui/main/MainWindowDialogs.java +++ b/src/main/java/amidst/gui/main/MainWindowDialogs.java @@ -13,7 +13,7 @@ import amidst.documentation.NotThreadSafe; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.facade.LauncherProfile; +import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.world.WorldSeed; import amidst.mojangapi.world.WorldType; import amidst.mojangapi.world.export.WorldExporterConfiguration; diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index d6b2f3e8c..325ba5b08 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -11,9 +11,9 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.LauncherProfile; -import amidst.mojangapi.file.facade.UnresolvedLauncherProfile; +import amidst.mojangapi.file.UnresolvedLauncherProfile; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.threading.WorkerExecutor; diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index e645e9fd6..1a50ba61f 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -22,7 +22,7 @@ import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.UnresolvedLauncherProfile; +import amidst.mojangapi.file.UnresolvedLauncherProfile; import amidst.threading.WorkerExecutor; import net.miginfocom.swing.MigLayout; diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 9da685328..567beead2 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -8,10 +8,10 @@ import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.LauncherProfile; -import amidst.mojangapi.file.facade.MinecraftInstallation; -import amidst.mojangapi.file.facade.VersionList; +import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java index cdf964b40..ed8757f99 100644 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ b/src/main/java/amidst/mojangapi/MojangApiBuilder.java @@ -7,8 +7,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.MinecraftInstallation; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.WorldBuilder; diff --git a/src/main/java/amidst/mojangapi/file/facade/ImmutablePlayerInformationProvider.java b/src/main/java/amidst/mojangapi/file/ImmutablePlayerInformationProvider.java similarity index 94% rename from src/main/java/amidst/mojangapi/file/facade/ImmutablePlayerInformationProvider.java rename to src/main/java/amidst/mojangapi/file/ImmutablePlayerInformationProvider.java index 77a847a14..efd17833e 100644 --- a/src/main/java/amidst/mojangapi/file/facade/ImmutablePlayerInformationProvider.java +++ b/src/main/java/amidst/mojangapi/file/ImmutablePlayerInformationProvider.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import amidst.documentation.Immutable; import amidst.documentation.NotNull; diff --git a/src/main/java/amidst/mojangapi/file/facade/LauncherProfile.java b/src/main/java/amidst/mojangapi/file/LauncherProfile.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/facade/LauncherProfile.java rename to src/main/java/amidst/mojangapi/file/LauncherProfile.java index 5596351ac..fe7c85199 100644 --- a/src/main/java/amidst/mojangapi/file/facade/LauncherProfile.java +++ b/src/main/java/amidst/mojangapi/file/LauncherProfile.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.io.File; import java.net.MalformedURLException; diff --git a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java similarity index 95% rename from src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java rename to src/main/java/amidst/mojangapi/file/MinecraftInstallation.java index ed8ab0ce9..77beb9d9f 100644 --- a/src/main/java/amidst/mojangapi/file/facade/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.io.File; import java.io.IOException; @@ -7,8 +7,6 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.directory.VersionDirectory; diff --git a/src/main/java/amidst/mojangapi/file/facade/PlayerInformationCache.java b/src/main/java/amidst/mojangapi/file/PlayerInformationCache.java similarity index 98% rename from src/main/java/amidst/mojangapi/file/facade/PlayerInformationCache.java rename to src/main/java/amidst/mojangapi/file/PlayerInformationCache.java index d90a6ae04..0a0706df8 100644 --- a/src/main/java/amidst/mojangapi/file/facade/PlayerInformationCache.java +++ b/src/main/java/amidst/mojangapi/file/PlayerInformationCache.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/src/main/java/amidst/mojangapi/file/facade/PlayerInformationProvider.java b/src/main/java/amidst/mojangapi/file/PlayerInformationProvider.java similarity index 89% rename from src/main/java/amidst/mojangapi/file/facade/PlayerInformationProvider.java rename to src/main/java/amidst/mojangapi/file/PlayerInformationProvider.java index 63c649747..797bf1451 100644 --- a/src/main/java/amidst/mojangapi/file/facade/PlayerInformationProvider.java +++ b/src/main/java/amidst/mojangapi/file/PlayerInformationProvider.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; diff --git a/src/main/java/amidst/mojangapi/file/facade/SaveGame.java b/src/main/java/amidst/mojangapi/file/SaveGame.java similarity index 98% rename from src/main/java/amidst/mojangapi/file/facade/SaveGame.java rename to src/main/java/amidst/mojangapi/file/SaveGame.java index c014eda72..919338303 100644 --- a/src/main/java/amidst/mojangapi/file/facade/SaveGame.java +++ b/src/main/java/amidst/mojangapi/file/SaveGame.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.util.Collections; import java.util.LinkedList; diff --git a/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java b/src/main/java/amidst/mojangapi/file/SaveGamePlayer.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java rename to src/main/java/amidst/mojangapi/file/SaveGamePlayer.java index 59d3f70fa..f1950d1f4 100644 --- a/src/main/java/amidst/mojangapi/file/facade/SaveGamePlayer.java +++ b/src/main/java/amidst/mojangapi/file/SaveGamePlayer.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import amidst.documentation.Immutable; import amidst.mojangapi.file.directory.SaveDirectory; diff --git a/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java b/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java similarity index 95% rename from src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java rename to src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java index cc5ad584b..588846660 100644 --- a/src/main/java/amidst/mojangapi/file/facade/UnresolvedLauncherProfile.java +++ b/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java @@ -1,9 +1,8 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.io.IOException; import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; diff --git a/src/main/java/amidst/mojangapi/file/facade/Version.java b/src/main/java/amidst/mojangapi/file/Version.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/facade/Version.java rename to src/main/java/amidst/mojangapi/file/Version.java index 48492db06..87c26af41 100644 --- a/src/main/java/amidst/mojangapi/file/facade/Version.java +++ b/src/main/java/amidst/mojangapi/file/Version.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.io.File; import java.io.IOException; diff --git a/src/main/java/amidst/mojangapi/file/facade/VersionList.java b/src/main/java/amidst/mojangapi/file/VersionList.java similarity index 93% rename from src/main/java/amidst/mojangapi/file/facade/VersionList.java rename to src/main/java/amidst/mojangapi/file/VersionList.java index 8f9c14e94..3e8d02fb3 100644 --- a/src/main/java/amidst/mojangapi/file/facade/VersionList.java +++ b/src/main/java/amidst/mojangapi/file/VersionList.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.io.FileNotFoundException; import java.io.IOException; @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.service.VersionListService; @Immutable diff --git a/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java b/src/main/java/amidst/mojangapi/file/VersionListProvider.java similarity index 89% rename from src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java rename to src/main/java/amidst/mojangapi/file/VersionListProvider.java index 80c1047a3..2a77eea40 100644 --- a/src/main/java/amidst/mojangapi/file/facade/VersionListProvider.java +++ b/src/main/java/amidst/mojangapi/file/VersionListProvider.java @@ -1,11 +1,10 @@ -package amidst.mojangapi.file.facade; +package amidst.mojangapi.file; import java.io.IOException; import amidst.documentation.AmidstThread; import amidst.documentation.CalledOnlyBy; import amidst.documentation.ThreadSafe; -import amidst.mojangapi.file.MojangApiParsingException; @ThreadSafe public class VersionListProvider { diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index 8348d1d9e..3631d9f80 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -10,11 +10,11 @@ import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.MojangApiParsingException; +import amidst.mojangapi.file.Version; +import amidst.mojangapi.file.VersionList; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; -import amidst.mojangapi.file.facade.Version; -import amidst.mojangapi.file.facade.VersionList; import amidst.mojangapi.file.json.ReleaseType; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfileJson; import amidst.mojangapi.file.json.launcherprofiles.LauncherProfilesJson; diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java index b7f4eb22b..92c8f43a0 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterface.java @@ -7,7 +7,7 @@ import amidst.clazz.translator.ClassTranslator; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.facade.LauncherProfile; +import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; diff --git a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java index 41c65e9bf..9462d292f 100644 --- a/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java +++ b/src/main/java/amidst/mojangapi/minecraftinterface/local/LocalMinecraftInterfaceBuilder.java @@ -12,7 +12,7 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.facade.LauncherProfile; +import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @Immutable diff --git a/src/main/java/amidst/mojangapi/world/WorldBuilder.java b/src/main/java/amidst/mojangapi/world/WorldBuilder.java index ae6ab481a..b2e058bab 100644 --- a/src/main/java/amidst/mojangapi/world/WorldBuilder.java +++ b/src/main/java/amidst/mojangapi/world/WorldBuilder.java @@ -3,10 +3,10 @@ import java.io.IOException; import amidst.documentation.Immutable; +import amidst.mojangapi.file.ImmutablePlayerInformationProvider; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.ImmutablePlayerInformationProvider; -import amidst.mojangapi.file.facade.PlayerInformationProvider; -import amidst.mojangapi.file.facade.SaveGame; +import amidst.mojangapi.file.PlayerInformationProvider; +import amidst.mojangapi.file.SaveGame; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; diff --git a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java index dea1ada5e..e0897944f 100644 --- a/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java +++ b/src/main/java/amidst/mojangapi/world/player/MovablePlayerList.java @@ -7,9 +7,9 @@ import amidst.documentation.CalledOnlyBy; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.facade.PlayerInformationProvider; -import amidst.mojangapi.file.facade.SaveGame; -import amidst.mojangapi.file.facade.SaveGamePlayer; +import amidst.mojangapi.file.PlayerInformationProvider; +import amidst.mojangapi.file.SaveGame; +import amidst.mojangapi.file.SaveGamePlayer; import amidst.threading.WorkerExecutor; @ThreadSafe diff --git a/src/main/java/amidst/mojangapi/world/player/Player.java b/src/main/java/amidst/mojangapi/world/player/Player.java index 4c40fc8c0..da97a305b 100644 --- a/src/main/java/amidst/mojangapi/world/player/Player.java +++ b/src/main/java/amidst/mojangapi/world/player/Player.java @@ -2,7 +2,7 @@ import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.facade.SaveGamePlayer; +import amidst.mojangapi.file.SaveGamePlayer; import amidst.mojangapi.world.Dimension; import amidst.mojangapi.world.coordinates.CoordinatesInWorld; import amidst.mojangapi.world.icon.WorldIconImage; diff --git a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java index 557b0a8ac..21b50dad4 100644 --- a/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java +++ b/src/main/java/amidst/mojangapi/world/player/WorldPlayerType.java @@ -6,8 +6,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.facade.SaveGame; -import amidst.mojangapi.file.facade.SaveGamePlayer; +import amidst.mojangapi.file.SaveGame; +import amidst.mojangapi.file.SaveGamePlayer; @Immutable public enum WorldPlayerType { diff --git a/src/test/java/amidst/devtools/DevToolRunner.java b/src/test/java/amidst/devtools/DevToolRunner.java index a984f9eb2..9a61b8b92 100644 --- a/src/test/java/amidst/devtools/DevToolRunner.java +++ b/src/test/java/amidst/devtools/DevToolRunner.java @@ -10,7 +10,7 @@ import amidst.ResourceLoader; import amidst.devtools.settings.DevToolSettings; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.VersionList; +import amidst.mojangapi.file.VersionList; import amidst.mojangapi.world.biome.Biome; /** diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index f04b0ea81..2d414c43c 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -9,10 +9,10 @@ import amidst.devtools.utils.RecognisedVersionEnumBuilder; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.MinecraftInstallation; -import amidst.mojangapi.file.facade.Version; -import amidst.mojangapi.file.facade.VersionList; +import amidst.mojangapi.file.Version; +import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.RecognisedVersion; public class GenerateRecognisedVersionList { diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index fe81785f2..057b84443 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -7,11 +7,11 @@ import amidst.clazz.translator.ClassTranslator; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.MojangApiParsingException; -import amidst.mojangapi.file.facade.LauncherProfile; -import amidst.mojangapi.file.facade.MinecraftInstallation; -import amidst.mojangapi.file.facade.Version; -import amidst.mojangapi.file.facade.VersionList; +import amidst.mojangapi.file.Version; +import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java index 0d59807a9..6595dde92 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloadAvailabilityChecker.java @@ -1,8 +1,8 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.facade.Version; -import amidst.mojangapi.file.facade.VersionList; +import amidst.mojangapi.file.Version; +import amidst.mojangapi.file.VersionList; public class MinecraftJarDownloadAvailabilityChecker { private VersionStateRenderer renderer = new VersionStateRenderer(); diff --git a/src/test/java/amidst/devtools/MinecraftJarDownloader.java b/src/test/java/amidst/devtools/MinecraftJarDownloader.java index d30e85d39..c69f3285b 100644 --- a/src/test/java/amidst/devtools/MinecraftJarDownloader.java +++ b/src/test/java/amidst/devtools/MinecraftJarDownloader.java @@ -1,8 +1,8 @@ package amidst.devtools; import amidst.devtools.utils.VersionStateRenderer; -import amidst.mojangapi.file.facade.Version; -import amidst.mojangapi.file.facade.VersionList; +import amidst.mojangapi.file.Version; +import amidst.mojangapi.file.VersionList; public class MinecraftJarDownloader { private VersionStateRenderer renderer = new VersionStateRenderer(); diff --git a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java index 40de2af73..0b0b62496 100644 --- a/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java +++ b/src/test/java/amidst/devtools/MinecraftVersionCompatibilityChecker.java @@ -11,8 +11,8 @@ import amidst.clazz.real.JarFileParsingException; import amidst.clazz.symbolic.declaration.SymbolicClassDeclaration; import amidst.clazz.translator.ClassTranslator; -import amidst.mojangapi.file.facade.Version; -import amidst.mojangapi.file.facade.VersionList; +import amidst.mojangapi.file.Version; +import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; /** diff --git a/src/test/java/amidst/devtools/utils/VersionStateRenderer.java b/src/test/java/amidst/devtools/utils/VersionStateRenderer.java index 5a46ec7d5..b7e95864b 100644 --- a/src/test/java/amidst/devtools/utils/VersionStateRenderer.java +++ b/src/test/java/amidst/devtools/utils/VersionStateRenderer.java @@ -1,6 +1,6 @@ package amidst.devtools.utils; -import amidst.mojangapi.file.facade.Version; +import amidst.mojangapi.file.Version; public class VersionStateRenderer { public String render(Version version, boolean hasServer, boolean hasClient) { From afffcfe7a647207c006fd313713577f2b265a621 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 20:59:41 +0200 Subject: [PATCH 34/48] moved class --- .../java/amidst/mojangapi/file/service/DownloadService.java | 2 +- src/main/java/amidst/{mojangapi/file => parsing}/URIUtils.java | 2 +- src/main/java/amidst/parsing/json/JsonReader.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/amidst/{mojangapi/file => parsing}/URIUtils.java (97%) diff --git a/src/main/java/amidst/mojangapi/file/service/DownloadService.java b/src/main/java/amidst/mojangapi/file/service/DownloadService.java index 08b1cc1a5..ed49ca896 100644 --- a/src/main/java/amidst/mojangapi/file/service/DownloadService.java +++ b/src/main/java/amidst/mojangapi/file/service/DownloadService.java @@ -11,7 +11,7 @@ import amidst.documentation.Immutable; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.URIUtils; +import amidst.parsing.URIUtils; @Immutable public class DownloadService { diff --git a/src/main/java/amidst/mojangapi/file/URIUtils.java b/src/main/java/amidst/parsing/URIUtils.java similarity index 97% rename from src/main/java/amidst/mojangapi/file/URIUtils.java rename to src/main/java/amidst/parsing/URIUtils.java index cfc316a8c..6c2d274f3 100644 --- a/src/main/java/amidst/mojangapi/file/URIUtils.java +++ b/src/main/java/amidst/parsing/URIUtils.java @@ -1,4 +1,4 @@ -package amidst.mojangapi.file; +package amidst.parsing; import java.io.BufferedInputStream; import java.io.BufferedReader; diff --git a/src/main/java/amidst/parsing/json/JsonReader.java b/src/main/java/amidst/parsing/json/JsonReader.java index ff321931c..005b3e04a 100644 --- a/src/main/java/amidst/parsing/json/JsonReader.java +++ b/src/main/java/amidst/parsing/json/JsonReader.java @@ -11,8 +11,8 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.mojangapi.file.URIUtils; import amidst.parsing.FormatException; +import amidst.parsing.URIUtils; @Immutable public enum JsonReader { From 13e81f321456993aedd308feda29df8d5b012d05 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 21:18:52 +0200 Subject: [PATCH 35/48] removed MojangApiParsingException --- .../java/amidst/gui/main/WorldSwitcher.java | 4 +-- .../profileselect/LocalProfileComponent.java | 4 +-- .../profileselect/ProfileSelectWindow.java | 4 +-- src/main/java/amidst/mojangapi/MojangApi.java | 9 +++--- .../amidst/mojangapi/MojangApiBuilder.java | 4 +-- .../mojangapi/file/MinecraftInstallation.java | 32 ++++++++----------- .../file/MojangApiParsingException.java | 16 ---------- .../file/UnresolvedLauncherProfile.java | 20 +++++------- .../amidst/mojangapi/file/VersionList.java | 5 +-- .../mojangapi/file/VersionListProvider.java | 5 +-- .../mojangapi/file/nbt/LevelDatNbt.java | 11 ++++--- .../file/nbt/player/PlayerLocationLoader.java | 3 ++ .../file/nbt/player/PlayerLocationSaver.java | 3 ++ .../service/DotMinecraftDirectoryService.java | 9 ++---- .../service/PlayerInformationService.java | 11 +++---- .../file/service/SaveDirectoryService.java | 7 ++-- .../file/service/VersionListService.java | 21 ++++-------- .../amidst/mojangapi/world/WorldBuilder.java | 4 +-- .../java/amidst/devtools/DevToolRunner.java | 16 +++++----- .../GenerateRecognisedVersionList.java | 6 ++-- .../devtools/GenerateWorldTestData.java | 6 ++-- 21 files changed, 83 insertions(+), 117 deletions(-) delete mode 100644 src/main/java/amidst/mojangapi/file/MojangApiParsingException.java diff --git a/src/main/java/amidst/gui/main/WorldSwitcher.java b/src/main/java/amidst/gui/main/WorldSwitcher.java index 570c93314..57ee57440 100644 --- a/src/main/java/amidst/gui/main/WorldSwitcher.java +++ b/src/main/java/amidst/gui/main/WorldSwitcher.java @@ -17,13 +17,13 @@ import amidst.gui.main.viewer.ViewerFacade; import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.world.World; import amidst.mojangapi.world.WorldSeed; import amidst.mojangapi.world.WorldType; import amidst.mojangapi.world.player.MovablePlayerList; import amidst.mojangapi.world.player.WorldPlayerType; +import amidst.parsing.FormatException; import amidst.threading.ThreadMaster; @NotThreadSafe @@ -71,7 +71,7 @@ public void displayWorld(WorldSeed worldSeed, WorldType worldType) { public void displayWorld(File file) { try { setWorld(mojangApi.createWorldFromSaveGame(file)); - } catch (IllegalStateException | MinecraftInterfaceException | IOException | MojangApiParsingException e) { + } catch (IllegalStateException | MinecraftInterfaceException | IOException | FormatException e) { AmidstLogger.warn(e); dialogs.displayError(e); } diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index 325ba5b08..274bc95e7 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -12,9 +12,9 @@ import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.LauncherProfile; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.UnresolvedLauncherProfile; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; +import amidst.parsing.FormatException; import amidst.threading.WorkerExecutor; @NotThreadSafe @@ -56,7 +56,7 @@ private boolean tryFind() { try { resolvedProfile = unresolvedProfile.resolve(mojangApi.getVersionList()); return true; - } catch (IOException | MojangApiParsingException e) { + } catch (FormatException | IOException e) { AmidstLogger.warn(e); return false; } diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index 1a50ba61f..f9a81cacf 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -21,8 +21,8 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.UnresolvedLauncherProfile; +import amidst.parsing.FormatException; import amidst.threading.WorkerExecutor; import net.miginfocom.swing.MigLayout; @@ -112,7 +112,7 @@ private void scanAndLoadProfilesLater() { } @CalledOnlyBy(AmidstThread.WORKER) - private List scanAndLoadProfiles() throws MojangApiParsingException, IOException { + private List scanAndLoadProfiles() throws FormatException, IOException { AmidstLogger.info("Scanning for profiles."); List launcherProfiles = mojangApi.getMinecraftInstallation().readLauncherProfiles(); AmidstLogger.info("Successfully loaded profile list."); diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 567beead2..f5bf73306 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -10,7 +10,6 @@ import amidst.logging.AmidstLogger; import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.MinecraftInstallation; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; @@ -22,6 +21,7 @@ import amidst.mojangapi.world.WorldBuilder; import amidst.mojangapi.world.WorldSeed; import amidst.mojangapi.world.WorldType; +import amidst.parsing.FormatException; @ThreadSafe public class MojangApi { @@ -119,11 +119,10 @@ public World createWorldFromSeed(WorldSeed worldSeed, WorldType worldType) * created world objects. */ public World createWorldFromSaveGame(File file) - throws FileNotFoundException, - IOException, - IllegalStateException, + throws IllegalStateException, MinecraftInterfaceException, - MojangApiParsingException { + IOException, + FormatException { MinecraftInterface minecraftInterface = this.minecraftInterface; if (minecraftInterface != null) { return worldBuilder.fromSaveGame(minecraftInterface, minecraftInstallation.newSaveGame(file)); diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java index ed8757f99..ccca4cb90 100644 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ b/src/main/java/amidst/mojangapi/MojangApiBuilder.java @@ -8,9 +8,9 @@ import amidst.documentation.NotNull; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.MinecraftInstallation; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.WorldBuilder; +import amidst.parsing.FormatException; @Immutable public class MojangApiBuilder { @@ -35,7 +35,7 @@ public MojangApi construct() minecraftInstallation.newLauncherProfile( new File(parameters.minecraftJarFile), new File(parameters.minecraftJsonFile))); - } catch (MojangApiParsingException | IOException e) { + } catch (FormatException | IOException e) { result.setLauncherProfile(null); } } else { diff --git a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java index 77beb9d9f..c62569935 100644 --- a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java @@ -44,7 +44,7 @@ public MinecraftInstallation(DotMinecraftDirectory dotMinecraftDirectory) { this.dotMinecraftDirectory = dotMinecraftDirectory; } - public List readLauncherProfiles() throws MojangApiParsingException, IOException { + public List readLauncherProfiles() throws FormatException, IOException { return dotMinecraftDirectoryService .readLauncherProfilesFrom(dotMinecraftDirectory) .getProfiles() @@ -54,34 +54,28 @@ public List readLauncherProfiles() throws MojangApiPa .collect(Collectors.toList()); } - public LauncherProfile newLauncherProfile(String versionId) throws MojangApiParsingException, IOException { + public LauncherProfile newLauncherProfile(String versionId) throws FormatException, IOException { return newLauncherProfile( dotMinecraftDirectoryService.createValidVersionDirectory(dotMinecraftDirectory, versionId)); } - public LauncherProfile newLauncherProfile(File jar, File json) throws MojangApiParsingException, IOException { + public LauncherProfile newLauncherProfile(File jar, File json) throws FormatException, IOException { return newLauncherProfile(dotMinecraftDirectoryService.createValidVersionDirectory(jar, json)); } - private LauncherProfile newLauncherProfile(VersionDirectory versionDirectory) - throws IOException, - MojangApiParsingException { - try { - VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); - return new LauncherProfile( - dotMinecraftDirectory, - dotMinecraftDirectory.asProfileDirectory(), - versionDirectory, - versionJson, - versionJson.getId()); - } catch (FormatException e) { - throw new MojangApiParsingException(e); - } + private LauncherProfile newLauncherProfile(VersionDirectory versionDirectory) throws FormatException, IOException { + VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); + return new LauncherProfile( + dotMinecraftDirectory, + dotMinecraftDirectory.asProfileDirectory(), + versionDirectory, + versionJson, + versionJson.getId()); } - public SaveGame newSaveGame(File location) throws IOException, MojangApiParsingException { + public SaveGame newSaveGame(File location) throws IOException, FormatException { SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); SaveDirectory saveDirectory = saveDirectoryService.newSaveDirectory(location); - return new SaveGame(saveDirectory, saveDirectoryService.createLevelDat(saveDirectory)); + return new SaveGame(saveDirectory, saveDirectoryService.readLevelDat(saveDirectory)); } } diff --git a/src/main/java/amidst/mojangapi/file/MojangApiParsingException.java b/src/main/java/amidst/mojangapi/file/MojangApiParsingException.java deleted file mode 100644 index f5b3df5f4..000000000 --- a/src/main/java/amidst/mojangapi/file/MojangApiParsingException.java +++ /dev/null @@ -1,16 +0,0 @@ -package amidst.mojangapi.file; - -@SuppressWarnings("serial") -public class MojangApiParsingException extends Exception { - public MojangApiParsingException(String message) { - super(message); - } - - public MojangApiParsingException(Throwable cause) { - super(cause); - } - - public MojangApiParsingException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java b/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java index 588846660..7787814d2 100644 --- a/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java +++ b/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java @@ -28,22 +28,18 @@ public String getName() { return launcherProfileJson.getName(); } - public LauncherProfile resolve(VersionList versionList) throws MojangApiParsingException, IOException { + public LauncherProfile resolve(VersionList versionList) throws FormatException, IOException { DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); ProfileDirectory profileDirectory = dotMinecraftDirectoryService .createValidProfileDirectory(launcherProfileJson, dotMinecraftDirectory); VersionDirectory versionDirectory = dotMinecraftDirectoryService .createValidVersionDirectory(launcherProfileJson, versionList, dotMinecraftDirectory); - try { - VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); - return new LauncherProfile( - dotMinecraftDirectory, - profileDirectory, - versionDirectory, - versionJson, - launcherProfileJson.getName()); - } catch (FormatException e) { - throw new MojangApiParsingException(e); - } + VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class); + return new LauncherProfile( + dotMinecraftDirectory, + profileDirectory, + versionDirectory, + versionJson, + launcherProfileJson.getName()); } } diff --git a/src/main/java/amidst/mojangapi/file/VersionList.java b/src/main/java/amidst/mojangapi/file/VersionList.java index 3e8d02fb3..82c806f53 100644 --- a/src/main/java/amidst/mojangapi/file/VersionList.java +++ b/src/main/java/amidst/mojangapi/file/VersionList.java @@ -7,6 +7,7 @@ import amidst.documentation.Immutable; import amidst.mojangapi.file.service.VersionListService; +import amidst.parsing.FormatException; @Immutable public class VersionList { @@ -21,7 +22,7 @@ public static VersionList newRemoteOrLocalVersionList() throws FileNotFoundExcep .collect(Collectors.toList())); } - public static VersionList newRemoteVersionList() throws MojangApiParsingException, IOException { + public static VersionList newRemoteVersionList() throws FormatException, IOException { return new VersionList( new VersionListService() .readRemoteVersionList() @@ -31,7 +32,7 @@ public static VersionList newRemoteVersionList() throws MojangApiParsingExceptio .collect(Collectors.toList())); } - public static VersionList newLocalVersionList() throws MojangApiParsingException, IOException { + public static VersionList newLocalVersionList() throws FormatException, IOException { return new VersionList( new VersionListService() .readLocalVersionListFromResource() diff --git a/src/main/java/amidst/mojangapi/file/VersionListProvider.java b/src/main/java/amidst/mojangapi/file/VersionListProvider.java index 2a77eea40..b0159e34c 100644 --- a/src/main/java/amidst/mojangapi/file/VersionListProvider.java +++ b/src/main/java/amidst/mojangapi/file/VersionListProvider.java @@ -5,10 +5,11 @@ import amidst.documentation.AmidstThread; import amidst.documentation.CalledOnlyBy; import amidst.documentation.ThreadSafe; +import amidst.parsing.FormatException; @ThreadSafe public class VersionListProvider { - public static VersionListProvider create() throws MojangApiParsingException, IOException { + public static VersionListProvider create() throws FormatException, IOException { return new VersionListProvider(VersionList.newLocalVersionList()); } @@ -20,7 +21,7 @@ public VersionListProvider(VersionList local) { } @CalledOnlyBy(AmidstThread.WORKER) - public void startDownload() throws MojangApiParsingException, IOException { + public void startDownload() throws FormatException, IOException { remote = VersionList.newRemoteVersionList(); } diff --git a/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java b/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java index f6ea237ed..1483f2bd9 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java +++ b/src/main/java/amidst/mojangapi/file/nbt/LevelDatNbt.java @@ -1,17 +1,20 @@ package amidst.mojangapi.file.nbt; +import java.io.File; +import java.io.IOException; + import org.jnbt.CompoundTag; import amidst.documentation.Immutable; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.world.WorldType; import amidst.mojangapi.world.coordinates.CoordinatesInWorld; +import amidst.parsing.FormatException; @Immutable public class LevelDatNbt { - public static LevelDatNbt from(CompoundTag root) throws MojangApiParsingException { + public static LevelDatNbt from(File file) throws IOException, FormatException { try { - CompoundTag dataTag = readDataTag(root); + CompoundTag dataTag = readDataTag(NBTUtils.readTagFromFile(file)); long seed = readRandomSeed(dataTag); CoordinatesInWorld worldSpawn = readWorldSpawn(dataTag); WorldType worldType = readWorldType(dataTag); @@ -19,7 +22,7 @@ public static LevelDatNbt from(CompoundTag root) throws MojangApiParsingExceptio boolean hasPlayer = hasPlayerTag(dataTag); return new LevelDatNbt(seed, worldSpawn, worldType, generatorOptions, hasPlayer); } catch (NullPointerException e) { - throw new MojangApiParsingException("cannot read level.dat", e); + throw new FormatException("cannot read level.dat: " + file); } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java index 9c5a1c497..8e64471a3 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationLoader.java @@ -11,6 +11,7 @@ import org.jnbt.Tag; import amidst.documentation.Immutable; +import amidst.logging.AmidstLogger; import amidst.mojangapi.file.nbt.NBTTagKeys; import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.world.player.PlayerCoordinates; @@ -23,6 +24,7 @@ public static Optional tryReadFromPlayerFile(File file) throw try { return Optional.of(readPlayerCoordinates(NBTUtils.readTagFromFile(file))); } catch (NullPointerException e) { + AmidstLogger.warn(e, "cannot read player from file: " + file); return Optional.empty(); } } @@ -32,6 +34,7 @@ public static Optional tryReadFromLevelDat(File file) throws return Optional .of(readPlayerCoordinates(getSinglePlayerPlayerTag(getTagRootTag(NBTUtils.readTagFromFile(file))))); } catch (NullPointerException e) { + AmidstLogger.warn(e, "cannot read player from level.dat: " + file); return Optional.empty(); } } diff --git a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java index 374f60e8f..ab00d0752 100644 --- a/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java +++ b/src/main/java/amidst/mojangapi/file/nbt/player/PlayerLocationSaver.java @@ -13,6 +13,7 @@ import org.jnbt.Tag; import amidst.documentation.Immutable; +import amidst.logging.AmidstLogger; import amidst.mojangapi.file.nbt.NBTTagKeys; import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.world.player.PlayerCoordinates; @@ -28,6 +29,7 @@ public static boolean tryWriteToPlayerFile(PlayerCoordinates coordinates, File f NBTUtils.writeTagToFile(file, modifiedDataTag); return true; } catch (NullPointerException e) { + AmidstLogger.warn(e, "cannot write player to file: " + file); return false; } } @@ -39,6 +41,7 @@ public static boolean tryWriteToLevelDat(PlayerCoordinates coordinates, File fil NBTUtils.writeTagToFile(file, modifiedBaseTag); return true; } catch (NullPointerException e) { + AmidstLogger.warn(e, "cannot write player to level.dat: " + file); return false; } } diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index 3631d9f80..da29a0770 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -9,7 +9,6 @@ import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.Version; import amidst.mojangapi.file.VersionList; import amidst.mojangapi.file.directory.DotMinecraftDirectory; @@ -87,13 +86,9 @@ private File getMinecraftDirectory() { @NotNull public LauncherProfilesJson readLauncherProfilesFrom(DotMinecraftDirectory dotMinecraftDirectory) - throws MojangApiParsingException, + throws FormatException, IOException { - try { - return JsonReader.readLocation(dotMinecraftDirectory.getLauncherProfilesJson(), LauncherProfilesJson.class); - } catch (FormatException e) { - throw new MojangApiParsingException(e); - } + return JsonReader.readLocation(dotMinecraftDirectory.getLauncherProfilesJson(), LauncherProfilesJson.class); } @NotNull diff --git a/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java index b9df9f66a..a0a3d6473 100644 --- a/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java +++ b/src/main/java/amidst/mojangapi/file/service/PlayerInformationService.java @@ -14,7 +14,6 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.player.PlayerJson; import amidst.mojangapi.file.json.player.PropertyJson; import amidst.mojangapi.file.json.player.SKINJson; @@ -96,25 +95,25 @@ private Optional tryReadTexturesProperty(PlayerJson player } } return Optional.empty(); - } catch (FormatException | MojangApiParsingException e) { + } catch (FormatException e) { return Optional.empty(); } } - private boolean isTexturesProperty(PropertyJson propertyJson) throws MojangApiParsingException { + private boolean isTexturesProperty(PropertyJson propertyJson) throws FormatException { String name = propertyJson.getName(); if (name == null) { - throw new MojangApiParsingException("property has no name"); + throw new FormatException("property has no name"); } else { return name.equals("textures"); } } @NotNull - private String getDecodedValue(PropertyJson propertyJson) throws MojangApiParsingException { + private String getDecodedValue(PropertyJson propertyJson) throws FormatException { String value = propertyJson.getValue(); if (value == null) { - throw new MojangApiParsingException("unable to decode property value"); + throw new FormatException("unable to decode property value"); } else { return new String( Base64.getDecoder().decode(value.getBytes(StandardCharsets.UTF_8)), diff --git a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java index 3773c5e69..c7cba8b88 100644 --- a/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/SaveDirectoryService.java @@ -14,14 +14,13 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.directory.SaveDirectory; import amidst.mojangapi.file.nbt.LevelDatNbt; -import amidst.mojangapi.file.nbt.NBTUtils; import amidst.mojangapi.file.nbt.player.PlayerLocationLoader; import amidst.mojangapi.file.nbt.player.PlayerLocationSaver; import amidst.mojangapi.file.nbt.player.PlayerNbt; import amidst.mojangapi.world.player.PlayerCoordinates; +import amidst.parsing.FormatException; @Immutable public class SaveDirectoryService { @@ -67,8 +66,8 @@ private SaveDirectory createValidSaveDirectory(File currentFile) { } } - public LevelDatNbt createLevelDat(SaveDirectory saveDirectory) throws IOException, MojangApiParsingException { - return LevelDatNbt.from(NBTUtils.readTagFromFile(saveDirectory.getLevelDat())); + public LevelDatNbt readLevelDat(SaveDirectory saveDirectory) throws IOException, FormatException { + return LevelDatNbt.from(saveDirectory.getLevelDat()); } /** diff --git a/src/main/java/amidst/mojangapi/file/service/VersionListService.java b/src/main/java/amidst/mojangapi/file/service/VersionListService.java index 4c8e65e6b..ace594442 100644 --- a/src/main/java/amidst/mojangapi/file/service/VersionListService.java +++ b/src/main/java/amidst/mojangapi/file/service/VersionListService.java @@ -8,7 +8,6 @@ import amidst.documentation.Immutable; import amidst.documentation.NotNull; import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.parsing.FormatException; import amidst.parsing.json.JsonReader; @@ -27,7 +26,7 @@ public VersionListJson readRemoteOrLocalVersionList() throws FileNotFoundExcepti VersionListJson remote = readRemoteVersionList(); AmidstLogger.info("Successfully loaded version list. URL: " + REMOTE_VERSION_LIST); return remote; - } catch (IOException | MojangApiParsingException e) { + } catch (FormatException | IOException e) { AmidstLogger.warn("Unable to read remote version list."); AmidstLogger.warn(e); AmidstLogger.warn("Aborting version list load. URL: " + REMOTE_VERSION_LIST); @@ -37,7 +36,7 @@ public VersionListJson readRemoteOrLocalVersionList() throws FileNotFoundExcepti VersionListJson local = readLocalVersionListFromResource(); AmidstLogger.info("Successfully loaded version list. URL: " + LOCAL_VERSION_LIST); return local; - } catch (IOException | MojangApiParsingException e) { + } catch (FormatException | IOException e) { AmidstLogger.warn("Unable to read local version list."); AmidstLogger.warn(e); AmidstLogger.warn("Aborting version list load. URL: " + LOCAL_VERSION_LIST); @@ -47,20 +46,12 @@ public VersionListJson readRemoteOrLocalVersionList() throws FileNotFoundExcepti } @NotNull - public VersionListJson readRemoteVersionList() throws MojangApiParsingException, IOException { - try { - return JsonReader.readLocation(REMOTE_VERSION_LIST, VersionListJson.class); - } catch (FormatException e) { - throw new MojangApiParsingException(e); - } + public VersionListJson readRemoteVersionList() throws FormatException, IOException { + return JsonReader.readLocation(REMOTE_VERSION_LIST, VersionListJson.class); } @NotNull - public VersionListJson readLocalVersionListFromResource() throws MojangApiParsingException, IOException { - try { - return JsonReader.readLocation(LOCAL_VERSION_LIST, VersionListJson.class); - } catch (FormatException e) { - throw new MojangApiParsingException(e); - } + public VersionListJson readLocalVersionListFromResource() throws FormatException, IOException { + return JsonReader.readLocation(LOCAL_VERSION_LIST, VersionListJson.class); } } diff --git a/src/main/java/amidst/mojangapi/world/WorldBuilder.java b/src/main/java/amidst/mojangapi/world/WorldBuilder.java index b2e058bab..b9bcf7922 100644 --- a/src/main/java/amidst/mojangapi/world/WorldBuilder.java +++ b/src/main/java/amidst/mojangapi/world/WorldBuilder.java @@ -4,7 +4,6 @@ import amidst.documentation.Immutable; import amidst.mojangapi.file.ImmutablePlayerInformationProvider; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.PlayerInformationProvider; import amidst.mojangapi.file.SaveGame; import amidst.mojangapi.minecraftinterface.MinecraftInterface; @@ -74,8 +73,7 @@ public World fromSeed(MinecraftInterface minecraftInterface, WorldSeed worldSeed public World fromSaveGame(MinecraftInterface minecraftInterface, SaveGame saveGame) throws IOException, - MinecraftInterfaceException, - MojangApiParsingException { + MinecraftInterfaceException { VersionFeatures versionFeatures = DefaultVersionFeatures.create(minecraftInterface.getRecognisedVersion()); MovablePlayerList movablePlayerList = new MovablePlayerList( playerInformationProvider, diff --git a/src/test/java/amidst/devtools/DevToolRunner.java b/src/test/java/amidst/devtools/DevToolRunner.java index 9a61b8b92..6be60d78b 100644 --- a/src/test/java/amidst/devtools/DevToolRunner.java +++ b/src/test/java/amidst/devtools/DevToolRunner.java @@ -9,9 +9,9 @@ import amidst.AmidstVersion; import amidst.ResourceLoader; import amidst.devtools.settings.DevToolSettings; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.VersionList; import amidst.mojangapi.world.biome.Biome; +import amidst.parsing.FormatException; /** * Eclipse does not allow to run the main directly as a Java Application, @@ -21,37 +21,37 @@ public class DevToolRunner { @Ignore @Test - public void generateRecognisedVersionList() throws IOException, MojangApiParsingException { + public void generateRecognisedVersionList() throws FormatException, IOException { new GenerateRecognisedVersionList(versionsDirectory(), librariesDirectory(), versionList()).run(); } @Ignore @Test - public void generateUpdateInformationJson() throws IOException, MojangApiParsingException { + public void generateUpdateInformationJson() { new GenerateUpdateInformationJson(amidstVersion()).run(); } @Ignore @Test - public void generateWorldTestData() throws IOException, MojangApiParsingException { + public void generateWorldTestData() throws FormatException, IOException { new GenerateWorldTestData(versionsDirectory(), librariesDirectory(), versionList()).run(); } @Ignore @Test - public void checkMinecraftJarFileDownloadAvailability() throws IOException, MojangApiParsingException { + public void checkMinecraftJarFileDownloadAvailability() throws FormatException, IOException { new MinecraftJarDownloadAvailabilityChecker(versionList()).run(); } @Ignore @Test - public void downloadMinecraftJarFiles() throws IOException, MojangApiParsingException { + public void downloadMinecraftJarFiles() throws FormatException, IOException { new MinecraftJarDownloader(versionsDirectory(), versionList()).run(); } @Ignore @Test - public void checkMinecraftVersionCompatibility() throws IOException, MojangApiParsingException { + public void checkMinecraftVersionCompatibility() throws FormatException, IOException { new MinecraftVersionCompatibilityChecker(versionsDirectory(), versionList()).run(); } @@ -61,7 +61,7 @@ public void generateBiomeColorImages() throws IOException { new GenerateBiomeColorImages(Biome.allBiomes(), new File(biomeColorImagesDirectory())).run(); } - private VersionList versionList() throws IOException, MojangApiParsingException { + private VersionList versionList() throws FormatException, IOException { return VersionList.newRemoteVersionList(); } diff --git a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java index 2d414c43c..e94001bd3 100644 --- a/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java +++ b/src/test/java/amidst/devtools/GenerateRecognisedVersionList.java @@ -10,10 +10,10 @@ import amidst.logging.AmidstLogger; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.MinecraftInstallation; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.Version; import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.RecognisedVersion; +import amidst.parsing.FormatException; public class GenerateRecognisedVersionList { private final String prefix; @@ -47,7 +47,7 @@ private void process(Version version) { if (version.tryDownloadClient(prefix)) { try { process(version.getId()); - } catch (ClassNotFoundException | NoClassDefFoundError | MojangApiParsingException | IOException e) { + } catch (ClassNotFoundException | NoClassDefFoundError | FormatException | IOException e) { e.printStackTrace(); versionsWithError.add(version.getId()); } @@ -56,7 +56,7 @@ private void process(Version version) { } } - private void process(String versionId) throws ClassNotFoundException, MojangApiParsingException, IOException { + private void process(String versionId) throws ClassNotFoundException, FormatException, IOException { AmidstLogger.info("version " + versionId); URLClassLoader classLoader = minecraftInstallation.newLauncherProfile(versionId).newClassLoader(); String magicString = RecognisedVersion.generateMagicString(classLoader); diff --git a/src/test/java/amidst/devtools/GenerateWorldTestData.java b/src/test/java/amidst/devtools/GenerateWorldTestData.java index 057b84443..bfae77569 100644 --- a/src/test/java/amidst/devtools/GenerateWorldTestData.java +++ b/src/test/java/amidst/devtools/GenerateWorldTestData.java @@ -9,7 +9,6 @@ import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.MinecraftInstallation; -import amidst.mojangapi.file.MojangApiParsingException; import amidst.mojangapi.file.Version; import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; @@ -18,6 +17,7 @@ import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.testworld.TestWorldCache; import amidst.mojangapi.world.testworld.TestWorldDeclaration; +import amidst.parsing.FormatException; public class GenerateWorldTestData { private final String prefix; @@ -56,8 +56,8 @@ private void generate(TestWorldDeclaration declaration, Version version) { } catch ( LocalMinecraftInterfaceCreationException | MinecraftInterfaceException - | IOException - | MojangApiParsingException e) { + | FormatException + | IOException e) { e.printStackTrace(); failed.add(version.getId()); } From dac5189bcf8f8ce2342eb506e22454b5b7ce459d Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 21:46:21 +0200 Subject: [PATCH 36/48] added method MinecraftInstallation::readInstalledVersionsAsLauncherProfiles --- .../mojangapi/file/MinecraftInstallation.java | 14 ++++++++++++ .../service/DotMinecraftDirectoryService.java | 22 +++++++++++++++++++ .../java/amidst/devtools/DevToolRunner.java | 7 ++++++ .../GenerateInstalledVersionsList.java | 19 ++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 src/test/java/amidst/devtools/GenerateInstalledVersionsList.java diff --git a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java index c62569935..a4eb60b9d 100644 --- a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; @@ -29,6 +30,10 @@ public static MinecraftInstallation newCustomMinecraftInstallation( return new MinecraftInstallation(dotMinecraftDirectory); } + public static MinecraftInstallation newLocalMinecraftInstallation() throws DotMinecraftDirectoryNotFoundException { + return newLocalMinecraftInstallation(null); + } + public static MinecraftInstallation newLocalMinecraftInstallation(String preferredDotMinecraftDirectory) throws DotMinecraftDirectoryNotFoundException { DotMinecraftDirectory dotMinecraftDirectory = new DotMinecraftDirectoryService() @@ -44,6 +49,15 @@ public MinecraftInstallation(DotMinecraftDirectory dotMinecraftDirectory) { this.dotMinecraftDirectory = dotMinecraftDirectory; } + public List readInstalledVersionsAsLauncherProfiles() throws FormatException, IOException { + List result = new LinkedList<>(); + for (VersionDirectory versionDirectory : dotMinecraftDirectoryService + .findInstalledValidVersionDirectories(dotMinecraftDirectory)) { + result.add(newLauncherProfile(versionDirectory)); + } + return result; + } + public List readLauncherProfiles() throws FormatException, IOException { return dotMinecraftDirectoryService .readLauncherProfilesFrom(dotMinecraftDirectory) diff --git a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java index da29a0770..e10eeb3c5 100644 --- a/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java +++ b/src/main/java/amidst/mojangapi/file/service/DotMinecraftDirectoryService.java @@ -3,7 +3,10 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import amidst.documentation.Immutable; import amidst.documentation.NotNull; @@ -187,4 +190,23 @@ private VersionDirectory createVersionDirectory(DotMinecraftDirectory dotMinecra File json = filenameService.getClientJsonFile(versions, versionId); return new VersionDirectory(jar, json); } + + public List findInstalledValidVersionDirectories(DotMinecraftDirectory dotMinecraftDirectory) { + return listFiles(dotMinecraftDirectory.getVersions()) + .stream() + .filter(File::isDirectory) + .map(File::getName) + .map(id -> createVersionDirectory(dotMinecraftDirectory, id)) + .filter(VersionDirectory::isValid) + .collect(Collectors.toList()); + } + + private List listFiles(File file) { + File[] files = file.listFiles(); + if (files != null) { + return Arrays.asList(files); + } else { + return Collections.emptyList(); + } + } } diff --git a/src/test/java/amidst/devtools/DevToolRunner.java b/src/test/java/amidst/devtools/DevToolRunner.java index 6be60d78b..b6dc35230 100644 --- a/src/test/java/amidst/devtools/DevToolRunner.java +++ b/src/test/java/amidst/devtools/DevToolRunner.java @@ -9,6 +9,7 @@ import amidst.AmidstVersion; import amidst.ResourceLoader; import amidst.devtools.settings.DevToolSettings; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.VersionList; import amidst.mojangapi.world.biome.Biome; import amidst.parsing.FormatException; @@ -19,6 +20,12 @@ * ignored when creating a commit, so they will be ignored by travis ci. */ public class DevToolRunner { + @Ignore + @Test + public void generateInstalledVersionsList() throws FormatException, IOException { + new GenerateInstalledVersionsList(MinecraftInstallation.newLocalMinecraftInstallation()).run(); + } + @Ignore @Test public void generateRecognisedVersionList() throws FormatException, IOException { diff --git a/src/test/java/amidst/devtools/GenerateInstalledVersionsList.java b/src/test/java/amidst/devtools/GenerateInstalledVersionsList.java new file mode 100644 index 000000000..30d7fa6ab --- /dev/null +++ b/src/test/java/amidst/devtools/GenerateInstalledVersionsList.java @@ -0,0 +1,19 @@ +package amidst.devtools; + +import java.io.IOException; + +import amidst.mojangapi.file.MinecraftInstallation; +import amidst.parsing.FormatException; + +public class GenerateInstalledVersionsList { + private final MinecraftInstallation minecraftInstallation; + + public GenerateInstalledVersionsList(MinecraftInstallation minecraftInstallation) { + this.minecraftInstallation = minecraftInstallation; + } + + public void run() throws FormatException, IOException { + minecraftInstallation.readInstalledVersionsAsLauncherProfiles().stream().map(p -> p.getVersionId()).forEach( + System.out::println); + } +} From 30a13646fb1aafa2d60f2dd1cfe362921438a0ed Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 22:06:45 +0200 Subject: [PATCH 37/48] removed VersionList from MojangApi --- .../profileselect/LocalProfileComponent.java | 3 ++- src/main/java/amidst/mojangapi/MojangApi.java | 19 ----------------- .../mojangapi/file/VersionListProvider.java | 21 +++++++++++++++++++ 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index 274bc95e7..2d072b67d 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -13,6 +13,7 @@ import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.UnresolvedLauncherProfile; +import amidst.mojangapi.file.VersionListProvider; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.parsing.FormatException; import amidst.threading.WorkerExecutor; @@ -54,7 +55,7 @@ private void initDirectoriesLater() { @CalledOnlyBy(AmidstThread.WORKER) private boolean tryFind() { try { - resolvedProfile = unresolvedProfile.resolve(mojangApi.getVersionList()); + resolvedProfile = unresolvedProfile.resolve(VersionListProvider.getRemoteOrLocalVersionList()); return true; } catch (FormatException | IOException e) { AmidstLogger.warn(e); diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index f5bf73306..43a4a21b8 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -1,16 +1,13 @@ package amidst.mojangapi; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.Optional; -import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.MinecraftInstallation; -import amidst.mojangapi.file.VersionList; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -31,7 +28,6 @@ public class MojangApi { private final WorldBuilder worldBuilder; private final MinecraftInstallation minecraftInstallation; - private volatile VersionList versionList; private volatile MinecraftInterface minecraftInterface; private volatile LauncherProfile launcherProfile; @@ -48,21 +44,6 @@ public Optional getLauncherProfile() { return Optional.ofNullable(launcherProfile); } - @NotNull - public VersionList getVersionList() throws FileNotFoundException { - VersionList versionList = this.versionList; - if (versionList == null) { - synchronized (this) { - versionList = this.versionList; - if (versionList == null) { - versionList = VersionList.newRemoteOrLocalVersionList(); - this.versionList = versionList; - } - } - } - return versionList; - } - public void setLauncherProfile(LauncherProfile launcherProfile) throws LocalMinecraftInterfaceCreationException { this.launcherProfile = launcherProfile; if (launcherProfile != null) { diff --git a/src/main/java/amidst/mojangapi/file/VersionListProvider.java b/src/main/java/amidst/mojangapi/file/VersionListProvider.java index b0159e34c..17383ea64 100644 --- a/src/main/java/amidst/mojangapi/file/VersionListProvider.java +++ b/src/main/java/amidst/mojangapi/file/VersionListProvider.java @@ -1,9 +1,11 @@ package amidst.mojangapi.file; +import java.io.FileNotFoundException; import java.io.IOException; import amidst.documentation.AmidstThread; import amidst.documentation.CalledOnlyBy; +import amidst.documentation.NotNull; import amidst.documentation.ThreadSafe; import amidst.parsing.FormatException; @@ -13,6 +15,25 @@ public static VersionListProvider create() throws FormatException, IOException { return new VersionListProvider(VersionList.newLocalVersionList()); } + @NotNull + @Deprecated + public static VersionList getRemoteOrLocalVersionList() throws FileNotFoundException { + VersionList versionList = VersionListProvider.remoteOrLocalVersionList; + if (versionList == null) { + synchronized (VersionListProvider.class) { + versionList = VersionListProvider.remoteOrLocalVersionList; + if (versionList == null) { + versionList = VersionList.newRemoteOrLocalVersionList(); + VersionListProvider.remoteOrLocalVersionList = versionList; + } + } + } + return versionList; + } + + @Deprecated + private static volatile VersionList remoteOrLocalVersionList; + private final VersionList local; private volatile VersionList remote; From c3a7118deee98411ac0a41a8f22c43b07adca5df Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 22:13:05 +0200 Subject: [PATCH 38/48] removed helper methods from MojangApi --- .../gui/main/PerMainWindowInjector.java | 14 +++++++++--- src/main/java/amidst/mojangapi/MojangApi.java | 22 +++++-------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/main/java/amidst/gui/main/PerMainWindowInjector.java b/src/main/java/amidst/gui/main/PerMainWindowInjector.java index ac22edc62..c55047235 100644 --- a/src/main/java/amidst/gui/main/PerMainWindowInjector.java +++ b/src/main/java/amidst/gui/main/PerMainWindowInjector.java @@ -19,6 +19,7 @@ import amidst.gui.seedsearcher.SeedSearcher; import amidst.gui.seedsearcher.SeedSearcherWindow; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.world.World; import amidst.settings.biomeprofile.BiomeProfileDirectory; import amidst.threading.ThreadMaster; @@ -27,9 +28,16 @@ public class PerMainWindowInjector { @CalledOnlyBy(AmidstThread.EDT) private static String createVersionString(AmidstMetaData metadata, MojangApi mojangApi) { - return metadata.getVersion().createLongVersionString() + " - Selected Profile: " + mojangApi.getProfileName() - + " - Minecraft Version " + mojangApi.getVersionId() + " (recognised: " - + mojangApi.getRecognisedVersionName() + ")"; + return new StringBuilder() + .append(metadata.getVersion().createLongVersionString()) + .append(" - Selected Profile: ") + .append(mojangApi.getLauncherProfile().map(LauncherProfile::getProfileName).orElse("unknown")) + .append(" - Minecraft Version ") + .append(mojangApi.getLauncherProfile().map(LauncherProfile::getVersionId).orElse("unknown")) + .append(" (recognised: ") + .append(mojangApi.getRecognisedVersionName()) + .append(")") + .toString(); } private final Factory2 viewerFacadeFactory; diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 43a4a21b8..dc92a750d 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -22,9 +22,6 @@ @ThreadSafe public class MojangApi { - private static final String UNKNOWN_PROFILE_NAME = "unknown"; - public static final String UNKNOWN_VERSION_ID = "unknown"; - private final WorldBuilder worldBuilder; private final MinecraftInstallation minecraftInstallation; @@ -112,20 +109,11 @@ public World createWorldFromSaveGame(File file) } } - public String getVersionId() { - return getLauncherProfile().map(LauncherProfile::getVersionId).orElse(UNKNOWN_VERSION_ID); - } - public String getRecognisedVersionName() { - MinecraftInterface minecraftInterface = this.minecraftInterface; - if (minecraftInterface != null) { - return minecraftInterface.getRecognisedVersion().getName(); - } else { - return RecognisedVersion.UNKNOWN.getName(); - } - } - - public String getProfileName() { - return getLauncherProfile().map(LauncherProfile::getProfileName).orElse(UNKNOWN_PROFILE_NAME); + return Optional + .ofNullable(this.minecraftInterface) + .map(MinecraftInterface::getRecognisedVersion) + .map(RecognisedVersion::getName) + .orElse(RecognisedVersion.UNKNOWN.getName()); } } From 87c126289e37ecacc30488743757a304139cbeb8 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 22:38:28 +0200 Subject: [PATCH 39/48] removed MojangApiBuilder --- .../java/amidst/PerApplicationInjector.java | 13 +++++- src/main/java/amidst/mojangapi/MojangApi.java | 17 +++++-- .../amidst/mojangapi/MojangApiBuilder.java | 46 ------------------- .../mojangapi/file/MinecraftInstallation.java | 20 ++++++++ 4 files changed, 44 insertions(+), 52 deletions(-) delete mode 100644 src/main/java/amidst/mojangapi/MojangApiBuilder.java diff --git a/src/main/java/amidst/PerApplicationInjector.java b/src/main/java/amidst/PerApplicationInjector.java index 8643a730e..30c53a0df 100644 --- a/src/main/java/amidst/PerApplicationInjector.java +++ b/src/main/java/amidst/PerApplicationInjector.java @@ -1,5 +1,7 @@ package amidst; +import java.util.Optional; + import amidst.documentation.AmidstThread; import amidst.documentation.CalledOnlyBy; import amidst.documentation.NotThreadSafe; @@ -17,8 +19,9 @@ import amidst.gui.main.viewer.Zoom; import amidst.gui.profileselect.ProfileSelectWindow; import amidst.mojangapi.MojangApi; -import amidst.mojangapi.MojangApiBuilder; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; +import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.PlayerInformationCache; import amidst.mojangapi.file.PlayerInformationProvider; import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; @@ -34,6 +37,8 @@ public class PerApplicationInjector { private final AmidstSettings settings; private final PlayerInformationProvider playerInformationProvider; private final SeedHistoryLogger seedHistoryLogger; + private final MinecraftInstallation minecraftInstallation; + private final Optional preferredLauncherProfile; private final WorldBuilder worldBuilder; private final MojangApi mojangApi; private final BiomeProfileDirectory biomeProfileDirectory; @@ -52,8 +57,12 @@ public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData m this.settings = settings; this.playerInformationProvider = new PlayerInformationCache(); this.seedHistoryLogger = SeedHistoryLogger.from(parameters.seedHistoryFile); + this.minecraftInstallation = MinecraftInstallation + .newLocalMinecraftInstallation(parameters.dotMinecraftDirectory); + this.preferredLauncherProfile = minecraftInstallation + .tryReadLauncherProfile(parameters.minecraftJarFile, parameters.minecraftJsonFile); this.worldBuilder = new WorldBuilder(playerInformationProvider, seedHistoryLogger); - this.mojangApi = new MojangApiBuilder(worldBuilder, parameters).construct(); + this.mojangApi = MojangApi.from(minecraftInstallation, preferredLauncherProfile, worldBuilder); this.biomeProfileDirectory = BiomeProfileDirectory.create(parameters.biomeProfilesDirectory); this.threadMaster = new ThreadMaster(); this.layerBuilder = new LayerBuilder(); diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index dc92a750d..b50eb791d 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -22,15 +22,24 @@ @ThreadSafe public class MojangApi { - private final WorldBuilder worldBuilder; + public static MojangApi from( + MinecraftInstallation minecraftInstallation, + Optional preferredLauncherProfile, + WorldBuilder worldBuilder) throws LocalMinecraftInterfaceCreationException { + MojangApi result = new MojangApi(minecraftInstallation, worldBuilder); + result.setLauncherProfile(preferredLauncherProfile.orElse(null)); + return result; + } + private final MinecraftInstallation minecraftInstallation; + private final WorldBuilder worldBuilder; private volatile MinecraftInterface minecraftInterface; private volatile LauncherProfile launcherProfile; - public MojangApi(WorldBuilder worldBuilder, MinecraftInstallation minecraftInstallation) { - this.worldBuilder = worldBuilder; + public MojangApi(MinecraftInstallation minecraftInstallation, WorldBuilder worldBuilder) { this.minecraftInstallation = minecraftInstallation; + this.worldBuilder = worldBuilder; } public MinecraftInstallation getMinecraftInstallation() { @@ -60,7 +69,7 @@ public void setLauncherProfile(LauncherProfile launcherProfile) throws LocalMine } public MojangApi createSilentPlayerlessCopy() { - MojangApi result = new MojangApi(WorldBuilder.createSilentPlayerless(), minecraftInstallation); + MojangApi result = new MojangApi(minecraftInstallation, WorldBuilder.createSilentPlayerless()); try { result.setLauncherProfile(launcherProfile); } catch (LocalMinecraftInterfaceCreationException e) { diff --git a/src/main/java/amidst/mojangapi/MojangApiBuilder.java b/src/main/java/amidst/mojangapi/MojangApiBuilder.java deleted file mode 100644 index ccca4cb90..000000000 --- a/src/main/java/amidst/mojangapi/MojangApiBuilder.java +++ /dev/null @@ -1,46 +0,0 @@ -package amidst.mojangapi; - -import java.io.File; -import java.io.IOException; - -import amidst.CommandLineParameters; -import amidst.documentation.Immutable; -import amidst.documentation.NotNull; -import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; -import amidst.mojangapi.file.MinecraftInstallation; -import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; -import amidst.mojangapi.world.WorldBuilder; -import amidst.parsing.FormatException; - -@Immutable -public class MojangApiBuilder { - private final WorldBuilder worldBuilder; - private final CommandLineParameters parameters; - - public MojangApiBuilder(WorldBuilder worldBuilder, CommandLineParameters parameters) { - this.worldBuilder = worldBuilder; - this.parameters = parameters; - } - - @NotNull - public MojangApi construct() - throws DotMinecraftDirectoryNotFoundException, - LocalMinecraftInterfaceCreationException { - MinecraftInstallation minecraftInstallation = MinecraftInstallation - .newLocalMinecraftInstallation(parameters.dotMinecraftDirectory); - MojangApi result = new MojangApi(worldBuilder, minecraftInstallation); - if (parameters.minecraftJarFile != null && parameters.minecraftJsonFile != null) { - try { - result.setLauncherProfile( - minecraftInstallation.newLauncherProfile( - new File(parameters.minecraftJarFile), - new File(parameters.minecraftJsonFile))); - } catch (FormatException | IOException e) { - result.setLauncherProfile(null); - } - } else { - result.setLauncherProfile(null); - } - return result; - } -} diff --git a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java index a4eb60b9d..4e4e6c232 100644 --- a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.LinkedList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import amidst.documentation.Immutable; @@ -92,4 +93,23 @@ public SaveGame newSaveGame(File location) throws IOException, FormatException { SaveDirectory saveDirectory = saveDirectoryService.newSaveDirectory(location); return new SaveGame(saveDirectory, saveDirectoryService.readLevelDat(saveDirectory)); } + + public Optional tryReadLauncherProfile( + String preferredMinecraftJarFile, + String preferredMinecraftJsonFile) { + if (preferredMinecraftJarFile != null && preferredMinecraftJsonFile != null) { + try { + return Optional.of( + newLauncherProfile(new File(preferredMinecraftJarFile), new File(preferredMinecraftJsonFile))); + } catch (FormatException | IOException e) { + AmidstLogger.error( + e, + "cannot read launcher profile. preferredMinecraftJarFile: '" + preferredMinecraftJarFile + + "', preferredMinecraftJsonFile: '" + "'"); + return Optional.empty(); + } + } else { + return Optional.empty(); + } + } } From 7aa01fb196cbdce656398db85f0b40e8c40722e1 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 22:49:09 +0200 Subject: [PATCH 40/48] removed MojangApi::getMinecraftInstallation --- src/main/java/amidst/PerApplicationInjector.java | 8 +++++++- .../amidst/gui/profileselect/ProfileSelectWindow.java | 6 +++++- src/main/java/amidst/mojangapi/MojangApi.java | 4 ---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/amidst/PerApplicationInjector.java b/src/main/java/amidst/PerApplicationInjector.java index 30c53a0df..fdc23f842 100644 --- a/src/main/java/amidst/PerApplicationInjector.java +++ b/src/main/java/amidst/PerApplicationInjector.java @@ -102,7 +102,13 @@ private MainWindow createMainWindow() { @CalledOnlyBy(AmidstThread.EDT) private ProfileSelectWindow createProfileSelectWindow() { - return new ProfileSelectWindow(application, metadata, threadMaster.getWorkerExecutor(), mojangApi, settings); + return new ProfileSelectWindow( + application, + metadata, + threadMaster.getWorkerExecutor(), + minecraftInstallation, + mojangApi, + settings); } @CalledOnlyBy(AmidstThread.EDT) diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index f9a81cacf..8254a5a5b 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -21,6 +21,7 @@ import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.UnresolvedLauncherProfile; import amidst.parsing.FormatException; import amidst.threading.WorkerExecutor; @@ -33,6 +34,7 @@ public class ProfileSelectWindow { private final Application application; private final AmidstMetaData metadata; private final WorkerExecutor workerExecutor; + private final MinecraftInstallation minecraftInstallation; private final MojangApi mojangApi; private final AmidstSettings settings; @@ -44,11 +46,13 @@ public ProfileSelectWindow( Application application, AmidstMetaData metadata, WorkerExecutor workerExecutor, + MinecraftInstallation minecraftInstallation, MojangApi mojangApi, AmidstSettings settings) { this.application = application; this.metadata = metadata; this.workerExecutor = workerExecutor; + this.minecraftInstallation = minecraftInstallation; this.mojangApi = mojangApi; this.settings = settings; this.profileSelectPanel = new ProfileSelectPanel(settings.lastProfile, "Scanning..."); @@ -114,7 +118,7 @@ private void scanAndLoadProfilesLater() { @CalledOnlyBy(AmidstThread.WORKER) private List scanAndLoadProfiles() throws FormatException, IOException { AmidstLogger.info("Scanning for profiles."); - List launcherProfiles = mojangApi.getMinecraftInstallation().readLauncherProfiles(); + List launcherProfiles = minecraftInstallation.readLauncherProfiles(); AmidstLogger.info("Successfully loaded profile list."); return launcherProfiles; } diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index b50eb791d..3b4f20d35 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -42,10 +42,6 @@ public MojangApi(MinecraftInstallation minecraftInstallation, WorldBuilder world this.worldBuilder = worldBuilder; } - public MinecraftInstallation getMinecraftInstallation() { - return minecraftInstallation; - } - public Optional getLauncherProfile() { return Optional.ofNullable(launcherProfile); } From a2f8e1ca97902b2e4ba8a559050caf2f5328fe07 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 22:54:39 +0200 Subject: [PATCH 41/48] removed MinecraftInstallation from MojangApi --- .../java/amidst/PerApplicationInjector.java | 3 ++- .../gui/main/PerMainWindowInjector.java | 3 +++ .../java/amidst/gui/main/WorldSwitcher.java | 6 ++++- src/main/java/amidst/mojangapi/MojangApi.java | 25 +++++++------------ 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/main/java/amidst/PerApplicationInjector.java b/src/main/java/amidst/PerApplicationInjector.java index fdc23f842..13f6a8ca1 100644 --- a/src/main/java/amidst/PerApplicationInjector.java +++ b/src/main/java/amidst/PerApplicationInjector.java @@ -62,7 +62,7 @@ public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData m this.preferredLauncherProfile = minecraftInstallation .tryReadLauncherProfile(parameters.minecraftJarFile, parameters.minecraftJsonFile); this.worldBuilder = new WorldBuilder(playerInformationProvider, seedHistoryLogger); - this.mojangApi = MojangApi.from(minecraftInstallation, preferredLauncherProfile, worldBuilder); + this.mojangApi = MojangApi.from(preferredLauncherProfile, worldBuilder); this.biomeProfileDirectory = BiomeProfileDirectory.create(parameters.biomeProfilesDirectory); this.threadMaster = new ThreadMaster(); this.layerBuilder = new LayerBuilder(); @@ -94,6 +94,7 @@ private MainWindow createMainWindow() { application, metadata, settings, + minecraftInstallation, mojangApi, biomeProfileDirectory, this::createViewerFacade, diff --git a/src/main/java/amidst/gui/main/PerMainWindowInjector.java b/src/main/java/amidst/gui/main/PerMainWindowInjector.java index c55047235..36c9d5928 100644 --- a/src/main/java/amidst/gui/main/PerMainWindowInjector.java +++ b/src/main/java/amidst/gui/main/PerMainWindowInjector.java @@ -20,6 +20,7 @@ import amidst.gui.seedsearcher.SeedSearcherWindow; import amidst.mojangapi.MojangApi; import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.world.World; import amidst.settings.biomeprofile.BiomeProfileDirectory; import amidst.threading.ThreadMaster; @@ -58,6 +59,7 @@ public PerMainWindowInjector( Application application, AmidstMetaData metadata, AmidstSettings settings, + MinecraftInstallation minecraftInstallation, MojangApi mojangApi, BiomeProfileDirectory biomeProfileDirectory, Factory2 viewerFacadeFactory, @@ -69,6 +71,7 @@ public PerMainWindowInjector( this.viewerFacadeReference = new AtomicReference<>(); this.dialogs = new MainWindowDialogs(settings, mojangApi, frame); this.worldSwitcher = new WorldSwitcher( + minecraftInstallation, mojangApi, this::createViewerFacade, threadMaster, diff --git a/src/main/java/amidst/gui/main/WorldSwitcher.java b/src/main/java/amidst/gui/main/WorldSwitcher.java index 57ee57440..f9909fd11 100644 --- a/src/main/java/amidst/gui/main/WorldSwitcher.java +++ b/src/main/java/amidst/gui/main/WorldSwitcher.java @@ -17,6 +17,7 @@ import amidst.gui.main.viewer.ViewerFacade; import amidst.logging.AmidstLogger; import amidst.mojangapi.MojangApi; +import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.world.World; import amidst.mojangapi.world.WorldSeed; @@ -28,6 +29,7 @@ @NotThreadSafe public class WorldSwitcher { + private final MinecraftInstallation minecraftInstallation; private final MojangApi mojangApi; private final Factory1 viewerFacadeFactory; private final ThreadMaster threadMaster; @@ -39,6 +41,7 @@ public class WorldSwitcher { @CalledOnlyBy(AmidstThread.EDT) public WorldSwitcher( + MinecraftInstallation minecraftInstallation, MojangApi mojangApi, Factory1 viewerFacadeFactory, ThreadMaster threadMaster, @@ -47,6 +50,7 @@ public WorldSwitcher( AtomicReference viewerFacadeReference, MainWindowDialogs dialogs, Supplier menuBarSupplier) { + this.minecraftInstallation = minecraftInstallation; this.mojangApi = mojangApi; this.viewerFacadeFactory = viewerFacadeFactory; this.threadMaster = threadMaster; @@ -70,7 +74,7 @@ public void displayWorld(WorldSeed worldSeed, WorldType worldType) { @CalledOnlyBy(AmidstThread.EDT) public void displayWorld(File file) { try { - setWorld(mojangApi.createWorldFromSaveGame(file)); + setWorld(mojangApi.createWorldFromSaveGame(minecraftInstallation.newSaveGame(file))); } catch (IllegalStateException | MinecraftInterfaceException | IOException | FormatException e) { AmidstLogger.warn(e); dialogs.displayError(e); diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java index 3b4f20d35..85efd8e7a 100644 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ b/src/main/java/amidst/mojangapi/MojangApi.java @@ -1,13 +1,12 @@ package amidst.mojangapi; -import java.io.File; import java.io.IOException; import java.util.Optional; import amidst.documentation.ThreadSafe; import amidst.logging.AmidstLogger; import amidst.mojangapi.file.LauncherProfile; -import amidst.mojangapi.file.MinecraftInstallation; +import amidst.mojangapi.file.SaveGame; import amidst.mojangapi.minecraftinterface.MinecraftInterface; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -18,27 +17,22 @@ import amidst.mojangapi.world.WorldBuilder; import amidst.mojangapi.world.WorldSeed; import amidst.mojangapi.world.WorldType; -import amidst.parsing.FormatException; @ThreadSafe public class MojangApi { - public static MojangApi from( - MinecraftInstallation minecraftInstallation, - Optional preferredLauncherProfile, - WorldBuilder worldBuilder) throws LocalMinecraftInterfaceCreationException { - MojangApi result = new MojangApi(minecraftInstallation, worldBuilder); + public static MojangApi from(Optional preferredLauncherProfile, WorldBuilder worldBuilder) + throws LocalMinecraftInterfaceCreationException { + MojangApi result = new MojangApi(worldBuilder); result.setLauncherProfile(preferredLauncherProfile.orElse(null)); return result; } - private final MinecraftInstallation minecraftInstallation; private final WorldBuilder worldBuilder; private volatile MinecraftInterface minecraftInterface; private volatile LauncherProfile launcherProfile; - public MojangApi(MinecraftInstallation minecraftInstallation, WorldBuilder worldBuilder) { - this.minecraftInstallation = minecraftInstallation; + public MojangApi(WorldBuilder worldBuilder) { this.worldBuilder = worldBuilder; } @@ -65,7 +59,7 @@ public void setLauncherProfile(LauncherProfile launcherProfile) throws LocalMine } public MojangApi createSilentPlayerlessCopy() { - MojangApi result = new MojangApi(minecraftInstallation, WorldBuilder.createSilentPlayerless()); + MojangApi result = new MojangApi(WorldBuilder.createSilentPlayerless()); try { result.setLauncherProfile(launcherProfile); } catch (LocalMinecraftInterfaceCreationException e) { @@ -101,14 +95,13 @@ public World createWorldFromSeed(WorldSeed worldSeed, WorldType worldType) * one world at a time. Creating a new world will break all previously * created world objects. */ - public World createWorldFromSaveGame(File file) + public World createWorldFromSaveGame(SaveGame saveGame) throws IllegalStateException, - MinecraftInterfaceException, IOException, - FormatException { + MinecraftInterfaceException { MinecraftInterface minecraftInterface = this.minecraftInterface; if (minecraftInterface != null) { - return worldBuilder.fromSaveGame(minecraftInterface, minecraftInstallation.newSaveGame(file)); + return worldBuilder.fromSaveGame(minecraftInterface, saveGame); } else { throw new IllegalStateException("cannot create a world without a minecraft interface"); } From 4ae5d48e6bdfbbef9d29ff6815474faf8b825912 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Thu, 1 Jun 2017 23:50:10 +0200 Subject: [PATCH 42/48] split MojangApi into LauncherProfileRunner and RunningLauncherProfile --- src/main/java/amidst/Application.java | 30 +++-- .../java/amidst/PerApplicationInjector.java | 20 +-- .../amidst/gui/main/MainWindowDialogs.java | 12 +- .../gui/main/PerMainWindowInjector.java | 24 ++-- .../java/amidst/gui/main/WorldSwitcher.java | 16 +-- .../profileselect/LocalProfileComponent.java | 57 ++++----- .../gui/profileselect/ProfileComponent.java | 16 +-- .../profileselect/ProfileSelectWindow.java | 11 +- .../amidst/gui/seedsearcher/SeedSearcher.java | 13 +- .../mojangapi/LauncherProfileRunner.java | 19 +++ src/main/java/amidst/mojangapi/MojangApi.java | 117 ------------------ .../mojangapi/RunningLauncherProfile.java | 81 ++++++++++++ 12 files changed, 206 insertions(+), 210 deletions(-) create mode 100644 src/main/java/amidst/mojangapi/LauncherProfileRunner.java delete mode 100644 src/main/java/amidst/mojangapi/MojangApi.java create mode 100644 src/main/java/amidst/mojangapi/RunningLauncherProfile.java diff --git a/src/main/java/amidst/Application.java b/src/main/java/amidst/Application.java index fc9141308..577edc903 100644 --- a/src/main/java/amidst/Application.java +++ b/src/main/java/amidst/Application.java @@ -1,5 +1,7 @@ package amidst; +import java.util.Optional; + import amidst.dependency.injection.Factory0; import amidst.dependency.injection.Factory1; import amidst.documentation.AmidstThread; @@ -10,14 +12,18 @@ import amidst.gui.main.MainWindowDialogs; import amidst.gui.main.UpdatePrompt; import amidst.gui.profileselect.ProfileSelectWindow; -import amidst.mojangapi.MojangApi; +import amidst.mojangapi.LauncherProfileRunner; +import amidst.mojangapi.RunningLauncherProfile; +import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; @NotThreadSafe public class Application { - private final MojangApi mojangApi; + private final Optional preferredLauncherProfile; + private final LauncherProfileRunner launcherProfileRunner; private final Factory1 noisyUpdatePromptFactory; private final Factory0 silentUpdatePromptFactory; - private final Factory0 mainWindowFactory; + private final Factory1 mainWindowFactory; private final Factory0 profileSelectWindowFactory; private final Factory0 licenseWindowFactory; @@ -26,13 +32,15 @@ public class Application { @CalledOnlyBy(AmidstThread.EDT) public Application( - MojangApi mojangApi, + Optional preferredLauncherProfile, + LauncherProfileRunner launcherProfileRunner, Factory1 noisyUpdatePromptFactory, Factory0 silentUpdatePromptFactory, - Factory0 mainWindowFactory, + Factory1 mainWindowFactory, Factory0 profileSelectWindowFactory, Factory0 licenseWindowFactory) { - this.mojangApi = mojangApi; + this.preferredLauncherProfile = preferredLauncherProfile; + this.launcherProfileRunner = launcherProfileRunner; this.noisyUpdatePromptFactory = noisyUpdatePromptFactory; this.silentUpdatePromptFactory = silentUpdatePromptFactory; this.mainWindowFactory = mainWindowFactory; @@ -41,10 +49,10 @@ public Application( } @CalledOnlyBy(AmidstThread.EDT) - public void run() { + public void run() throws LocalMinecraftInterfaceCreationException { checkForUpdatesSilently(); - if (mojangApi.canCreateWorld()) { - displayMainWindow(); + if (preferredLauncherProfile.isPresent()) { + displayMainWindow(launcherProfileRunner.run(preferredLauncherProfile.get())); } else { displayProfileSelectWindow(); } @@ -61,8 +69,8 @@ public void checkForUpdatesSilently() { } @CalledOnlyBy(AmidstThread.EDT) - public void displayMainWindow() { - setMainWindow(mainWindowFactory.create()); + public void displayMainWindow(RunningLauncherProfile runningLauncherProfile) { + setMainWindow(mainWindowFactory.create(runningLauncherProfile)); setProfileSelectWindow(null); } diff --git a/src/main/java/amidst/PerApplicationInjector.java b/src/main/java/amidst/PerApplicationInjector.java index 13f6a8ca1..4abe65a44 100644 --- a/src/main/java/amidst/PerApplicationInjector.java +++ b/src/main/java/amidst/PerApplicationInjector.java @@ -18,13 +18,13 @@ import amidst.gui.main.viewer.ViewerFacade; import amidst.gui.main.viewer.Zoom; import amidst.gui.profileselect.ProfileSelectWindow; -import amidst.mojangapi.MojangApi; +import amidst.mojangapi.LauncherProfileRunner; +import amidst.mojangapi.RunningLauncherProfile; import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException; import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.PlayerInformationCache; import amidst.mojangapi.file.PlayerInformationProvider; -import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; import amidst.mojangapi.world.SeedHistoryLogger; import amidst.mojangapi.world.World; import amidst.mojangapi.world.WorldBuilder; @@ -40,7 +40,7 @@ public class PerApplicationInjector { private final MinecraftInstallation minecraftInstallation; private final Optional preferredLauncherProfile; private final WorldBuilder worldBuilder; - private final MojangApi mojangApi; + private final LauncherProfileRunner launcherProfileRunner; private final BiomeProfileDirectory biomeProfileDirectory; private final ThreadMaster threadMaster; private final LayerBuilder layerBuilder; @@ -51,8 +51,7 @@ public class PerApplicationInjector { @CalledOnlyBy(AmidstThread.EDT) public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData metadata, AmidstSettings settings) - throws DotMinecraftDirectoryNotFoundException, - LocalMinecraftInterfaceCreationException { + throws DotMinecraftDirectoryNotFoundException { this.metadata = metadata; this.settings = settings; this.playerInformationProvider = new PlayerInformationCache(); @@ -62,7 +61,7 @@ public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData m this.preferredLauncherProfile = minecraftInstallation .tryReadLauncherProfile(parameters.minecraftJarFile, parameters.minecraftJsonFile); this.worldBuilder = new WorldBuilder(playerInformationProvider, seedHistoryLogger); - this.mojangApi = MojangApi.from(preferredLauncherProfile, worldBuilder); + this.launcherProfileRunner = new LauncherProfileRunner(worldBuilder); this.biomeProfileDirectory = BiomeProfileDirectory.create(parameters.biomeProfilesDirectory); this.threadMaster = new ThreadMaster(); this.layerBuilder = new LayerBuilder(); @@ -70,7 +69,8 @@ public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData m this.fragmentManager = new FragmentManager(layerBuilder.getConstructors(), layerBuilder.getNumberOfLayers()); this.biomeSelection = new BiomeSelection(); this.application = new Application( - mojangApi, + preferredLauncherProfile, + launcherProfileRunner, this::createNoisyUpdatePrompt, this::createSilentUpdatePrompt, this::createMainWindow, @@ -89,13 +89,13 @@ private UpdatePrompt createSilentUpdatePrompt() { } @CalledOnlyBy(AmidstThread.EDT) - private MainWindow createMainWindow() { + private MainWindow createMainWindow(RunningLauncherProfile runningLauncherProfile) { return new PerMainWindowInjector( application, metadata, settings, minecraftInstallation, - mojangApi, + runningLauncherProfile, biomeProfileDirectory, this::createViewerFacade, threadMaster).getMainWindow(); @@ -108,7 +108,7 @@ private ProfileSelectWindow createProfileSelectWindow() { metadata, threadMaster.getWorkerExecutor(), minecraftInstallation, - mojangApi, + launcherProfileRunner, settings); } diff --git a/src/main/java/amidst/gui/main/MainWindowDialogs.java b/src/main/java/amidst/gui/main/MainWindowDialogs.java index ee5b23c30..c521057d5 100644 --- a/src/main/java/amidst/gui/main/MainWindowDialogs.java +++ b/src/main/java/amidst/gui/main/MainWindowDialogs.java @@ -12,8 +12,7 @@ import amidst.documentation.CalledOnlyBy; import amidst.documentation.NotThreadSafe; import amidst.logging.AmidstMessageBox; -import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.RunningLauncherProfile; import amidst.mojangapi.world.WorldSeed; import amidst.mojangapi.world.WorldType; import amidst.mojangapi.world.export.WorldExporterConfiguration; @@ -22,13 +21,13 @@ @NotThreadSafe public class MainWindowDialogs { private final AmidstSettings settings; - private final MojangApi mojangApi; + private final RunningLauncherProfile runningLauncherProfile; private final JFrame frame; @CalledOnlyBy(AmidstThread.EDT) - public MainWindowDialogs(AmidstSettings settings, MojangApi mojangApi, JFrame frame) { + public MainWindowDialogs(AmidstSettings settings, RunningLauncherProfile runningLauncherProfile, JFrame frame) { this.settings = settings; - this.mojangApi = mojangApi; + this.runningLauncherProfile = runningLauncherProfile; this.frame = frame; } @@ -53,8 +52,7 @@ public File askForSaveGame() { @CalledOnlyBy(AmidstThread.EDT) private JFileChooser createSaveGameFileChooser() { - JFileChooser result = new JFileChooser( - mojangApi.getLauncherProfile().map(LauncherProfile::getSaves).orElse(null)); + JFileChooser result = new JFileChooser(runningLauncherProfile.getLauncherProfile().getSaves()); result.setFileFilter(new LevelFileFilter()); result.setAcceptAllFileFilterUsed(false); result.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); diff --git a/src/main/java/amidst/gui/main/PerMainWindowInjector.java b/src/main/java/amidst/gui/main/PerMainWindowInjector.java index 36c9d5928..1774e3ec9 100644 --- a/src/main/java/amidst/gui/main/PerMainWindowInjector.java +++ b/src/main/java/amidst/gui/main/PerMainWindowInjector.java @@ -18,8 +18,7 @@ import amidst.gui.main.viewer.ViewerFacade; import amidst.gui.seedsearcher.SeedSearcher; import amidst.gui.seedsearcher.SeedSearcherWindow; -import amidst.mojangapi.MojangApi; -import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.RunningLauncherProfile; import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.world.World; import amidst.settings.biomeprofile.BiomeProfileDirectory; @@ -28,15 +27,15 @@ @NotThreadSafe public class PerMainWindowInjector { @CalledOnlyBy(AmidstThread.EDT) - private static String createVersionString(AmidstMetaData metadata, MojangApi mojangApi) { + private static String createVersionString(AmidstMetaData metadata, RunningLauncherProfile runningLauncherProfile) { return new StringBuilder() .append(metadata.getVersion().createLongVersionString()) .append(" - Selected Profile: ") - .append(mojangApi.getLauncherProfile().map(LauncherProfile::getProfileName).orElse("unknown")) + .append(runningLauncherProfile.getLauncherProfile().getProfileName()) .append(" - Minecraft Version ") - .append(mojangApi.getLauncherProfile().map(LauncherProfile::getVersionId).orElse("unknown")) + .append(runningLauncherProfile.getLauncherProfile().getVersionId()) .append(" (recognised: ") - .append(mojangApi.getRecognisedVersionName()) + .append(runningLauncherProfile.getRecognisedVersion().getName()) .append(")") .toString(); } @@ -60,19 +59,19 @@ public PerMainWindowInjector( AmidstMetaData metadata, AmidstSettings settings, MinecraftInstallation minecraftInstallation, - MojangApi mojangApi, + RunningLauncherProfile runningLauncherProfile, BiomeProfileDirectory biomeProfileDirectory, Factory2 viewerFacadeFactory, ThreadMaster threadMaster) { this.viewerFacadeFactory = viewerFacadeFactory; - this.versionString = createVersionString(metadata, mojangApi); + this.versionString = createVersionString(metadata, runningLauncherProfile); this.frame = new JFrame(); this.contentPane = frame.getContentPane(); this.viewerFacadeReference = new AtomicReference<>(); - this.dialogs = new MainWindowDialogs(settings, mojangApi, frame); + this.dialogs = new MainWindowDialogs(settings, runningLauncherProfile, frame); this.worldSwitcher = new WorldSwitcher( minecraftInstallation, - mojangApi, + runningLauncherProfile, this::createViewerFacade, threadMaster, frame, @@ -81,7 +80,10 @@ public PerMainWindowInjector( dialogs, this::getMenuBar); if (FeatureToggles.SEED_SEARCH) { - this.seedSearcher = new SeedSearcher(dialogs, mojangApi, threadMaster.getWorkerExecutor()); + this.seedSearcher = new SeedSearcher( + dialogs, + runningLauncherProfile.createSilentPlayerlessCopy(), + threadMaster.getWorkerExecutor()); this.seedSearcherWindow = new SeedSearcherWindow(metadata, dialogs, worldSwitcher, seedSearcher); } else { this.seedSearcher = null; diff --git a/src/main/java/amidst/gui/main/WorldSwitcher.java b/src/main/java/amidst/gui/main/WorldSwitcher.java index f9909fd11..258788f38 100644 --- a/src/main/java/amidst/gui/main/WorldSwitcher.java +++ b/src/main/java/amidst/gui/main/WorldSwitcher.java @@ -16,7 +16,7 @@ import amidst.gui.main.menu.AmidstMenu; import amidst.gui.main.viewer.ViewerFacade; import amidst.logging.AmidstLogger; -import amidst.mojangapi.MojangApi; +import amidst.mojangapi.RunningLauncherProfile; import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.world.World; @@ -30,7 +30,7 @@ @NotThreadSafe public class WorldSwitcher { private final MinecraftInstallation minecraftInstallation; - private final MojangApi mojangApi; + private final RunningLauncherProfile runningLauncherProfile; private final Factory1 viewerFacadeFactory; private final ThreadMaster threadMaster; private final JFrame frame; @@ -42,7 +42,7 @@ public class WorldSwitcher { @CalledOnlyBy(AmidstThread.EDT) public WorldSwitcher( MinecraftInstallation minecraftInstallation, - MojangApi mojangApi, + RunningLauncherProfile runningLauncherProfile, Factory1 viewerFacadeFactory, ThreadMaster threadMaster, JFrame frame, @@ -51,7 +51,7 @@ public WorldSwitcher( MainWindowDialogs dialogs, Supplier menuBarSupplier) { this.minecraftInstallation = minecraftInstallation; - this.mojangApi = mojangApi; + this.runningLauncherProfile = runningLauncherProfile; this.viewerFacadeFactory = viewerFacadeFactory; this.threadMaster = threadMaster; this.frame = frame; @@ -64,8 +64,8 @@ public WorldSwitcher( @CalledOnlyBy(AmidstThread.EDT) public void displayWorld(WorldSeed worldSeed, WorldType worldType) { try { - setWorld(mojangApi.createWorldFromSeed(worldSeed, worldType)); - } catch (IllegalStateException | MinecraftInterfaceException e) { + setWorld(runningLauncherProfile.createWorldFromSeed(worldSeed, worldType)); + } catch (MinecraftInterfaceException e) { AmidstLogger.warn(e); dialogs.displayError(e); } @@ -74,8 +74,8 @@ public void displayWorld(WorldSeed worldSeed, WorldType worldType) { @CalledOnlyBy(AmidstThread.EDT) public void displayWorld(File file) { try { - setWorld(mojangApi.createWorldFromSaveGame(minecraftInstallation.newSaveGame(file))); - } catch (IllegalStateException | MinecraftInterfaceException | IOException | FormatException e) { + setWorld(runningLauncherProfile.createWorldFromSaveGame(minecraftInstallation.newSaveGame(file))); + } catch (MinecraftInterfaceException | IOException | FormatException e) { AmidstLogger.warn(e); dialogs.displayError(e); } diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index 2d072b67d..8c0500888 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.util.Locale; +import java.util.Optional; import java.util.regex.Pattern; import amidst.Application; @@ -10,7 +11,8 @@ import amidst.documentation.NotThreadSafe; import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; -import amidst.mojangapi.MojangApi; +import amidst.mojangapi.LauncherProfileRunner; +import amidst.mojangapi.RunningLauncherProfile; import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.UnresolvedLauncherProfile; import amidst.mojangapi.file.VersionListProvider; @@ -22,11 +24,11 @@ public class LocalProfileComponent extends ProfileComponent { private final Application application; private final WorkerExecutor workerExecutor; - private final MojangApi mojangApi; + private final LauncherProfileRunner launcherProfileRunner; private final UnresolvedLauncherProfile unresolvedProfile; - private volatile boolean isSearching = false; - private volatile boolean failedSearching = false; + private volatile boolean isResolving = false; + private volatile boolean failedResolving = false; private volatile boolean isLoading = false; private volatile boolean failedLoading = false; private volatile LauncherProfile resolvedProfile; @@ -35,25 +37,25 @@ public class LocalProfileComponent extends ProfileComponent { public LocalProfileComponent( Application application, WorkerExecutor workerExecutor, - MojangApi mojangApi, + LauncherProfileRunner launcherProfileRunner, UnresolvedLauncherProfile unresolvedProfile) { this.application = application; - this.mojangApi = mojangApi; this.workerExecutor = workerExecutor; + this.launcherProfileRunner = launcherProfileRunner; this.unresolvedProfile = unresolvedProfile; initComponent(); - initDirectoriesLater(); + resolveLater(); } @CalledOnlyBy(AmidstThread.EDT) - private void initDirectoriesLater() { - isSearching = true; + private void resolveLater() { + isResolving = true; repaintComponent(); - workerExecutor.run(this::tryFind, this::findFinished); + workerExecutor.run(this::tryResolve, this::resolveFinished); } @CalledOnlyBy(AmidstThread.WORKER) - private boolean tryFind() { + private boolean tryResolve() { try { resolvedProfile = unresolvedProfile.resolve(VersionListProvider.getRemoteOrLocalVersionList()); return true; @@ -64,9 +66,9 @@ private boolean tryFind() { } @CalledOnlyBy(AmidstThread.EDT) - private void findFinished(boolean isSuccessful) { - isSearching = false; - failedSearching = !isSuccessful; + private void resolveFinished(boolean isSuccessful) { + isResolving = false; + failedResolving = !isSuccessful; repaintComponent(); } @@ -79,7 +81,7 @@ public void load() { } @CalledOnlyBy(AmidstThread.WORKER) - private boolean tryLoad() { + private Optional tryLoad() { // TODO: Replace with proper handling for modded profiles. try { AmidstLogger.info( @@ -93,38 +95,37 @@ private boolean tryLoad() { AmidstMessageBox.displayError( "Error", "Amidst does not support modded Minecraft profiles! Please select or create an unmodded Minecraft profile via the Minecraft Launcher."); - return false; + return Optional.empty(); } - mojangApi.setLauncherProfile(resolvedProfile); - return true; + return Optional.of(launcherProfileRunner.run(resolvedProfile)); } catch (LocalMinecraftInterfaceCreationException e) { AmidstLogger.error(e); AmidstMessageBox.displayError("Error", e); - return false; + return Optional.empty(); } } @CalledOnlyBy(AmidstThread.EDT) - private void loadFinished(boolean isSuccessful) { + private void loadFinished(Optional runningLauncherProfile) { isLoading = false; - failedLoading = !isSuccessful; + failedLoading = !runningLauncherProfile.isPresent(); repaintComponent(); - if (isSuccessful) { - application.displayMainWindow(); + if (runningLauncherProfile.isPresent()) { + application.displayMainWindow(runningLauncherProfile.get()); } } @CalledOnlyBy(AmidstThread.EDT) @Override - protected boolean isSearching() { - return isSearching; + protected boolean isResolving() { + return isResolving; } @CalledOnlyBy(AmidstThread.EDT) @Override - protected boolean failedSearching() { - return failedSearching; + protected boolean failedResolving() { + return failedResolving; } @CalledOnlyBy(AmidstThread.EDT) @@ -142,7 +143,7 @@ protected boolean failedLoading() { @CalledOnlyBy(AmidstThread.EDT) @Override protected boolean isReadyToLoad() { - return !isSearching && !failedSearching; + return !isResolving && !failedResolving; } @CalledOnlyBy(AmidstThread.EDT) diff --git a/src/main/java/amidst/gui/profileselect/ProfileComponent.java b/src/main/java/amidst/gui/profileselect/ProfileComponent.java index 1e3df1998..e5e62717d 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/ProfileComponent.java @@ -167,10 +167,10 @@ private String getLoadingStatus() { return "failed loading"; } else if (isLoading()) { return "loading"; - } else if (failedSearching()) { + } else if (failedResolving()) { return "not found"; - } else if (isSearching()) { - return "searching"; + } else if (isResolving()) { + return "resolving"; } else { return "found"; } @@ -182,9 +182,9 @@ private BufferedImage getIcon() { return INACTIVE_ICON; } else if (isLoading()) { return LOADING_ICON; - } else if (failedSearching()) { + } else if (failedResolving()) { return INACTIVE_ICON; - } else if (isSearching()) { + } else if (isResolving()) { return INACTIVE_ICON; } else { return ACTIVE_ICON; @@ -197,7 +197,7 @@ private Color getBackgroundColor() { return FAILED_BG_COLOR; } else if (isLoading()) { return LOADING_BG_COLOR; - } else if (failedSearching()) { + } else if (failedResolving()) { return FAILED_BG_COLOR; } else if (isSelected) { return SELECTED_BG_COLOR; @@ -210,10 +210,10 @@ private Color getBackgroundColor() { protected abstract void load(); @CalledOnlyBy(AmidstThread.EDT) - protected abstract boolean isSearching(); + protected abstract boolean isResolving(); @CalledOnlyBy(AmidstThread.EDT) - protected abstract boolean failedSearching(); + protected abstract boolean failedResolving(); @CalledOnlyBy(AmidstThread.EDT) protected abstract boolean isLoading(); diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index 8254a5a5b..ad5bd28d9 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -20,7 +20,7 @@ import amidst.documentation.NotThreadSafe; import amidst.logging.AmidstLogger; import amidst.logging.AmidstMessageBox; -import amidst.mojangapi.MojangApi; +import amidst.mojangapi.LauncherProfileRunner; import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.UnresolvedLauncherProfile; import amidst.parsing.FormatException; @@ -35,7 +35,7 @@ public class ProfileSelectWindow { private final AmidstMetaData metadata; private final WorkerExecutor workerExecutor; private final MinecraftInstallation minecraftInstallation; - private final MojangApi mojangApi; + private final LauncherProfileRunner launcherProfileRunner; private final AmidstSettings settings; private final JFrame frame; @@ -47,13 +47,13 @@ public ProfileSelectWindow( AmidstMetaData metadata, WorkerExecutor workerExecutor, MinecraftInstallation minecraftInstallation, - MojangApi mojangApi, + LauncherProfileRunner launcherProfileRunner, AmidstSettings settings) { this.application = application; this.metadata = metadata; this.workerExecutor = workerExecutor; this.minecraftInstallation = minecraftInstallation; - this.mojangApi = mojangApi; + this.launcherProfileRunner = launcherProfileRunner; this.settings = settings; this.profileSelectPanel = new ProfileSelectPanel(settings.lastProfile, "Scanning..."); this.frame = createFrame(); @@ -143,7 +143,8 @@ private void createProfileComponentsIfNecessary(List @CalledOnlyBy(AmidstThread.EDT) private void createProfileComponents(List launcherProfiles) { for (UnresolvedLauncherProfile profile : launcherProfiles) { - profileSelectPanel.addProfile(new LocalProfileComponent(application, workerExecutor, mojangApi, profile)); + profileSelectPanel + .addProfile(new LocalProfileComponent(application, workerExecutor, launcherProfileRunner, profile)); } } diff --git a/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java b/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java index 917ebddb6..4f7b377ed 100644 --- a/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java +++ b/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java @@ -7,7 +7,7 @@ import amidst.documentation.NotThreadSafe; import amidst.gui.main.MainWindowDialogs; import amidst.logging.AmidstLogger; -import amidst.mojangapi.MojangApi; +import amidst.mojangapi.RunningLauncherProfile; import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; import amidst.mojangapi.world.World; import amidst.mojangapi.world.WorldSeed; @@ -18,16 +18,19 @@ @NotThreadSafe public class SeedSearcher { private final MainWindowDialogs dialogs; - private final MojangApi mojangApi; + private final RunningLauncherProfile runningLauncherProfile; private final WorkerExecutor workerExecutor; private volatile boolean isSearching = false; private volatile boolean isStopRequested = false; @CalledOnlyBy(AmidstThread.EDT) - public SeedSearcher(MainWindowDialogs dialogs, MojangApi mojangApi, WorkerExecutor workerExecutor) { + public SeedSearcher( + MainWindowDialogs dialogs, + RunningLauncherProfile runningLauncherProfile, + WorkerExecutor workerExecutor) { this.dialogs = dialogs; - this.mojangApi = mojangApi.createSilentPlayerlessCopy(); + this.runningLauncherProfile = runningLauncherProfile; this.workerExecutor = workerExecutor; } @@ -89,7 +92,7 @@ private void doSearch(ProgressReporter reporter, SeedSearcherConfigur private void doSearchOne(ProgressReporter reporter, SeedSearcherConfiguration configuration) throws MinecraftInterfaceException { while (!isStopRequested) { - World world = mojangApi.createWorldFromSeed(WorldSeed.random(), configuration.getWorldType()); + World world = runningLauncherProfile.createWorldFromSeed(WorldSeed.random(), configuration.getWorldType()); if (configuration.getWorldFilter().isValid(world)) { reporter.report(world.getWorldSeed()); break; diff --git a/src/main/java/amidst/mojangapi/LauncherProfileRunner.java b/src/main/java/amidst/mojangapi/LauncherProfileRunner.java new file mode 100644 index 000000000..43d6039bb --- /dev/null +++ b/src/main/java/amidst/mojangapi/LauncherProfileRunner.java @@ -0,0 +1,19 @@ +package amidst.mojangapi; + +import amidst.documentation.Immutable; +import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; +import amidst.mojangapi.world.WorldBuilder; + +@Immutable +public class LauncherProfileRunner { + private final WorldBuilder worldBuilder; + + public LauncherProfileRunner(WorldBuilder worldBuilder) { + this.worldBuilder = worldBuilder; + } + + public RunningLauncherProfile run(LauncherProfile launcherProfile) throws LocalMinecraftInterfaceCreationException { + return RunningLauncherProfile.from(worldBuilder, launcherProfile); + } +} diff --git a/src/main/java/amidst/mojangapi/MojangApi.java b/src/main/java/amidst/mojangapi/MojangApi.java deleted file mode 100644 index 85efd8e7a..000000000 --- a/src/main/java/amidst/mojangapi/MojangApi.java +++ /dev/null @@ -1,117 +0,0 @@ -package amidst.mojangapi; - -import java.io.IOException; -import java.util.Optional; - -import amidst.documentation.ThreadSafe; -import amidst.logging.AmidstLogger; -import amidst.mojangapi.file.LauncherProfile; -import amidst.mojangapi.file.SaveGame; -import amidst.mojangapi.minecraftinterface.MinecraftInterface; -import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; -import amidst.mojangapi.minecraftinterface.RecognisedVersion; -import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; -import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; -import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; -import amidst.mojangapi.world.World; -import amidst.mojangapi.world.WorldBuilder; -import amidst.mojangapi.world.WorldSeed; -import amidst.mojangapi.world.WorldType; - -@ThreadSafe -public class MojangApi { - public static MojangApi from(Optional preferredLauncherProfile, WorldBuilder worldBuilder) - throws LocalMinecraftInterfaceCreationException { - MojangApi result = new MojangApi(worldBuilder); - result.setLauncherProfile(preferredLauncherProfile.orElse(null)); - return result; - } - - private final WorldBuilder worldBuilder; - - private volatile MinecraftInterface minecraftInterface; - private volatile LauncherProfile launcherProfile; - - public MojangApi(WorldBuilder worldBuilder) { - this.worldBuilder = worldBuilder; - } - - public Optional getLauncherProfile() { - return Optional.ofNullable(launcherProfile); - } - - public void setLauncherProfile(LauncherProfile launcherProfile) throws LocalMinecraftInterfaceCreationException { - this.launcherProfile = launcherProfile; - if (launcherProfile != null) { - AmidstLogger.info( - "using launcher profile. version id: '" + launcherProfile.getVersionId() + "', profile name: '" - + launcherProfile.getProfileName() + "', jar file: '" + launcherProfile.getJar() + "'"); - try { - this.minecraftInterface = LocalMinecraftInterface - .create(DefaultClassTranslator.INSTANCE.get(), launcherProfile); - } catch (LocalMinecraftInterfaceCreationException e) { - this.minecraftInterface = null; - throw e; - } - } else { - this.minecraftInterface = null; - } - } - - public MojangApi createSilentPlayerlessCopy() { - MojangApi result = new MojangApi(WorldBuilder.createSilentPlayerless()); - try { - result.setLauncherProfile(launcherProfile); - } catch (LocalMinecraftInterfaceCreationException e) { - // This will not happen normally, because we already successfully - // created the same LocalMinecraftInterface once before. - throw new RuntimeException("exception while duplicating the MojangApi", e); - } - return result; - } - - public boolean canCreateWorld() { - return minecraftInterface != null; - } - - /** - * Due to the limitation of the minecraft interface, you can only work with - * one world at a time. Creating a new world will break all previously - * created world objects. - */ - public World createWorldFromSeed(WorldSeed worldSeed, WorldType worldType) - throws IllegalStateException, - MinecraftInterfaceException { - MinecraftInterface minecraftInterface = this.minecraftInterface; - if (minecraftInterface != null) { - return worldBuilder.fromSeed(minecraftInterface, worldSeed, worldType); - } else { - throw new IllegalStateException("cannot create a world without a minecraft interface"); - } - } - - /** - * Due to the limitation of the minecraft interface, you can only work with - * one world at a time. Creating a new world will break all previously - * created world objects. - */ - public World createWorldFromSaveGame(SaveGame saveGame) - throws IllegalStateException, - IOException, - MinecraftInterfaceException { - MinecraftInterface minecraftInterface = this.minecraftInterface; - if (minecraftInterface != null) { - return worldBuilder.fromSaveGame(minecraftInterface, saveGame); - } else { - throw new IllegalStateException("cannot create a world without a minecraft interface"); - } - } - - public String getRecognisedVersionName() { - return Optional - .ofNullable(this.minecraftInterface) - .map(MinecraftInterface::getRecognisedVersion) - .map(RecognisedVersion::getName) - .orElse(RecognisedVersion.UNKNOWN.getName()); - } -} diff --git a/src/main/java/amidst/mojangapi/RunningLauncherProfile.java b/src/main/java/amidst/mojangapi/RunningLauncherProfile.java new file mode 100644 index 000000000..e4023d146 --- /dev/null +++ b/src/main/java/amidst/mojangapi/RunningLauncherProfile.java @@ -0,0 +1,81 @@ +package amidst.mojangapi; + +import java.io.IOException; + +import amidst.documentation.ThreadSafe; +import amidst.logging.AmidstLogger; +import amidst.mojangapi.file.LauncherProfile; +import amidst.mojangapi.file.SaveGame; +import amidst.mojangapi.minecraftinterface.MinecraftInterface; +import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException; +import amidst.mojangapi.minecraftinterface.RecognisedVersion; +import amidst.mojangapi.minecraftinterface.local.DefaultClassTranslator; +import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterface; +import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException; +import amidst.mojangapi.world.World; +import amidst.mojangapi.world.WorldBuilder; +import amidst.mojangapi.world.WorldSeed; +import amidst.mojangapi.world.WorldType; + +@ThreadSafe +public class RunningLauncherProfile { + public static RunningLauncherProfile from(WorldBuilder worldBuilder, LauncherProfile launcherProfile) + throws LocalMinecraftInterfaceCreationException { + AmidstLogger.info( + "using launcher profile. version id: '" + launcherProfile.getVersionId() + "', profile name: '" + + launcherProfile.getProfileName() + "', jar file: '" + launcherProfile.getJar() + "'"); + return new RunningLauncherProfile( + worldBuilder, + launcherProfile, + LocalMinecraftInterface.create(DefaultClassTranslator.INSTANCE.get(), launcherProfile)); + } + + private final WorldBuilder worldBuilder; + private final LauncherProfile launcherProfile; + private final MinecraftInterface minecraftInterface; + + public RunningLauncherProfile( + WorldBuilder worldBuilder, + LauncherProfile launcherProfile, + MinecraftInterface minecraftInterface) { + this.worldBuilder = worldBuilder; + this.launcherProfile = launcherProfile; + this.minecraftInterface = minecraftInterface; + } + + public LauncherProfile getLauncherProfile() { + return launcherProfile; + } + + public RecognisedVersion getRecognisedVersion() { + return minecraftInterface.getRecognisedVersion(); + } + + public RunningLauncherProfile createSilentPlayerlessCopy() { + try { + return RunningLauncherProfile.from(WorldBuilder.createSilentPlayerless(), launcherProfile); + } catch (LocalMinecraftInterfaceCreationException e) { + // This will not happen normally, because we already successfully + // created the same LocalMinecraftInterface once before. + throw new RuntimeException("exception while duplicating the RunningLauncherProfile", e); + } + } + + /** + * Due to the limitation of the minecraft interface, you can only work with + * one world at a time. Creating a new world will break all previously + * created world objects. + */ + public World createWorldFromSeed(WorldSeed worldSeed, WorldType worldType) throws MinecraftInterfaceException { + return worldBuilder.fromSeed(minecraftInterface, worldSeed, worldType); + } + + /** + * Due to the limitation of the minecraft interface, you can only work with + * one world at a time. Creating a new world will break all previously + * created world objects. + */ + public World createWorldFromSaveGame(SaveGame saveGame) throws IOException, MinecraftInterfaceException { + return worldBuilder.fromSaveGame(minecraftInterface, saveGame); + } +} From eed56c195b18453e9b3bfe2254b95ae17301d222 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Fri, 2 Jun 2017 01:39:48 +0200 Subject: [PATCH 43/48] actually used VersionListProvider --- .../java/amidst/PerApplicationInjector.java | 11 ++- .../profileselect/LocalProfileComponent.java | 24 +++--- .../gui/profileselect/ProfileComponent.java | 3 + .../gui/profileselect/ProfileSelectPanel.java | 7 ++ .../profileselect/ProfileSelectWindow.java | 15 +++- .../amidst/mojangapi/file/VersionList.java | 12 --- .../mojangapi/file/VersionListProvider.java | 74 ++++++++++++------- .../file/service/VersionListService.java | 29 -------- 8 files changed, 94 insertions(+), 81 deletions(-) diff --git a/src/main/java/amidst/PerApplicationInjector.java b/src/main/java/amidst/PerApplicationInjector.java index 4abe65a44..e40278be7 100644 --- a/src/main/java/amidst/PerApplicationInjector.java +++ b/src/main/java/amidst/PerApplicationInjector.java @@ -1,5 +1,6 @@ package amidst; +import java.io.IOException; import java.util.Optional; import amidst.documentation.AmidstThread; @@ -25,9 +26,11 @@ import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.PlayerInformationCache; import amidst.mojangapi.file.PlayerInformationProvider; +import amidst.mojangapi.file.VersionListProvider; import amidst.mojangapi.world.SeedHistoryLogger; import amidst.mojangapi.world.World; import amidst.mojangapi.world.WorldBuilder; +import amidst.parsing.FormatException; import amidst.settings.biomeprofile.BiomeProfileDirectory; import amidst.threading.ThreadMaster; @@ -43,6 +46,7 @@ public class PerApplicationInjector { private final LauncherProfileRunner launcherProfileRunner; private final BiomeProfileDirectory biomeProfileDirectory; private final ThreadMaster threadMaster; + private final VersionListProvider versionListProvider; private final LayerBuilder layerBuilder; private final Zoom zoom; private final FragmentManager fragmentManager; @@ -51,7 +55,9 @@ public class PerApplicationInjector { @CalledOnlyBy(AmidstThread.EDT) public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData metadata, AmidstSettings settings) - throws DotMinecraftDirectoryNotFoundException { + throws DotMinecraftDirectoryNotFoundException, + FormatException, + IOException { this.metadata = metadata; this.settings = settings; this.playerInformationProvider = new PlayerInformationCache(); @@ -64,6 +70,8 @@ public PerApplicationInjector(CommandLineParameters parameters, AmidstMetaData m this.launcherProfileRunner = new LauncherProfileRunner(worldBuilder); this.biomeProfileDirectory = BiomeProfileDirectory.create(parameters.biomeProfilesDirectory); this.threadMaster = new ThreadMaster(); + this.versionListProvider = VersionListProvider + .createLocalAndStartDownloadingRemote(threadMaster.getWorkerExecutor()); this.layerBuilder = new LayerBuilder(); this.zoom = new Zoom(settings.maxZoom); this.fragmentManager = new FragmentManager(layerBuilder.getConstructors(), layerBuilder.getNumberOfLayers()); @@ -107,6 +115,7 @@ private ProfileSelectWindow createProfileSelectWindow() { application, metadata, threadMaster.getWorkerExecutor(), + versionListProvider, minecraftInstallation, launcherProfileRunner, settings); diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index 8c0500888..59aa24a62 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -24,6 +24,7 @@ public class LocalProfileComponent extends ProfileComponent { private final Application application; private final WorkerExecutor workerExecutor; + private final VersionListProvider versionListProvider; private final LauncherProfileRunner launcherProfileRunner; private final UnresolvedLauncherProfile unresolvedProfile; @@ -37,38 +38,41 @@ public class LocalProfileComponent extends ProfileComponent { public LocalProfileComponent( Application application, WorkerExecutor workerExecutor, + VersionListProvider versionListProvider, LauncherProfileRunner launcherProfileRunner, UnresolvedLauncherProfile unresolvedProfile) { this.application = application; this.workerExecutor = workerExecutor; + this.versionListProvider = versionListProvider; this.launcherProfileRunner = launcherProfileRunner; this.unresolvedProfile = unresolvedProfile; initComponent(); - resolveLater(); } @CalledOnlyBy(AmidstThread.EDT) - private void resolveLater() { + @Override + public void resolveLater() { + resolvedProfile = null; isResolving = true; repaintComponent(); workerExecutor.run(this::tryResolve, this::resolveFinished); } @CalledOnlyBy(AmidstThread.WORKER) - private boolean tryResolve() { + private Optional tryResolve() { try { - resolvedProfile = unresolvedProfile.resolve(VersionListProvider.getRemoteOrLocalVersionList()); - return true; + return Optional.of(unresolvedProfile.resolve(versionListProvider.getRemoteOrElseLocal())); } catch (FormatException | IOException e) { AmidstLogger.warn(e); - return false; + return Optional.empty(); } } @CalledOnlyBy(AmidstThread.EDT) - private void resolveFinished(boolean isSuccessful) { + private void resolveFinished(Optional launcherProfile) { isResolving = false; - failedResolving = !isSuccessful; + failedResolving = !launcherProfile.isPresent(); + resolvedProfile = launcherProfile.orElse(null); repaintComponent(); } @@ -143,7 +147,7 @@ protected boolean failedLoading() { @CalledOnlyBy(AmidstThread.EDT) @Override protected boolean isReadyToLoad() { - return !isResolving && !failedResolving; + return resolvedProfile != null; } @CalledOnlyBy(AmidstThread.EDT) @@ -155,7 +159,7 @@ protected String getProfileName() { @CalledOnlyBy(AmidstThread.EDT) @Override protected String getVersionName() { - if (isReadyToLoad()) { + if (resolvedProfile != null) { return resolvedProfile.getVersionId(); } else { return ""; diff --git a/src/main/java/amidst/gui/profileselect/ProfileComponent.java b/src/main/java/amidst/gui/profileselect/ProfileComponent.java index e5e62717d..3b0d03337 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/ProfileComponent.java @@ -229,4 +229,7 @@ private Color getBackgroundColor() { @CalledOnlyBy(AmidstThread.EDT) protected abstract String getVersionName(); + + @CalledOnlyBy(AmidstThread.EDT) + public abstract void resolveLater(); } diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectPanel.java b/src/main/java/amidst/gui/profileselect/ProfileSelectPanel.java index 1e3a70e48..cbe50626b 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectPanel.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectPanel.java @@ -261,4 +261,11 @@ private boolean isLoading() { } return false; } + + @CalledOnlyBy(AmidstThread.EDT) + public void resolveAllLater() { + if (!isLoading()) { + profileComponents.forEach(ProfileComponent::resolveLater); + } + } } diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index ad5bd28d9..99c8ba562 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -23,6 +23,7 @@ import amidst.mojangapi.LauncherProfileRunner; import amidst.mojangapi.file.MinecraftInstallation; import amidst.mojangapi.file.UnresolvedLauncherProfile; +import amidst.mojangapi.file.VersionListProvider; import amidst.parsing.FormatException; import amidst.threading.WorkerExecutor; import net.miginfocom.swing.MigLayout; @@ -34,6 +35,7 @@ public class ProfileSelectWindow { private final Application application; private final AmidstMetaData metadata; private final WorkerExecutor workerExecutor; + private final VersionListProvider versionListProvider; private final MinecraftInstallation minecraftInstallation; private final LauncherProfileRunner launcherProfileRunner; private final AmidstSettings settings; @@ -46,12 +48,14 @@ public ProfileSelectWindow( Application application, AmidstMetaData metadata, WorkerExecutor workerExecutor, + VersionListProvider versionListProvider, MinecraftInstallation minecraftInstallation, LauncherProfileRunner launcherProfileRunner, AmidstSettings settings) { this.application = application; this.metadata = metadata; this.workerExecutor = workerExecutor; + this.versionListProvider = versionListProvider; this.minecraftInstallation = minecraftInstallation; this.launcherProfileRunner = launcherProfileRunner; this.settings = settings; @@ -137,14 +141,21 @@ private void createProfileComponentsIfNecessary(List profileSelectPanel.setEmptyMessage("No profiles found"); } else { createProfileComponents(launcherProfiles); + versionListProvider.onDownloadRemoteFinished(profileSelectPanel::resolveAllLater); + profileSelectPanel.resolveAllLater(); } } @CalledOnlyBy(AmidstThread.EDT) private void createProfileComponents(List launcherProfiles) { for (UnresolvedLauncherProfile profile : launcherProfiles) { - profileSelectPanel - .addProfile(new LocalProfileComponent(application, workerExecutor, launcherProfileRunner, profile)); + profileSelectPanel.addProfile( + new LocalProfileComponent( + application, + workerExecutor, + versionListProvider, + launcherProfileRunner, + profile)); } } diff --git a/src/main/java/amidst/mojangapi/file/VersionList.java b/src/main/java/amidst/mojangapi/file/VersionList.java index 82c806f53..3bc48bf80 100644 --- a/src/main/java/amidst/mojangapi/file/VersionList.java +++ b/src/main/java/amidst/mojangapi/file/VersionList.java @@ -1,6 +1,5 @@ package amidst.mojangapi.file; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; import java.util.stream.Collectors; @@ -11,17 +10,6 @@ @Immutable public class VersionList { - @Deprecated - public static VersionList newRemoteOrLocalVersionList() throws FileNotFoundException { - return new VersionList( - new VersionListService() - .readRemoteOrLocalVersionList() - .getVersions() - .stream() - .map(v -> new Version(v)) - .collect(Collectors.toList())); - } - public static VersionList newRemoteVersionList() throws FormatException, IOException { return new VersionList( new VersionListService() diff --git a/src/main/java/amidst/mojangapi/file/VersionListProvider.java b/src/main/java/amidst/mojangapi/file/VersionListProvider.java index 17383ea64..2f5ea4073 100644 --- a/src/main/java/amidst/mojangapi/file/VersionListProvider.java +++ b/src/main/java/amidst/mojangapi/file/VersionListProvider.java @@ -1,51 +1,71 @@ package amidst.mojangapi.file; -import java.io.FileNotFoundException; import java.io.IOException; +import java.util.concurrent.ConcurrentLinkedQueue; import amidst.documentation.AmidstThread; +import amidst.documentation.CalledByAny; import amidst.documentation.CalledOnlyBy; -import amidst.documentation.NotNull; -import amidst.documentation.ThreadSafe; +import amidst.documentation.NotThreadSafe; +import amidst.logging.AmidstLogger; import amidst.parsing.FormatException; +import amidst.threading.WorkerExecutor; -@ThreadSafe +/** + * This class is responsible to provide the version list. It will instantly + * provide the local version list, but try to download the remote version list + * in the background. Listeners can be registered to be informed about a + * successful download. + */ +@NotThreadSafe public class VersionListProvider { - public static VersionListProvider create() throws FormatException, IOException { - return new VersionListProvider(VersionList.newLocalVersionList()); - } - - @NotNull - @Deprecated - public static VersionList getRemoteOrLocalVersionList() throws FileNotFoundException { - VersionList versionList = VersionListProvider.remoteOrLocalVersionList; - if (versionList == null) { - synchronized (VersionListProvider.class) { - versionList = VersionListProvider.remoteOrLocalVersionList; - if (versionList == null) { - versionList = VersionList.newRemoteOrLocalVersionList(); - VersionListProvider.remoteOrLocalVersionList = versionList; - } - } - } - return versionList; + @CalledOnlyBy(AmidstThread.EDT) + public static VersionListProvider createLocalAndStartDownloadingRemote(WorkerExecutor workerExecutor) + throws FormatException, + IOException { + VersionListProvider versionListProvider = new VersionListProvider(VersionList.newLocalVersionList()); + versionListProvider.startDownloading(workerExecutor); + return versionListProvider; } - @Deprecated - private static volatile VersionList remoteOrLocalVersionList; - + private final ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue<>(); private final VersionList local; private volatile VersionList remote; + @CalledOnlyBy(AmidstThread.EDT) public VersionListProvider(VersionList local) { this.local = local; } + @CalledOnlyBy(AmidstThread.EDT) + public void onDownloadRemoteFinished(Runnable listener) { + listeners.offer(listener); + } + + @CalledOnlyBy(AmidstThread.EDT) + private void startDownloading(WorkerExecutor workerExecutor) { + workerExecutor.run(this::doDownload, this::finishedDownload, this::downloadFailed); + } + @CalledOnlyBy(AmidstThread.WORKER) - public void startDownload() throws FormatException, IOException { - remote = VersionList.newRemoteVersionList(); + private VersionList doDownload() throws FormatException, IOException { + AmidstLogger.info("Starting to download remote version list."); + return VersionList.newRemoteVersionList(); + } + + @CalledOnlyBy(AmidstThread.EDT) + private void finishedDownload(VersionList remote) { + AmidstLogger.info("Successfully loaded remote version list."); + this.remote = remote; + listeners.forEach(Runnable::run); + } + + @CalledOnlyBy(AmidstThread.EDT) + private void downloadFailed(Exception e) { + AmidstLogger.warn(e, "Error while downloading remote version list."); } + @CalledByAny public VersionList getRemoteOrElseLocal() { VersionList remote = this.remote; if (remote != null) { diff --git a/src/main/java/amidst/mojangapi/file/service/VersionListService.java b/src/main/java/amidst/mojangapi/file/service/VersionListService.java index ace594442..93be46fe4 100644 --- a/src/main/java/amidst/mojangapi/file/service/VersionListService.java +++ b/src/main/java/amidst/mojangapi/file/service/VersionListService.java @@ -1,13 +1,11 @@ package amidst.mojangapi.file.service; -import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import amidst.ResourceLoader; import amidst.documentation.Immutable; import amidst.documentation.NotNull; -import amidst.logging.AmidstLogger; import amidst.mojangapi.file.json.versionlist.VersionListJson; import amidst.parsing.FormatException; import amidst.parsing.json.JsonReader; @@ -18,33 +16,6 @@ public class VersionListService { private static final URL LOCAL_VERSION_LIST = ResourceLoader .getResourceURL("/amidst/mojangapi/version_manifest.json"); - @NotNull - public VersionListJson readRemoteOrLocalVersionList() throws FileNotFoundException { - AmidstLogger.info("Beginning latest version list load."); - AmidstLogger.info("Attempting to download remote version list..."); - try { - VersionListJson remote = readRemoteVersionList(); - AmidstLogger.info("Successfully loaded version list. URL: " + REMOTE_VERSION_LIST); - return remote; - } catch (FormatException | IOException e) { - AmidstLogger.warn("Unable to read remote version list."); - AmidstLogger.warn(e); - AmidstLogger.warn("Aborting version list load. URL: " + REMOTE_VERSION_LIST); - } - AmidstLogger.info("Attempting to load local version list..."); - try { - VersionListJson local = readLocalVersionListFromResource(); - AmidstLogger.info("Successfully loaded version list. URL: " + LOCAL_VERSION_LIST); - return local; - } catch (FormatException | IOException e) { - AmidstLogger.warn("Unable to read local version list."); - AmidstLogger.warn(e); - AmidstLogger.warn("Aborting version list load. URL: " + LOCAL_VERSION_LIST); - } - AmidstLogger.warn("Failed to load both remote and local version list."); - throw new FileNotFoundException("unable to read version list"); - } - @NotNull public VersionListJson readRemoteVersionList() throws FormatException, IOException { return JsonReader.readLocation(REMOTE_VERSION_LIST, VersionListJson.class); From e8d41c2c35c4970093280967bc0f85d75b9488c0 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Fri, 2 Jun 2017 12:57:01 +0200 Subject: [PATCH 44/48] added dispose mechanism to World to be able to restrict the simultaneous MinecraftInterface usages --- .../java/amidst/gui/main/WorldSwitcher.java | 31 +++++++++-------- .../amidst/gui/main/viewer/ViewerFacade.java | 1 + .../amidst/gui/seedsearcher/SeedSearcher.java | 5 ++- .../mojangapi/RunningLauncherProfile.java | 34 ++++++++++++++++--- .../java/amidst/mojangapi/world/World.java | 14 ++++++++ .../amidst/mojangapi/world/WorldBuilder.java | 14 ++++++-- .../mojangapi/mocking/FakeWorldBuilder.java | 11 ++++-- 7 files changed, 85 insertions(+), 25 deletions(-) diff --git a/src/main/java/amidst/gui/main/WorldSwitcher.java b/src/main/java/amidst/gui/main/WorldSwitcher.java index 258788f38..485db0a0f 100644 --- a/src/main/java/amidst/gui/main/WorldSwitcher.java +++ b/src/main/java/amidst/gui/main/WorldSwitcher.java @@ -64,8 +64,9 @@ public WorldSwitcher( @CalledOnlyBy(AmidstThread.EDT) public void displayWorld(WorldSeed worldSeed, WorldType worldType) { try { + clearViewerFacade(); setWorld(runningLauncherProfile.createWorldFromSeed(worldSeed, worldType)); - } catch (MinecraftInterfaceException e) { + } catch (IllegalStateException | MinecraftInterfaceException e) { AmidstLogger.warn(e); dialogs.displayError(e); } @@ -74,16 +75,28 @@ public void displayWorld(WorldSeed worldSeed, WorldType worldType) { @CalledOnlyBy(AmidstThread.EDT) public void displayWorld(File file) { try { + clearViewerFacade(); setWorld(runningLauncherProfile.createWorldFromSaveGame(minecraftInstallation.newSaveGame(file))); - } catch (MinecraftInterfaceException | IOException | FormatException e) { + } catch (IllegalStateException | MinecraftInterfaceException | IOException | FormatException e) { AmidstLogger.warn(e); dialogs.displayError(e); } } + @CalledOnlyBy(AmidstThread.EDT) + private void clearViewerFacade() { + threadMaster.clearOnRepaintTick(); + threadMaster.clearOnFragmentLoadTick(); + ViewerFacade viewerFacade = viewerFacadeReference.getAndSet(null); + if (viewerFacade != null) { + contentPane.remove(viewerFacade.getComponent()); + viewerFacade.dispose(); + } + menuBarSupplier.get().clear(); + } + @CalledOnlyBy(AmidstThread.EDT) private void setWorld(World world) { - clearViewerFacade(); if (decideWorldPlayerType(world.getMovablePlayerList())) { setViewerFacade(viewerFacadeFactory.create(world)); } else { @@ -118,18 +131,6 @@ private void setViewerFacade(ViewerFacade viewerFacade) { viewerFacadeReference.set(viewerFacade); } - @CalledOnlyBy(AmidstThread.EDT) - private void clearViewerFacade() { - threadMaster.clearOnRepaintTick(); - threadMaster.clearOnFragmentLoadTick(); - ViewerFacade viewerFacade = viewerFacadeReference.getAndSet(null); - if (viewerFacade != null) { - contentPane.remove(viewerFacade.getComponent()); - viewerFacade.dispose(); - } - menuBarSupplier.get().clear(); - } - @CalledOnlyBy(AmidstThread.EDT) public void clearWorld() { clearViewerFacade(); diff --git a/src/main/java/amidst/gui/main/viewer/ViewerFacade.java b/src/main/java/amidst/gui/main/viewer/ViewerFacade.java index 7f0e7c6a1..fceab036e 100644 --- a/src/main/java/amidst/gui/main/viewer/ViewerFacade.java +++ b/src/main/java/amidst/gui/main/viewer/ViewerFacade.java @@ -94,6 +94,7 @@ public void dispose() { graph.dispose(); zoom.skipFading(); zoom.reset(); + world.dispose(); } @CalledOnlyBy(AmidstThread.EDT) diff --git a/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java b/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java index 4f7b377ed..f1e4fa858 100644 --- a/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java +++ b/src/main/java/amidst/gui/seedsearcher/SeedSearcher.java @@ -90,13 +90,16 @@ private void doSearch(ProgressReporter reporter, SeedSearcherConfigur @CalledOnlyBy(AmidstThread.WORKER) private void doSearchOne(ProgressReporter reporter, SeedSearcherConfiguration configuration) - throws MinecraftInterfaceException { + throws IllegalStateException, + MinecraftInterfaceException { while (!isStopRequested) { World world = runningLauncherProfile.createWorldFromSeed(WorldSeed.random(), configuration.getWorldType()); if (configuration.getWorldFilter().isValid(world)) { reporter.report(world.getWorldSeed()); + world.dispose(); break; } + world.dispose(); } } } diff --git a/src/main/java/amidst/mojangapi/RunningLauncherProfile.java b/src/main/java/amidst/mojangapi/RunningLauncherProfile.java index e4023d146..5ed590597 100644 --- a/src/main/java/amidst/mojangapi/RunningLauncherProfile.java +++ b/src/main/java/amidst/mojangapi/RunningLauncherProfile.java @@ -33,6 +33,7 @@ public static RunningLauncherProfile from(WorldBuilder worldBuilder, LauncherPro private final WorldBuilder worldBuilder; private final LauncherProfile launcherProfile; private final MinecraftInterface minecraftInterface; + private volatile World currentWorld = null; public RunningLauncherProfile( WorldBuilder worldBuilder, @@ -66,8 +67,16 @@ public RunningLauncherProfile createSilentPlayerlessCopy() { * one world at a time. Creating a new world will break all previously * created world objects. */ - public World createWorldFromSeed(WorldSeed worldSeed, WorldType worldType) throws MinecraftInterfaceException { - return worldBuilder.fromSeed(minecraftInterface, worldSeed, worldType); + public synchronized World createWorldFromSeed(WorldSeed worldSeed, WorldType worldType) + throws IllegalStateException, + MinecraftInterfaceException { + if (currentWorld == null) { + currentWorld = worldBuilder.fromSeed(minecraftInterface, this::unlock, worldSeed, worldType); + return currentWorld; + } else { + throw new IllegalStateException( + "Each minecraft interface can only handle one world at a time. Dispose the previous world before creating a new one."); + } } /** @@ -75,7 +84,24 @@ public World createWorldFromSeed(WorldSeed worldSeed, WorldType worldType) throw * one world at a time. Creating a new world will break all previously * created world objects. */ - public World createWorldFromSaveGame(SaveGame saveGame) throws IOException, MinecraftInterfaceException { - return worldBuilder.fromSaveGame(minecraftInterface, saveGame); + public synchronized World createWorldFromSaveGame(SaveGame saveGame) + throws IllegalStateException, + IOException, + MinecraftInterfaceException { + if (currentWorld == null) { + currentWorld = worldBuilder.fromSaveGame(minecraftInterface, this::unlock, saveGame); + return currentWorld; + } else { + throw new IllegalStateException( + "Each minecraft interface can only handle one world at a time. Dispose the previous world before creating a new one."); + } + } + + private synchronized void unlock(World world) throws IllegalStateException { + if (currentWorld == world) { + currentWorld = null; + } else { + throw new IllegalStateException("The requested world is no longer the currentWorld."); + } } } diff --git a/src/main/java/amidst/mojangapi/world/World.java b/src/main/java/amidst/mojangapi/world/World.java index 37ec00a8a..6891a38b1 100644 --- a/src/main/java/amidst/mojangapi/world/World.java +++ b/src/main/java/amidst/mojangapi/world/World.java @@ -1,6 +1,7 @@ package amidst.mojangapi.world; import java.util.List; +import java.util.function.Consumer; import amidst.documentation.ThreadSafe; import amidst.mojangapi.minecraftinterface.RecognisedVersion; @@ -16,6 +17,8 @@ @ThreadSafe public class World { + private final Consumer onDisposeWorld; + private final WorldSeed worldSeed; private final WorldType worldType; private final String generatorOptions; @@ -37,6 +40,7 @@ public class World { private final WorldIconProducer> endCityProducer; public World( + Consumer onDisposeWorld, WorldSeed worldSeed, WorldType worldType, String generatorOptions, @@ -55,6 +59,7 @@ public World( WorldIconProducer oceanMonumentProducer, WorldIconProducer netherFortressProducer, WorldIconProducer> endCityProducer) { + this.onDisposeWorld = onDisposeWorld; this.worldSeed = worldSeed; this.worldType = worldType; this.generatorOptions = generatorOptions; @@ -162,4 +167,13 @@ public List getPlayerWorldIcons() { public void reloadPlayerWorldIcons() { playerProducer.resetCache(); } + + /** + * Unlocks the RunningLauncherProfile to allow the creation of another + * world. However, this does not actually prevent the usage of this world. + * If you keep using it, something will break. + */ + public void dispose() { + onDisposeWorld.accept(this); + } } diff --git a/src/main/java/amidst/mojangapi/world/WorldBuilder.java b/src/main/java/amidst/mojangapi/world/WorldBuilder.java index b9bcf7922..ba11182de 100644 --- a/src/main/java/amidst/mojangapi/world/WorldBuilder.java +++ b/src/main/java/amidst/mojangapi/world/WorldBuilder.java @@ -1,6 +1,7 @@ package amidst.mojangapi.world; import java.io.IOException; +import java.util.function.Consumer; import amidst.documentation.Immutable; import amidst.mojangapi.file.ImmutablePlayerInformationProvider; @@ -53,12 +54,16 @@ public WorldBuilder(PlayerInformationProvider playerInformationProvider, SeedHis this.seedHistoryLogger = seedHistoryLogger; } - public World fromSeed(MinecraftInterface minecraftInterface, WorldSeed worldSeed, WorldType worldType) - throws MinecraftInterfaceException { + public World fromSeed( + MinecraftInterface minecraftInterface, + Consumer onDisposeWorld, + WorldSeed worldSeed, + WorldType worldType) throws MinecraftInterfaceException { BiomeDataOracle biomeDataOracle = new BiomeDataOracle(minecraftInterface); VersionFeatures versionFeatures = DefaultVersionFeatures.create(minecraftInterface.getRecognisedVersion()); return create( minecraftInterface, + onDisposeWorld, worldSeed, worldType, "", @@ -71,7 +76,7 @@ public World fromSeed(MinecraftInterface minecraftInterface, WorldSeed worldSeed versionFeatures.getValidBiomesForStructure_Spawn())); } - public World fromSaveGame(MinecraftInterface minecraftInterface, SaveGame saveGame) + public World fromSaveGame(MinecraftInterface minecraftInterface, Consumer onDisposeWorld, SaveGame saveGame) throws IOException, MinecraftInterfaceException { VersionFeatures versionFeatures = DefaultVersionFeatures.create(minecraftInterface.getRecognisedVersion()); @@ -82,6 +87,7 @@ public World fromSaveGame(MinecraftInterface minecraftInterface, SaveGame saveGa WorldPlayerType.from(saveGame)); return create( minecraftInterface, + onDisposeWorld, WorldSeed.fromSaveGame(saveGame.getSeed()), saveGame.getWorldType(), saveGame.getGeneratorOptions(), @@ -93,6 +99,7 @@ public World fromSaveGame(MinecraftInterface minecraftInterface, SaveGame saveGa private World create( MinecraftInterface minecraftInterface, + Consumer onDisposeWorld, WorldSeed worldSeed, WorldType worldType, String generatorOptions, @@ -105,6 +112,7 @@ private World create( long seed = worldSeed.getLong(); minecraftInterface.createWorld(seed, worldType, generatorOptions); return new World( + onDisposeWorld, worldSeed, worldType, generatorOptions, diff --git a/src/test/java/amidst/mojangapi/mocking/FakeWorldBuilder.java b/src/test/java/amidst/mojangapi/mocking/FakeWorldBuilder.java index 2251c7952..e9b384bdd 100644 --- a/src/test/java/amidst/mojangapi/mocking/FakeWorldBuilder.java +++ b/src/test/java/amidst/mojangapi/mocking/FakeWorldBuilder.java @@ -1,6 +1,7 @@ package amidst.mojangapi.mocking; import java.util.Map; +import java.util.function.Consumer; import amidst.documentation.ThreadSafe; import amidst.mojangapi.minecraftinterface.MinecraftInterface; @@ -21,6 +22,8 @@ public static FakeWorldBuilder create(TestWorldDirectoryDeclaration directoryDec return new FakeWorldBuilder(WorldBuilder.createSilentPlayerless(), directoryDeclaration); } + private static final Consumer NOOP = disposedWorld -> { + }; private final WorldBuilder builder; private final TestWorldDirectoryDeclaration directoryDeclaration; @@ -31,8 +34,11 @@ public FakeWorldBuilder(WorldBuilder builder, TestWorldDirectoryDeclaration dire public World createRealWorld(TestWorldDeclaration worldDeclaration, MinecraftInterface realMinecraftInterface) throws MinecraftInterfaceException { - return builder - .fromSeed(realMinecraftInterface, worldDeclaration.getWorldSeed(), worldDeclaration.getWorldType()); + return builder.fromSeed( + realMinecraftInterface, + NOOP, + worldDeclaration.getWorldSeed(), + worldDeclaration.getWorldType()); } public World createFakeWorld(TestWorldDirectory worldDeclaration) throws MinecraftInterfaceException { @@ -55,6 +61,7 @@ private World createFakeWorld( BiomeDataJson fullBiomeData) throws MinecraftInterfaceException { return builder.fromSeed( createFakeMinecraftInterface(worldMetadata, quarterBiomeData, fullBiomeData), + NOOP, WorldSeed.fromUserInput(worldMetadata.getSeed() + ""), worldMetadata.getWorldType()); } From 08a09ef15b0177cc0ca4b4b46f278ec652de61b0 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Fri, 2 Jun 2017 13:19:09 +0200 Subject: [PATCH 45/48] removed duplicate log message --- .../java/amidst/gui/profileselect/LocalProfileComponent.java | 4 ++-- src/main/java/amidst/mojangapi/RunningLauncherProfile.java | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java index 59aa24a62..426a8f014 100644 --- a/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java +++ b/src/main/java/amidst/gui/profileselect/LocalProfileComponent.java @@ -89,8 +89,8 @@ private Optional tryLoad() { // TODO: Replace with proper handling for modded profiles. try { AmidstLogger.info( - "using minecraft launcher profile '" + getProfileName() + "' with versionId '" + getVersionName() - + "'"); + "using minecraft launcher profile '" + resolvedProfile.getProfileName() + "' with versionId '" + + resolvedProfile.getVersionId() + "'"); String possibleModProfiles = ".*(optifine|forge).*"; if (Pattern.matches(possibleModProfiles, getVersionName().toLowerCase(Locale.ENGLISH))) { diff --git a/src/main/java/amidst/mojangapi/RunningLauncherProfile.java b/src/main/java/amidst/mojangapi/RunningLauncherProfile.java index 5ed590597..58819ff98 100644 --- a/src/main/java/amidst/mojangapi/RunningLauncherProfile.java +++ b/src/main/java/amidst/mojangapi/RunningLauncherProfile.java @@ -3,7 +3,6 @@ import java.io.IOException; import amidst.documentation.ThreadSafe; -import amidst.logging.AmidstLogger; import amidst.mojangapi.file.LauncherProfile; import amidst.mojangapi.file.SaveGame; import amidst.mojangapi.minecraftinterface.MinecraftInterface; @@ -21,9 +20,6 @@ public class RunningLauncherProfile { public static RunningLauncherProfile from(WorldBuilder worldBuilder, LauncherProfile launcherProfile) throws LocalMinecraftInterfaceCreationException { - AmidstLogger.info( - "using launcher profile. version id: '" + launcherProfile.getVersionId() + "', profile name: '" - + launcherProfile.getProfileName() + "', jar file: '" + launcherProfile.getJar() + "'"); return new RunningLauncherProfile( worldBuilder, launcherProfile, From d0f424f19717c46f562e7d8ed3b554c728b30ad4 Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Fri, 2 Jun 2017 13:24:11 +0200 Subject: [PATCH 46/48] reworked service instantiation --- src/main/java/amidst/mojangapi/file/LauncherProfile.java | 2 +- src/main/java/amidst/mojangapi/file/MinecraftInstallation.java | 2 +- .../java/amidst/mojangapi/file/UnresolvedLauncherProfile.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/amidst/mojangapi/file/LauncherProfile.java b/src/main/java/amidst/mojangapi/file/LauncherProfile.java index fe7c85199..a159bdb1d 100644 --- a/src/main/java/amidst/mojangapi/file/LauncherProfile.java +++ b/src/main/java/amidst/mojangapi/file/LauncherProfile.java @@ -15,6 +15,7 @@ @Immutable public class LauncherProfile { + private final LibraryService libraryService = new LibraryService(); private final DotMinecraftDirectory dotMinecraftDirectory; private final ProfileDirectory profileDirectory; private final VersionDirectory versionDirectory; @@ -51,7 +52,6 @@ public File getSaves() { } public URLClassLoader newClassLoader() throws MalformedURLException { - LibraryService libraryService = new LibraryService(); List classLoaderUrls = libraryService.getAllClassLoaderUrls( dotMinecraftDirectory.getLibraries(), versionJson.getLibraries(), diff --git a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java index 4e4e6c232..363db4df2 100644 --- a/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java +++ b/src/main/java/amidst/mojangapi/file/MinecraftInstallation.java @@ -43,6 +43,7 @@ public static MinecraftInstallation newLocalMinecraftInstallation(String preferr return new MinecraftInstallation(dotMinecraftDirectory); } + private final SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); private final DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); private final DotMinecraftDirectory dotMinecraftDirectory; @@ -89,7 +90,6 @@ private LauncherProfile newLauncherProfile(VersionDirectory versionDirectory) th } public SaveGame newSaveGame(File location) throws IOException, FormatException { - SaveDirectoryService saveDirectoryService = new SaveDirectoryService(); SaveDirectory saveDirectory = saveDirectoryService.newSaveDirectory(location); return new SaveGame(saveDirectory, saveDirectoryService.readLevelDat(saveDirectory)); } diff --git a/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java b/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java index 7787814d2..ccaa876da 100644 --- a/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java +++ b/src/main/java/amidst/mojangapi/file/UnresolvedLauncherProfile.java @@ -14,6 +14,7 @@ @Immutable public class UnresolvedLauncherProfile { + private final DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); private final DotMinecraftDirectory dotMinecraftDirectory; private final LauncherProfileJson launcherProfileJson; @@ -29,7 +30,6 @@ public String getName() { } public LauncherProfile resolve(VersionList versionList) throws FormatException, IOException { - DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService(); ProfileDirectory profileDirectory = dotMinecraftDirectoryService .createValidProfileDirectory(launcherProfileJson, dotMinecraftDirectory); VersionDirectory versionDirectory = dotMinecraftDirectoryService From e4868bb63f981cce8d75e40a4e375266bedc445e Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Fri, 2 Jun 2017 13:35:40 +0200 Subject: [PATCH 47/48] converted LibraryService to ClassLoaderService --- .../amidst/mojangapi/file/LauncherProfile.java | 9 +++------ ...LibraryService.java => ClassLoaderService.java} | 14 +++++++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) rename src/main/java/amidst/mojangapi/file/service/{LibraryService.java => ClassLoaderService.java} (87%) diff --git a/src/main/java/amidst/mojangapi/file/LauncherProfile.java b/src/main/java/amidst/mojangapi/file/LauncherProfile.java index a159bdb1d..188e9b761 100644 --- a/src/main/java/amidst/mojangapi/file/LauncherProfile.java +++ b/src/main/java/amidst/mojangapi/file/LauncherProfile.java @@ -2,20 +2,18 @@ import java.io.File; import java.net.MalformedURLException; -import java.net.URL; import java.net.URLClassLoader; -import java.util.List; import amidst.documentation.Immutable; import amidst.mojangapi.file.directory.DotMinecraftDirectory; import amidst.mojangapi.file.directory.ProfileDirectory; import amidst.mojangapi.file.directory.VersionDirectory; import amidst.mojangapi.file.json.version.VersionJson; -import amidst.mojangapi.file.service.LibraryService; +import amidst.mojangapi.file.service.ClassLoaderService; @Immutable public class LauncherProfile { - private final LibraryService libraryService = new LibraryService(); + private final ClassLoaderService classLoaderService = new ClassLoaderService(); private final DotMinecraftDirectory dotMinecraftDirectory; private final ProfileDirectory profileDirectory; private final VersionDirectory versionDirectory; @@ -52,10 +50,9 @@ public File getSaves() { } public URLClassLoader newClassLoader() throws MalformedURLException { - List classLoaderUrls = libraryService.getAllClassLoaderUrls( + return classLoaderService.createClassLoader( dotMinecraftDirectory.getLibraries(), versionJson.getLibraries(), versionDirectory.getJar()); - return new URLClassLoader(classLoaderUrls.toArray(new URL[classLoaderUrls.size()])); } } diff --git a/src/main/java/amidst/mojangapi/file/service/LibraryService.java b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java similarity index 87% rename from src/main/java/amidst/mojangapi/file/service/LibraryService.java rename to src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java index dd16e1ef1..d535d37aa 100644 --- a/src/main/java/amidst/mojangapi/file/service/LibraryService.java +++ b/src/main/java/amidst/mojangapi/file/service/ClassLoaderService.java @@ -3,6 +3,7 @@ import java.io.File; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -21,11 +22,18 @@ import amidst.util.OperatingSystemDetector; @Immutable -public class LibraryService { +public class ClassLoaderService { private static final String ACTION_ALLOW = "allow"; @NotNull - public List getAllClassLoaderUrls(File librariesDirectory, List libraries, File versionJarFile) + public URLClassLoader createClassLoader(File librariesDirectory, List libraries, File versionJarFile) + throws MalformedURLException { + List classLoaderUrls = getAllClassLoaderUrls(librariesDirectory, libraries, versionJarFile); + return new URLClassLoader(classLoaderUrls.toArray(new URL[classLoaderUrls.size()])); + } + + @NotNull + private List getAllClassLoaderUrls(File librariesDirectory, List libraries, File versionJarFile) throws MalformedURLException { List result = new LinkedList<>(getLibraryUrls(librariesDirectory, libraries)); result.add(versionJarFile.toURI().toURL()); @@ -33,7 +41,7 @@ public List getAllClassLoaderUrls(File librariesDirectory, List getLibraryUrls(File librariesDirectory, List libraries) { + private List getLibraryUrls(File librariesDirectory, List libraries) { List result = new ArrayList<>(); AmidstLogger.info("Loading libraries."); for (LibraryJson library : libraries) { From 437ab4294ef9629e75a81f7d073eab4f4819155b Mon Sep 17 00:00:00 2001 From: Stefan Dollase Date: Fri, 2 Jun 2017 14:12:25 +0200 Subject: [PATCH 48/48] added safety checks for resolveAllLater mechanism --- .../amidst/gui/profileselect/ProfileSelectWindow.java | 11 ++++++++++- .../amidst/mojangapi/file/VersionListProvider.java | 5 ++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java index 99c8ba562..61417f6ee 100644 --- a/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java +++ b/src/main/java/amidst/gui/profileselect/ProfileSelectWindow.java @@ -43,6 +43,8 @@ public class ProfileSelectWindow { private final JFrame frame; private final ProfileSelectPanel profileSelectPanel; + private volatile boolean isDisposed = false; + @CalledOnlyBy(AmidstThread.EDT) public ProfileSelectWindow( Application application, @@ -141,7 +143,13 @@ private void createProfileComponentsIfNecessary(List profileSelectPanel.setEmptyMessage("No profiles found"); } else { createProfileComponents(launcherProfiles); - versionListProvider.onDownloadRemoteFinished(profileSelectPanel::resolveAllLater); + versionListProvider.onDownloadRemoteFinished(this::resolveAllLater); + profileSelectPanel.resolveAllLater(); + } + } + + private void resolveAllLater() { + if (!isDisposed) { profileSelectPanel.resolveAllLater(); } } @@ -178,6 +186,7 @@ private void scanAndLoadProfilesFailed(Exception e) { @CalledOnlyBy(AmidstThread.EDT) public void dispose() { + isDisposed = true; frame.dispose(); } } diff --git a/src/main/java/amidst/mojangapi/file/VersionListProvider.java b/src/main/java/amidst/mojangapi/file/VersionListProvider.java index 2f5ea4073..fa5ceca9d 100644 --- a/src/main/java/amidst/mojangapi/file/VersionListProvider.java +++ b/src/main/java/amidst/mojangapi/file/VersionListProvider.java @@ -39,7 +39,9 @@ public VersionListProvider(VersionList local) { @CalledOnlyBy(AmidstThread.EDT) public void onDownloadRemoteFinished(Runnable listener) { - listeners.offer(listener); + if (remote == null) { + listeners.offer(listener); + } } @CalledOnlyBy(AmidstThread.EDT) @@ -58,6 +60,7 @@ private void finishedDownload(VersionList remote) { AmidstLogger.info("Successfully loaded remote version list."); this.remote = remote; listeners.forEach(Runnable::run); + listeners.clear(); } @CalledOnlyBy(AmidstThread.EDT)