From 2b044865fe06313a9a143ad4ce681224cdeed68a Mon Sep 17 00:00:00 2001 From: Ellet <73608287+ellet0@users.noreply.github.com> Date: Sat, 29 Jun 2024 04:23:14 +0300 Subject: [PATCH] refactor(sync-info)!: sync info breaking changes (#11) * docs: update 'Mod.name' property comment * chore(sync-script): exit process with status 1 instead of 0 in case showErrorMessageAndTerminate() did not exit --- .../kotlin/launchers/LauncherDataSource.kt | 2 +- .../atLauncher/ATLauncherDataSource.kt | 2 +- .../modrinth/ModrinthLauncherDataSource.kt | 2 +- .../prismLauncher/PrismLauncherDataSource.kt | 2 +- .../prismLauncher/PrismLauncherModMetadata.kt | 2 +- .../modrinth/models/ModrinthProject.kt | 7 +- .../modsConverter/ModsConvertResult.kt | 2 +- .../services/modsConverter/ModsConverter.kt | 2 +- .../modsConverter/ModsConverterImpl.kt | 3 +- .../MinecraftAssetProviderUtils.kt | 7 +- .../kotlin/syncInfo/models/FileIntegrity.kt | 3 +- .../main/kotlin/syncInfo/models/SyncInfo.kt | 90 ++----------------- .../kotlin/syncInfo/models/{ => mod}/Mod.kt | 13 +-- .../kotlin/syncInfo/models/mod/ModSyncInfo.kt | 90 +++++++++++++++++++ .../models/{ => quickPlay}/QuickPlay.kt | 13 +-- .../syncInfo/models/{ => server}/Server.kt | 2 +- .../syncInfo/models/server/ServerSyncInfo.kt | 13 +++ .../kotlin/syncInfo/models/ModExtensions.kt | 5 +- .../kotlin/syncService/ModsSyncService.kt | 26 +++--- 19 files changed, 158 insertions(+), 128 deletions(-) rename common/src/main/kotlin/syncInfo/models/{ => mod}/Mod.kt (84%) create mode 100644 common/src/main/kotlin/syncInfo/models/mod/ModSyncInfo.kt rename common/src/main/kotlin/syncInfo/models/{ => quickPlay}/QuickPlay.kt (70%) rename common/src/main/kotlin/syncInfo/models/{ => server}/Server.kt (89%) create mode 100644 common/src/main/kotlin/syncInfo/models/server/ServerSyncInfo.kt diff --git a/admin/src/main/kotlin/launchers/LauncherDataSource.kt b/admin/src/main/kotlin/launchers/LauncherDataSource.kt index f00c15e..270bf3f 100644 --- a/admin/src/main/kotlin/launchers/LauncherDataSource.kt +++ b/admin/src/main/kotlin/launchers/LauncherDataSource.kt @@ -1,7 +1,7 @@ package launchers import minecraftAssetProviders.MinecraftAssetProvider -import syncInfo.models.Mod +import syncInfo.models.mod.Mod import java.nio.file.Path // TODO: Rename launcherInstanceDirectoryPath to dotMinecraftDirectoryPath, diff --git a/admin/src/main/kotlin/launchers/atLauncher/ATLauncherDataSource.kt b/admin/src/main/kotlin/launchers/atLauncher/ATLauncherDataSource.kt index 32b2848..f375213 100644 --- a/admin/src/main/kotlin/launchers/atLauncher/ATLauncherDataSource.kt +++ b/admin/src/main/kotlin/launchers/atLauncher/ATLauncherDataSource.kt @@ -8,7 +8,7 @@ import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.jsonObject import launchers.Instance import launchers.LauncherDataSource -import syncInfo.models.Mod +import syncInfo.models.mod.Mod import utils.JsonIgnoreUnknownKeys import utils.JsonPrettyPrint import utils.SystemFileProvider diff --git a/admin/src/main/kotlin/launchers/modrinth/ModrinthLauncherDataSource.kt b/admin/src/main/kotlin/launchers/modrinth/ModrinthLauncherDataSource.kt index 867c99b..41b6d25 100644 --- a/admin/src/main/kotlin/launchers/modrinth/ModrinthLauncherDataSource.kt +++ b/admin/src/main/kotlin/launchers/modrinth/ModrinthLauncherDataSource.kt @@ -9,7 +9,7 @@ import kotlinx.serialization.json.jsonObject import launchers.Instance import launchers.LauncherDataSource import launchers.modrinth.ModrinthLauncherInstance.ModrinthLauncherProject -import syncInfo.models.Mod +import syncInfo.models.mod.Mod import utils.JsonIgnoreUnknownKeys import utils.SystemFileProvider import utils.listFilteredPaths diff --git a/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherDataSource.kt b/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherDataSource.kt index 0e975fa..34d492b 100644 --- a/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherDataSource.kt +++ b/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherDataSource.kt @@ -6,7 +6,7 @@ import curseForgeDataSource import launchers.Instance import launchers.LauncherDataSource import okio.IOException -import syncInfo.models.Mod +import syncInfo.models.mod.Mod import utils.SystemFileProvider import utils.listFilteredPaths import java.nio.file.Path diff --git a/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherModMetadata.kt b/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherModMetadata.kt index e7f7198..6ca422f 100644 --- a/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherModMetadata.kt +++ b/admin/src/main/kotlin/launchers/prismLauncher/PrismLauncherModMetadata.kt @@ -3,7 +3,7 @@ package launchers.prismLauncher import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import syncInfo.models.FileIntegrityInfo -import syncInfo.models.Mod +import syncInfo.models.mod.Mod /** * Prism launcher stores the mod info inside a folder [PrismLauncherDataSource.MODS_METADATA_DIRECTORY_NAME] which is diff --git a/admin/src/main/kotlin/minecraftAssetProviders/modrinth/models/ModrinthProject.kt b/admin/src/main/kotlin/minecraftAssetProviders/modrinth/models/ModrinthProject.kt index 5fc56dc..67048c5 100644 --- a/admin/src/main/kotlin/minecraftAssetProviders/modrinth/models/ModrinthProject.kt +++ b/admin/src/main/kotlin/minecraftAssetProviders/modrinth/models/ModrinthProject.kt @@ -2,7 +2,7 @@ package minecraftAssetProviders.modrinth.models import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import syncInfo.models.Mod.ModSupport +import syncInfo.models.mod.Mod.ModSupport /** * From https://docs.modrinth.com/#tag/projects/operation/getProject @@ -87,13 +87,12 @@ data class ModrinthProject( /** * @return Convert [ProjectSide] to [ModSupport] which is data-specific to the project * */ - fun toModSupport(): ModSupport { - return when (this) { + fun toModSupport(): ModSupport = + when (this) { Required -> ModSupport.Required Optional -> ModSupport.Optional Unsupported -> ModSupport.Unsupported } - } } @Serializable diff --git a/admin/src/main/kotlin/services/modsConverter/ModsConvertResult.kt b/admin/src/main/kotlin/services/modsConverter/ModsConvertResult.kt index eee41c9..e443d62 100644 --- a/admin/src/main/kotlin/services/modsConverter/ModsConvertResult.kt +++ b/admin/src/main/kotlin/services/modsConverter/ModsConvertResult.kt @@ -1,7 +1,7 @@ package services.modsConverter import constants.AdminConstants -import syncInfo.models.Mod +import syncInfo.models.mod.Mod sealed class ModsConvertResult { data class Success( diff --git a/admin/src/main/kotlin/services/modsConverter/ModsConverter.kt b/admin/src/main/kotlin/services/modsConverter/ModsConverter.kt index 9c4eb49..de68abf 100644 --- a/admin/src/main/kotlin/services/modsConverter/ModsConverter.kt +++ b/admin/src/main/kotlin/services/modsConverter/ModsConverter.kt @@ -2,7 +2,7 @@ package services.modsConverter import launchers.MinecraftLauncher import services.modsConverter.models.ModsConvertMode -import syncInfo.models.Mod +import syncInfo.models.mod.Mod interface ModsConverter { /** diff --git a/admin/src/main/kotlin/services/modsConverter/ModsConverterImpl.kt b/admin/src/main/kotlin/services/modsConverter/ModsConverterImpl.kt index 38d7f75..351f3d6 100644 --- a/admin/src/main/kotlin/services/modsConverter/ModsConverterImpl.kt +++ b/admin/src/main/kotlin/services/modsConverter/ModsConverterImpl.kt @@ -7,6 +7,7 @@ import launchers.LauncherDataSourceFactory import launchers.MinecraftLauncher import services.modsConverter.models.ModsConvertMode import syncInfo.models.SyncInfo +import syncInfo.models.mod.ModSyncInfo import utils.JsonPrettyPrint import java.nio.file.Paths import kotlin.io.path.exists @@ -108,7 +109,7 @@ class ModsConverterImpl : ModsConverter { val json = if (prettyFormat) JsonPrettyPrint else Json val modsOutputText: String = when (convertMode) { - ModsConvertMode.InsideSyncInfo -> json.encodeToString(SyncInfo(mods = mods)) + ModsConvertMode.InsideSyncInfo -> json.encodeToString(SyncInfo(modSyncInfo = ModSyncInfo(mods = mods))) ModsConvertMode.AsModsList -> json.encodeToString(mods) } diff --git a/common/src/main/kotlin/minecraftAssetProviders/MinecraftAssetProviderUtils.kt b/common/src/main/kotlin/minecraftAssetProviders/MinecraftAssetProviderUtils.kt index 835fa83..dd70d1b 100644 --- a/common/src/main/kotlin/minecraftAssetProviders/MinecraftAssetProviderUtils.kt +++ b/common/src/main/kotlin/minecraftAssetProviders/MinecraftAssetProviderUtils.kt @@ -5,8 +5,8 @@ import utils.baseUrl import java.net.URL object MinecraftAssetProviderUtils { - fun getAssetProvider(downloadUrl: String): Result { - return try { + fun getAssetProvider(downloadUrl: String): Result = + try { val assetProvider = MinecraftAssetProvider.knownProviders.firstOrNull { val url = URL(downloadUrl) @@ -23,14 +23,13 @@ object MinecraftAssetProviderUtils { e.printStackTrace() Result.failure(e) } - } /** * @return The used providers for all the assets (e.g., Mods, Resource-packs etc...) * */ fun getAssetsProviders(syncInfo: SyncInfo): Result> { val assetsProviders = mutableSetOf() - syncInfo.mods.mapTo(assetsProviders) { getAssetProvider(it.downloadUrl).getOrThrow() } + syncInfo.modSyncInfo.mods.mapTo(assetsProviders) { getAssetProvider(it.downloadUrl).getOrThrow() } // TODO: Add all kind of assets like Resource-packs and shaders return Result.success(assetsProviders) } diff --git a/common/src/main/kotlin/syncInfo/models/FileIntegrity.kt b/common/src/main/kotlin/syncInfo/models/FileIntegrity.kt index ff4a366..87400f2 100644 --- a/common/src/main/kotlin/syncInfo/models/FileIntegrity.kt +++ b/common/src/main/kotlin/syncInfo/models/FileIntegrity.kt @@ -4,8 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** - * A class that hold the data that is used for verifying a fle - * will be used in [Mod] and another type of resources to verify them + * A class that holds the data that is used for verifying a file * * Used to verify the file's integrity * and trigger a re-download if the file is invalid or has been tampered with diff --git a/common/src/main/kotlin/syncInfo/models/SyncInfo.kt b/common/src/main/kotlin/syncInfo/models/SyncInfo.kt index 00227c8..7f07fa4 100644 --- a/common/src/main/kotlin/syncInfo/models/SyncInfo.kt +++ b/common/src/main/kotlin/syncInfo/models/SyncInfo.kt @@ -1,14 +1,14 @@ package syncInfo.models import kotlinx.serialization.Serializable +import syncInfo.models.mod.ModSyncInfo +import syncInfo.models.server.ServerSyncInfo // When adding new data fields to this data class, ensure they are added in the correct order // to maintain consistency with the JSON structure. /** * This data class represents the JSON structure containing sync information from a remote server. - * To simplify editing the JSON data, most variables like mods and related options to the mods are included directly. - * * */ @Serializable data class SyncInfo( @@ -32,91 +32,13 @@ data class SyncInfo( * */ val preferredAssetFileVerification: PreferredFileVerificationOption? = PreferredFileVerificationOption.Medium, /** - * The list of mods to sync, take a look at [Mod] for more details + * All required and optional properties for the mod syncing process * */ - val mods: List = emptyList(), + val modSyncInfo: ModSyncInfo = ModSyncInfo(), /** - * Will override [shouldVerifyAssetFilesIntegrity] for the mods - * - * By default, the script only validates the file name and usually the file name contains - * the mod and minecraft version, so when you update some mods, the old versions will be deleted and be - * downloaded once again, if you also want the script to verify each file and if it matches the file from the source - * if not, then it will be deleted and re-downloaded again - * - * Also, if some mods got corrupted because of killing the process, then this would be helpful to make sure - * you have healthy mod files - * - * **Notice**: This option will only take effect for the mods that have at least one non-null value in the [FileIntegrityInfo] - * for example if [FileIntegrityInfo.sha256] or [FileIntegrityInfo.sizeInBytes] is not null, you can use one, some or all - * of them, it's up to you, in short if you want to verify a mod to be matched on the one the server, you have - * to assign a value to at least one, use [FileIntegrityInfo.sha256] or [FileIntegrityInfo.sha512] - * as it's validating the content to make sure it's valid and secure, - * validating using [FileIntegrityInfo.sizeInBytes] is a little bit faster (the difference is very negligible) - * - * If you want to verify all the mods, then all the mods need to have at least one value for one - * of those discussed above - * - * If you want to completely disable the verifying process, - * pass false to [shouldVerifyModFilesIntegrity] and will ignore - * even if the data in the [FileIntegrityInfo] are specified - * - * @see Mod.overrideShouldVerifyFileIntegrity to override this value for a specific mod - * - * */ - val shouldVerifyModFilesIntegrity: Boolean? = null, - /** - * if [Environment] value is [Environment.Client] then will download/sync only the mods that'd need to be - * on te client side like client side mods and the mods that's needed to be in both Client and Server - * - * The exact opposite apply for [Environment.Server] - * - * This will depend on [Mod.clientSupport] and [Mod.serverSupport] values. - * - * **Notice**: If you automate the process of generating the mods info and get it from the Mod provider/ launcher, - * it might depend on the info that's on the provider (e.g, Modrinth) and it could be that the developers of the mod - * marked the mod as server side only and unsupported on the client side, while it's true for mods like [Geyser](https://modrinth.com/mod/geyser) - * - * It is usually optional on the client side. - * An example mod is [FallingTree](https://modrinth.com/mod/fallingtree) - * is marked as **server side only** and unsupported on the **client side** while it's **optional** for single player, - * it could work in single player in the **integrated server**; - * it's not needed on the **client side** to join a **multiplayer server** - * - * */ - val shouldSyncOnlyModsForCurrentEnvironment: Boolean = true, - /** - * Should the script allow the player to install mods other than the synced mods by the script? - * if true then the script won't touch any mods that is not installed by the script, otherwise will delete it and - * won't allow using any other mods, still can be bypassed, it's better to install a server side mod - * that check the installed mods (still can be bypassed) - * - * TODO: Currently (BUG) if you let's say have sodium installed (sodium.jar), the synced mod by the script would be (sodium.synced.jar) - * however the user can still install (sodium.jar) resulting in mod duplication which will cause the game to not run - * (for most mod loaders), we can solve this by reading the mod id from the jar and make sure there are no duplication - * */ - val allowUsingOtherMods: Boolean = false, - /** - * A way for the script to download mods and save them like (`my-mod.synced.jar`) instead of (`my-mod.jar`) - * the script need this so it can know if the mod installed by it or not to support [allowUsingOtherMods] - * when true, so it will ignore the mods installed by the player - * - * Pass null if you want to disable this and install the mod file name just like how it's on the source. - * In that case make sure to not pass true to [allowUsingOtherMods] because it won't work - * - * If you want to change it to something like (`my-mod.sync.jar`) pass `.sync` instead - * - * if there is already existing players that has the installed mods with a specific [modSyncMarker] and you change - * it from (`.synced` to `.sync` for example), then the script would identify the mods with (`.sync`) as mods - * installed by the player resulting in duplication, However, this occurs only if [allowUsingOtherMods] is true, otherwise - * will be deleted and downloaded again in case of this changed - * */ - val modSyncMarker: String? = ".synced", - /** - * The list of servers to sync, so when you change the server address or move to another host, - * the players are no longer required to update it, it will be all automated, you can add multiple servers - * in case you have different servers for different regions or some other use-case, for example + * All required and optional properties for the server syncing process * */ - val servers: List = emptyList(), + val serverSyncInfo: ServerSyncInfo = ServerSyncInfo(), ) { companion object } diff --git a/common/src/main/kotlin/syncInfo/models/Mod.kt b/common/src/main/kotlin/syncInfo/models/mod/Mod.kt similarity index 84% rename from common/src/main/kotlin/syncInfo/models/Mod.kt rename to common/src/main/kotlin/syncInfo/models/mod/Mod.kt index e7667ab..d506bb3 100644 --- a/common/src/main/kotlin/syncInfo/models/Mod.kt +++ b/common/src/main/kotlin/syncInfo/models/mod/Mod.kt @@ -1,7 +1,10 @@ -package syncInfo.models +package syncInfo.models.mod import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import syncInfo.models.Environment +import syncInfo.models.FileIntegrityInfo +import syncInfo.models.SyncInfo // When adding a new property, consider converting/import the new // data from other launchers data format if possible @@ -20,8 +23,8 @@ data class Mod( * */ val fileIntegrityInfo: FileIntegrityInfo = FileIntegrityInfo(), /** - * The mod name (optional) for now will be only used in the gui, if you don't specify it, then will get - * the file name from [mod] + * The mod name (optional) that might be displayed in GUI, if not present + * will fall back to the file name from [downloadUrl] * */ val name: String? = null, /** @@ -53,10 +56,10 @@ data class Mod( * */ val description: String? = null, /** - * Will override [SyncInfo.shouldVerifyModFilesIntegrity] and [SyncInfo.shouldVerifyAssetFilesIntegrity] + * Will override [ModSyncInfo.shouldVerifyModFilesIntegrity] and [SyncInfo.shouldVerifyAssetFilesIntegrity] * for a specific mod * - * @see SyncInfo.shouldVerifyModFilesIntegrity for more details. + * @see ModSyncInfo.shouldVerifyModFilesIntegrity for more details. * */ val overrideShouldVerifyFileIntegrity: Boolean? = null, ) { diff --git a/common/src/main/kotlin/syncInfo/models/mod/ModSyncInfo.kt b/common/src/main/kotlin/syncInfo/models/mod/ModSyncInfo.kt new file mode 100644 index 0000000..188efc1 --- /dev/null +++ b/common/src/main/kotlin/syncInfo/models/mod/ModSyncInfo.kt @@ -0,0 +1,90 @@ +package syncInfo.models.mod + +import kotlinx.serialization.Serializable +import syncInfo.models.Environment +import syncInfo.models.FileIntegrityInfo +import syncInfo.models.SyncInfo + +@Serializable +data class ModSyncInfo( + /** + * The list of mods to sync, take a look at [Mod] for more details + * */ + val mods: List = emptyList(), + /** + * Will override [SyncInfo.shouldVerifyAssetFilesIntegrity] for the mods + * + * By default, the script only validates the file name and usually the file name contains + * the mod and minecraft version, so when you update some mods, the old versions will be deleted and be + * downloaded once again, if you also want the script to verify each file and if it matches the file from the source + * if not, then it will be deleted and re-downloaded again + * + * Also, if some mods got corrupted because of killing the process, then this would be helpful to make sure + * you have healthy mod files + * + * **Notice**: This option will only take effect for the mods that have at least one non-null value in the [FileIntegrityInfo] + * for example if [FileIntegrityInfo.sha256] or [FileIntegrityInfo.sizeInBytes] is not null, you can use one, some or all + * of them, it's up to you, in short if you want to verify a mod to be matched on the one the server, you have + * to assign a value to at least one, use [FileIntegrityInfo.sha256] or [FileIntegrityInfo.sha512] + * as it's validating the content to make sure it's valid and secure, + * validating using [FileIntegrityInfo.sizeInBytes] is a little bit faster (the difference is very negligible) + * + * If you want to verify all the mods, then all the mods need to have at least one value for one + * of those discussed above + * + * If you want to completely disable the verifying process, + * pass false to [shouldVerifyModFilesIntegrity] and will ignore + * even if the data in the [FileIntegrityInfo] are specified + * + * @see Mod.overrideShouldVerifyFileIntegrity to override this value for a specific mod + * + * */ + val shouldVerifyModFilesIntegrity: Boolean? = null, + /** + * if [Environment] value is [Environment.Client] then will download/sync only the mods that'd need to be + * on te client side like client side mods and the mods that's needed to be in both Client and Server + * + * The exact opposite apply for [Environment.Server] + * + * This will depend on [Mod.clientSupport] and [Mod.serverSupport] values. + * + * **Notice**: If you automate the process of generating the mods info and get it from the Mod provider/ launcher, + * it might depend on the info that's on the provider (e.g, Modrinth) and it could be that the developers of the mod + * marked the mod as server side only and unsupported on the client side, while it's true for mods like [Geyser](https://modrinth.com/mod/geyser) + * + * It is usually optional on the client side. + * An example mod is [FallingTree](https://modrinth.com/mod/fallingtree) + * is marked as **server side only** and unsupported on the **client side** while it's **optional** for single player, + * it could work in single player in the **integrated server**; + * it's not needed on the **client side** to join a **multiplayer server** + * + * */ + val shouldSyncOnlyModsForCurrentEnvironment: Boolean = true, + /** + * Should the script allow the player to install mods other than the synced mods by the script? + * if true then the script won't touch any mods that is not installed by the script, otherwise will delete it and + * won't allow using any other mods, still can be bypassed, it's better to install a server side mod + * that check the installed mods (can be bypassed) + * + * TODO: Currently (BUG) if you let's say have sodium installed (sodium.jar), the synced mod by the script would be (sodium.synced.jar) + * however the user can still install (sodium.jar) resulting in mod duplication which will cause the game to not run + * (for most mod loaders), we can solve this by reading the mod id from the jar and make sure there are no duplication + * */ + val allowUsingOtherMods: Boolean = false, + /** + * A way for the script to download mods and save them like (`my-mod.synced.jar`) instead of (`my-mod.jar`) + * the script need this so it can know if the mod installed by it or not to support [allowUsingOtherMods] + * when true, so it will ignore the mods installed by the player + * + * Pass null if you want to disable this and install the mod file name just like how it's on the source. + * In that case make sure to not pass true to [allowUsingOtherMods] because it won't work + * + * If you want to change it to something like (`my-mod.sync.jar`) pass `.sync` instead + * + * if there is already existing players that has the installed mods with a specific [modSyncMarker] and you change + * it from (`.synced` to `.sync` for example), then the script would identify the mods with (`.sync`) as mods + * installed by the player resulting in duplication, However, this occurs only if [allowUsingOtherMods] is true, otherwise + * will be deleted and downloaded again in case of this changed + * */ + val modSyncMarker: String? = ".synced", +) diff --git a/common/src/main/kotlin/syncInfo/models/QuickPlay.kt b/common/src/main/kotlin/syncInfo/models/quickPlay/QuickPlay.kt similarity index 70% rename from common/src/main/kotlin/syncInfo/models/QuickPlay.kt rename to common/src/main/kotlin/syncInfo/models/quickPlay/QuickPlay.kt index 4005e8b..ac1ec8f 100644 --- a/common/src/main/kotlin/syncInfo/models/QuickPlay.kt +++ b/common/src/main/kotlin/syncInfo/models/quickPlay/QuickPlay.kt @@ -1,20 +1,23 @@ -package syncInfo.models +package syncInfo.models.quickPlay +import constants.DotMinecraftFileNames import kotlinx.serialization.Serializable /** * A data class that contains information the Minecraft Java Quick Play Feature which was added in * Minecraft Version [snapshot 23w14a](https://www.minecraft.net/en-us/article/minecraft-snapshot-23w14a) - * and above, only of the properties should be either not null or all of them null to disable the feature + * and above. + * Only of the properties should be either not null or all of them null to disable the feature * - * @param serverAddress The address that is used to connect to minecraft server, have backward compatibility + * @param serverAddress The address used to connect to minecraft server have backward compatibility * for earlier versions (lower than 1.20), example `localhost`, `localhost:25565`, `play.server.net` or `play.server.net:25565` - * @param worldSaveName The world save name (folder name) in the [Constants.MinecraftInstanceFiles.Saves] folder + * @param worldSaveName The world save name (folder name) in the [DotMinecraftFileNames.SAVES_DIRECTORY] folder * that is used to load a minecraft world, work only on recent minecraft versions (1.20 and above), example `New World` * @param realmId The realm id that is used to connect to a Minecraft Realm, work only on recent minecraft versions (1.20 and above) * * Work only on the supported Minecraft launchers - * // TODO: Mention and decide which launchers will be supported + * + * **Currently this feature is not implemented**. * * */ @Serializable diff --git a/common/src/main/kotlin/syncInfo/models/Server.kt b/common/src/main/kotlin/syncInfo/models/server/Server.kt similarity index 89% rename from common/src/main/kotlin/syncInfo/models/Server.kt rename to common/src/main/kotlin/syncInfo/models/server/Server.kt index f007e5e..6a03b1f 100644 --- a/common/src/main/kotlin/syncInfo/models/Server.kt +++ b/common/src/main/kotlin/syncInfo/models/server/Server.kt @@ -1,4 +1,4 @@ -package syncInfo.models +package syncInfo.models.server import kotlinx.serialization.Serializable diff --git a/common/src/main/kotlin/syncInfo/models/server/ServerSyncInfo.kt b/common/src/main/kotlin/syncInfo/models/server/ServerSyncInfo.kt new file mode 100644 index 0000000..9908548 --- /dev/null +++ b/common/src/main/kotlin/syncInfo/models/server/ServerSyncInfo.kt @@ -0,0 +1,13 @@ +package syncInfo.models.server + +import kotlinx.serialization.Serializable + +@Serializable +data class ServerSyncInfo( + /** + * The list of servers to sync, so when you change the server address or move to another host, + * the players are no longer required to update it, it will be all automated, you can add multiple servers + * in case you have different servers for different regions or some other use-case, for example + * */ + val servers: List = emptyList(), +) diff --git a/sync-script/src/main/kotlin/syncInfo/models/ModExtensions.kt b/sync-script/src/main/kotlin/syncInfo/models/ModExtensions.kt index 3cb9f12..ab24ae8 100644 --- a/sync-script/src/main/kotlin/syncInfo/models/ModExtensions.kt +++ b/sync-script/src/main/kotlin/syncInfo/models/ModExtensions.kt @@ -1,6 +1,7 @@ package syncInfo.models import config.models.ScriptConfig +import syncInfo.models.mod.Mod import utils.getFileNameFromUrlOrError import utils.showErrorMessageAndTerminate import java.nio.file.Path @@ -42,7 +43,7 @@ fun Mod.shouldSyncOnCurrentEnvironment(): Boolean { * Allow overriding the value for a specific mod, or all the mods, or use a global value for all the assets. * */ fun Mod.shouldVerifyFileIntegrity(): Boolean = - overrideShouldVerifyFileIntegrity ?: SyncInfo.instance.shouldVerifyModFilesIntegrity + overrideShouldVerifyFileIntegrity ?: SyncInfo.instance.modSyncInfo.shouldVerifyModFilesIntegrity ?: SyncInfo.instance.shouldVerifyAssetFilesIntegrity suspend fun Mod.hasValidFileIntegrityOrError(modFilePath: Path): Boolean? = @@ -52,5 +53,5 @@ suspend fun Mod.hasValidFileIntegrityOrError(modFilePath: Path): Boolean? = message = "An error occurred while validating the integrity of the mod file (${modFilePath.name}) \uD83D\uDCC1.", ) // This will never reach due to the previous statement stopping the application - exitProcess(0) + exitProcess(1) } diff --git a/sync-script/src/main/kotlin/syncService/ModsSyncService.kt b/sync-script/src/main/kotlin/syncService/ModsSyncService.kt index 07bfb21..1ec0c67 100644 --- a/sync-script/src/main/kotlin/syncService/ModsSyncService.kt +++ b/sync-script/src/main/kotlin/syncService/ModsSyncService.kt @@ -4,11 +4,12 @@ import constants.SyncScriptDotMinecraftFiles import gui.dialogs.LoadingIndicatorDialog import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import syncInfo.models.Mod import syncInfo.models.SyncInfo import syncInfo.models.getDisplayName import syncInfo.models.hasValidFileIntegrityOrError import syncInfo.models.instance +import syncInfo.models.mod.Mod +import syncInfo.models.mod.ModSyncInfo import syncInfo.models.shouldSyncOnCurrentEnvironment import syncInfo.models.shouldVerifyFileIntegrity import utils.ExecutionTimer @@ -34,13 +35,12 @@ import kotlin.io.path.nameWithoutExtension class ModsSyncService : SyncService { private val modsDirectoryPath = SyncScriptDotMinecraftFiles.Mods.path + private val modSyncInfo = SyncInfo.instance.modSyncInfo companion object { private const val MOD_FILE_EXTENSION = "jar" } - private val syncInfo = SyncInfo.instance - override suspend fun syncData() = withContext(Dispatchers.IO) { val modsExecutionTimer = ExecutionTimer() @@ -48,7 +48,7 @@ class ModsSyncService : SyncService { println("\n\uD83D\uDD04 Syncing mods...") // All mods from the remote - val mods = syncInfo.mods + val mods = modSyncInfo.mods println("📥 Total received mods from server: ${mods.size}") validateModsDirectory() @@ -102,14 +102,14 @@ class ModsSyncService : SyncService { // Get only the mods that are created by the script if the admin allows the player to install other mods /** - * The mods to deal with based on [SyncInfo.allowUsingOtherMods] + * The mods to deal with based on [ModSyncInfo.allowUsingOtherMods] * will or will not remove the mods that are created by the script * */ val localModFilePathsToProcess = modsDirectoryPath .listFilteredPaths { val isModFileExtension = !it.isDirectory() && !it.isHidden() && it.extension == MOD_FILE_EXTENSION - if (syncInfo.allowUsingOtherMods) { + if (modSyncInfo.allowUsingOtherMods) { return@listFilteredPaths isModFileExtension && isScriptModFile(it) } else { return@listFilteredPaths isModFileExtension @@ -137,7 +137,7 @@ class ModsSyncService : SyncService { } private fun getCurrentEnvironmentModsOrAll(mods: List): List { - if (syncInfo.shouldSyncOnlyModsForCurrentEnvironment) { + if (modSyncInfo.shouldSyncOnlyModsForCurrentEnvironment) { val currentEnvironmentMods = mods.filter { mod -> if (!mod.shouldSyncOnCurrentEnvironment()) { @@ -254,8 +254,8 @@ class ModsSyncService : SyncService { } /** - * @return The file that will be used, we use [SyncInfo.modSyncMarker] to support [isScriptModFile] - * will be the same file name from the [Mod.downloadUrl] if [SyncInfo.modSyncMarker] is null + * @return The file that will be used, we use [ModSyncInfo.modSyncMarker] to support [isScriptModFile] + * will be the same file name from the [Mod.downloadUrl] if [ModSyncInfo.modSyncMarker] is null * * @see isScriptModFile * */ @@ -265,7 +265,7 @@ class ModsSyncService : SyncService { val modFileName = buildString { append(modFileNameWithoutExtension) - SyncInfo.instance.modSyncMarker?.let { append(it) } + modSyncInfo.modSyncMarker?.let { append(it) } append(".${MOD_FILE_EXTENSION}") } return modsDirectoryPath.resolve(modFileName) @@ -273,14 +273,14 @@ class ModsSyncService : SyncService { /** * @return if this mod is created/synced by the script - * it will be identified by [SyncInfo.modSyncMarker] and will always return true - * if [SyncInfo.modSyncMarker] is null + * it will be identified by [ModSyncInfo.modSyncMarker] and will always return true + * if [ModSyncInfo.modSyncMarker] is null * * @see getModFilePath * */ private fun isScriptModFile(modFilePath: Path): Boolean = modFilePath.name.endsWith( - "${SyncInfo.instance.modSyncMarker.orEmpty()}.${MOD_FILE_EXTENSION}", + "${modSyncInfo.modSyncMarker.orEmpty()}.${MOD_FILE_EXTENSION}", ) /**