mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-09 15:29:20 -04:00
wip mod loading
This commit is contained in:
parent
6ba4928b1f
commit
0eb773f7fa
@ -307,6 +307,7 @@ dependencies {
|
||||
implementation("org.kamranzafar", "jtar", "2.3")
|
||||
implementation("org.reflections", "reflections", "0.10.2")
|
||||
implementation("it.unimi.dsi", "fastutil-core", "8.5.9")
|
||||
implementation("org.xeustechnologies", "jcl-core", version = "2.8")
|
||||
|
||||
|
||||
// ikonli
|
||||
|
@ -22,7 +22,6 @@
|
||||
- load meta -> inject to classpath -> initialize main class
|
||||
- main class template (with logging, assets, ...)
|
||||
- Multiple `mods` folders
|
||||
- pre load (before loading anything)
|
||||
- while load (while loading everything else)
|
||||
- background load (start loading in while, but don't wait for them. Only wait before loading connection)
|
||||
- connection load (load before connecting to server)
|
||||
- pre boot (before loading anything)
|
||||
- boot (while loading everything else)
|
||||
- post boot (start loading in while, but don't wait for them. Only wait before loading connection)
|
||||
|
@ -42,6 +42,8 @@ import de.bixilon.minosoft.gui.eros.util.JavaFXInitializer
|
||||
import de.bixilon.minosoft.main.BootTasks
|
||||
import de.bixilon.minosoft.modding.event.events.FinishInitializingEvent
|
||||
import de.bixilon.minosoft.modding.event.master.GlobalEventMaster
|
||||
import de.bixilon.minosoft.modding.loader.LoadingPhases
|
||||
import de.bixilon.minosoft.modding.loader.ModLoader
|
||||
import de.bixilon.minosoft.properties.MinosoftPropertiesLoader
|
||||
import de.bixilon.minosoft.protocol.packets.factory.PacketTypeRegistry
|
||||
import de.bixilon.minosoft.protocol.protocol.LANServerListener
|
||||
@ -70,11 +72,15 @@ object Minosoft {
|
||||
val start = nanos()
|
||||
Log::class.java.forceInit()
|
||||
CommandLineArguments.parse(args)
|
||||
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "Starting minosoft..." }
|
||||
|
||||
KUtil.initUtilClasses()
|
||||
KUtil.init()
|
||||
ModLoader.initModLoading()
|
||||
ModLoader.load(LoadingPhases.PRE_BOOT, CountUpAndDownLatch(0))
|
||||
ModLoader.await(LoadingPhases.PRE_BOOT)
|
||||
MINOSOFT_ASSETS_MANAGER.load(CountUpAndDownLatch(0))
|
||||
|
||||
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "Starting minosoft..." }
|
||||
warnMacOS()
|
||||
MinosoftPropertiesLoader.load()
|
||||
|
||||
@ -105,6 +111,7 @@ object Minosoft {
|
||||
taskWorker += WorkerTask(identifier = BootTasks.YGGDRASIL, executor = { YggdrasilUtil.load() })
|
||||
|
||||
taskWorker += WorkerTask(identifier = BootTasks.ASSETS_OVERRIDE, executor = { OVERRIDE_ASSETS_MANAGER.load(it) })
|
||||
taskWorker += WorkerTask(identifier = BootTasks.MODS, executor = { ModLoader.load(LoadingPhases.BOOT, it) })
|
||||
|
||||
|
||||
taskWorker.work(BOOT_LATCH)
|
||||
@ -114,6 +121,7 @@ object Minosoft {
|
||||
val end = nanos()
|
||||
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "Minosoft boot sequence finished in ${(end - start).formatNanos()}!" }
|
||||
GlobalEventMaster.fireEvent(FinishInitializingEvent())
|
||||
DefaultThreadPool += { ModLoader.load(LoadingPhases.POST_BOOT, CountUpAndDownLatch(0)) }
|
||||
|
||||
|
||||
RunConfiguration.AUTO_CONNECT_TO?.let { AutoConnect.autoConnect(it) }
|
||||
|
@ -27,5 +27,6 @@ enum class BootTasks {
|
||||
STARTUP_PROGRESS,
|
||||
ASSETS_OVERRIDE,
|
||||
CLI,
|
||||
MODS,
|
||||
;
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.modding.loader
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||
import org.xeustechnologies.jcl.JarClassLoader
|
||||
import org.xeustechnologies.jcl.JarResources
|
||||
import org.xeustechnologies.jcl.JclJarEntry
|
||||
import java.util.jar.JarEntry
|
||||
import java.util.jar.JarInputStream
|
||||
|
||||
object LoaderUtil {
|
||||
private val contentsField = JarResources::class.java.getDeclaredField("jarEntryContents")
|
||||
private val classpathResourcesField = JarClassLoader::class.java.getDeclaredField("classpathResources")
|
||||
|
||||
init {
|
||||
contentsField.isAccessible = true
|
||||
classpathResourcesField.isAccessible = true
|
||||
}
|
||||
|
||||
val JarResources.contents: MutableMap<String, JclJarEntry>
|
||||
get() = contentsField.get(this).unsafeCast()
|
||||
|
||||
|
||||
val JarClassLoader.classpathResources: JarResources
|
||||
get() = classpathResourcesField.get(this).unsafeCast()
|
||||
|
||||
fun JarClassLoader.load(entry: JarEntry, stream: JarInputStream) {
|
||||
load(entry.name, stream.readAllBytes())
|
||||
}
|
||||
|
||||
fun JarClassLoader.load(name: String, data: ByteArray) {
|
||||
val content = this.classpathResources.contents
|
||||
val entry = JclJarEntry()
|
||||
entry.baseUrl = null
|
||||
entry.resourceBytes = data
|
||||
content[name] = entry
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.modding.loader
|
||||
|
||||
import de.bixilon.kutil.enums.EnumUtil
|
||||
import de.bixilon.kutil.enums.ValuesEnum
|
||||
|
||||
enum class LoadingPhases {
|
||||
PRE_BOOT,
|
||||
BOOT,
|
||||
POST_BOOT,
|
||||
;
|
||||
|
||||
companion object : ValuesEnum<LoadingPhases> {
|
||||
override val VALUES: Array<LoadingPhases> = values()
|
||||
override val NAME_MAP: Map<String, LoadingPhases> = EnumUtil.getEnumValues(VALUES)
|
||||
}
|
||||
}
|
208
src/main/java/de/bixilon/minosoft/modding/loader/ModLoader.kt
Normal file
208
src/main/java/de/bixilon/minosoft/modding/loader/ModLoader.kt
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.modding.loader
|
||||
|
||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||
import de.bixilon.kutil.concurrent.worker.unconditional.UnconditionalWorker
|
||||
import de.bixilon.kutil.latch.CountUpAndDownLatch
|
||||
import de.bixilon.kutil.watcher.DataWatcher.Companion.watched
|
||||
import de.bixilon.minosoft.assets.util.FileUtil.readJson
|
||||
import de.bixilon.minosoft.modding.loader.LoaderUtil.load
|
||||
import de.bixilon.minosoft.modding.loader.mod.MinosoftMod
|
||||
import de.bixilon.minosoft.modding.loader.mod.ModMain
|
||||
import de.bixilon.minosoft.terminal.RunConfiguration
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.jar.JarEntry
|
||||
import java.util.jar.JarInputStream
|
||||
|
||||
|
||||
object ModLoader {
|
||||
private val BASE_PATH = RunConfiguration.HOME_DIRECTORY + "mods/"
|
||||
private const val MANFIEST = "manifest.json"
|
||||
private val mods: MutableList<MinosoftMod> = mutableListOf()
|
||||
private var latch: CountUpAndDownLatch? = null
|
||||
var currentPhase by watched(LoadingPhases.PRE_BOOT)
|
||||
private set
|
||||
var state by watched(PhaseStates.WAITING)
|
||||
private set
|
||||
|
||||
private val LoadingPhases.path: File get() = File(BASE_PATH + name.lowercase())
|
||||
|
||||
private fun createDirectories() {
|
||||
val created: MutableList<LoadingPhases> = mutableListOf()
|
||||
for (phase in LoadingPhases.VALUES) {
|
||||
val path = phase.path
|
||||
if (!path.exists()) {
|
||||
path.mkdirs()
|
||||
created += phase
|
||||
}
|
||||
}
|
||||
if (created.isNotEmpty()) {
|
||||
Log.log(LogMessageType.MOD_LOADING, LogLevels.VERBOSE) { "Created mod folders: $created" }
|
||||
}
|
||||
}
|
||||
|
||||
fun initModLoading() {
|
||||
DefaultThreadPool += { createDirectories() }
|
||||
}
|
||||
|
||||
private fun MinosoftMod.processFile(path: String, data: ByteArray) {
|
||||
TODO("Directory")
|
||||
}
|
||||
|
||||
private fun MinosoftMod.processJar(file: File) {
|
||||
val stream = JarInputStream(FileInputStream(file))
|
||||
while (true) {
|
||||
val entry = stream.nextEntry ?: break
|
||||
if (entry.isDirectory) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (entry.name.endsWith(".class") && entry is JarEntry) {
|
||||
this.classLoader.load(entry, stream)
|
||||
} else if (entry.name.startsWith("assets/")) {
|
||||
TODO("Assets")
|
||||
} else if (entry.name == MANFIEST) {
|
||||
manifest = stream.readJson(false)
|
||||
}
|
||||
}
|
||||
stream.close()
|
||||
}
|
||||
|
||||
private fun MinosoftMod.construct() {
|
||||
val manifest = manifest ?: throw IllegalStateException("Mod $path has no manifest!")
|
||||
val mainClass = Class.forName(manifest.main, true, classLoader)
|
||||
val main = mainClass.kotlin.objectInstance ?: throw IllegalStateException("${manifest.main} is not an kotlin object!")
|
||||
if (main !is ModMain) {
|
||||
throw IllegalStateException("${manifest.main} does not inherit ModMain!")
|
||||
}
|
||||
this.main = main
|
||||
main.init()
|
||||
}
|
||||
|
||||
private fun MinosoftMod.postInit() {
|
||||
main!!.postInit()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun load(phase: LoadingPhases, latch: CountUpAndDownLatch) {
|
||||
if (RunConfiguration.IGNORE_MODS) {
|
||||
return
|
||||
}
|
||||
Log.log(LogMessageType.MOD_LOADING, LogLevels.VERBOSE) { "Starting mod load: $phase" }
|
||||
// ToDo: check phase
|
||||
this.currentPhase = phase
|
||||
|
||||
val inner = CountUpAndDownLatch(1, latch)
|
||||
this.latch = inner
|
||||
this.state = PhaseStates.LISTING
|
||||
|
||||
val path = phase.path
|
||||
val files = path.listFiles()
|
||||
if (files == null || files.isEmpty()) {
|
||||
// no mods to load
|
||||
inner.dec()
|
||||
state = PhaseStates.COMPLETE
|
||||
return
|
||||
}
|
||||
val mods: MutableList<MinosoftMod> = mutableListOf()
|
||||
|
||||
state = PhaseStates.INJECTING
|
||||
for (file in files) {
|
||||
if (!file.isDirectory && !file.name.endsWith(".jar") && !file.name.endsWith(".zip")) {
|
||||
continue
|
||||
}
|
||||
val mod = MinosoftMod(file, phase, CountUpAndDownLatch(3, inner))
|
||||
Log.log(LogMessageType.MOD_LOADING, LogLevels.VERBOSE) { "Injecting $file" }
|
||||
try {
|
||||
if (file.isDirectory) {
|
||||
TODO("Scanning directory")
|
||||
}
|
||||
mod.processJar(file)
|
||||
mods += mod
|
||||
mod.latch.dec()
|
||||
} catch (exception: Throwable) {
|
||||
Log.log(LogMessageType.MOD_LOADING, LogLevels.WARN) { "Error injecting mod: $file" }
|
||||
exception.printStackTrace()
|
||||
mod.latch.count = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
state = PhaseStates.CONSTRUCTING
|
||||
var worker = UnconditionalWorker()
|
||||
for (mod in mods) {
|
||||
worker += {
|
||||
try {
|
||||
mod.construct()
|
||||
mod.latch.dec()
|
||||
} catch (error: Throwable) {
|
||||
mod.latch.count = 0
|
||||
error.printStackTrace()
|
||||
mods -= mod
|
||||
}
|
||||
}
|
||||
}
|
||||
worker.work(inner)
|
||||
|
||||
state = PhaseStates.POST_INIT
|
||||
worker = UnconditionalWorker()
|
||||
for (mod in mods) {
|
||||
worker += {
|
||||
try {
|
||||
mod.postInit()
|
||||
mod.latch.dec()
|
||||
} catch (error: Throwable) {
|
||||
mod.latch.count = 0
|
||||
error.printStackTrace()
|
||||
mods -= mod
|
||||
}
|
||||
}
|
||||
}
|
||||
worker.work(inner)
|
||||
|
||||
|
||||
this.mods += mods
|
||||
state = PhaseStates.COMPLETE
|
||||
inner.dec()
|
||||
if (phase == LoadingPhases.POST_BOOT) {
|
||||
Log.log(LogMessageType.MOD_LOADING, LogLevels.INFO) { "Mod loading completed!" }
|
||||
}
|
||||
}
|
||||
|
||||
fun await(phase: LoadingPhases) {
|
||||
if (RunConfiguration.IGNORE_MODS) {
|
||||
return
|
||||
}
|
||||
val latch = this.latch
|
||||
val currentPhase = this.currentPhase
|
||||
val state = this.state
|
||||
if (currentPhase == phase) {
|
||||
if (state == PhaseStates.COMPLETE) {
|
||||
return
|
||||
}
|
||||
latch!!.await() // ToDo: What if phase has not started yet?
|
||||
return
|
||||
}
|
||||
if (phase.ordinal < currentPhase.ordinal) {
|
||||
// already done
|
||||
return
|
||||
}
|
||||
throw IllegalStateException("$phase has not started yet!")
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.modding.loader
|
||||
|
||||
enum class PhaseStates {
|
||||
WAITING,
|
||||
LISTING,
|
||||
INJECTING,
|
||||
CONSTRUCTING,
|
||||
POST_INIT,
|
||||
COMPLETE,
|
||||
;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.modding.loader.mod
|
||||
|
||||
import de.bixilon.kutil.latch.CountUpAndDownLatch
|
||||
import de.bixilon.minosoft.assets.AssetsManager
|
||||
import de.bixilon.minosoft.modding.loader.LoadingPhases
|
||||
import de.bixilon.minosoft.modding.loader.mod.manifest.ModManifest
|
||||
import org.xeustechnologies.jcl.JarClassLoader
|
||||
import java.io.File
|
||||
|
||||
class MinosoftMod(
|
||||
val path: File,
|
||||
val phase: LoadingPhases,
|
||||
val latch: CountUpAndDownLatch,
|
||||
) {
|
||||
val classLoader = JarClassLoader()
|
||||
var manifest: ModManifest? = null
|
||||
var assetsManager: AssetsManager? = null
|
||||
var main: ModMain? = null
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.modding.loader.mod
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.unsafeNull
|
||||
import de.bixilon.minosoft.assets.AssetsManager
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.Initializable
|
||||
|
||||
abstract class ModMain : Initializable {
|
||||
val assets: AssetsManager = unsafeNull()
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.modding.loader.mod.manifest
|
||||
|
||||
import java.util.*
|
||||
|
||||
data class ModManifest(
|
||||
val name: String,
|
||||
val uuid: UUID,
|
||||
val version: String,
|
||||
val main: String,
|
||||
)
|
@ -48,6 +48,8 @@ import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent
|
||||
import de.bixilon.minosoft.modding.event.events.loading.RegistriesLoadEvent
|
||||
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.modding.loader.LoadingPhases
|
||||
import de.bixilon.minosoft.modding.loader.ModLoader
|
||||
import de.bixilon.minosoft.protocol.network.connection.Connection
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.clientsettings.ClientSettingsManager
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.plugin.DefaultPluginHandler
|
||||
@ -168,6 +170,9 @@ class PlayConnection(
|
||||
val count = latch.count
|
||||
check(!wasConnected) { "Connection was already connected!" }
|
||||
try {
|
||||
state = PlayConnectionStates.WAITING_MODS
|
||||
ModLoader.await(LoadingPhases.BOOT)
|
||||
|
||||
state = PlayConnectionStates.LOADING_ASSETS
|
||||
var error: Throwable? = null
|
||||
val taskWorker = TaskWorker(errorHandler = { _, exception -> if (error == null) error = exception }, criticalErrorHandler = { _, exception -> if (error == null) error = exception })
|
||||
|
@ -22,6 +22,8 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
enum class PlayConnectionStates : Translatable {
|
||||
WAITING,
|
||||
|
||||
WAITING_MODS,
|
||||
|
||||
LOADING_ASSETS,
|
||||
LOADING,
|
||||
|
||||
|
@ -82,6 +82,10 @@ object CommandLineArguments {
|
||||
addArgument("--ignore_yggdrasil")
|
||||
.action(Arguments.storeTrue())
|
||||
.help("Disable all yggdrasil (mojang) signature checking")
|
||||
|
||||
addArgument("--ignore_mods")
|
||||
.action(Arguments.storeTrue())
|
||||
.help("Ignores all mods and disable mod loading")
|
||||
}
|
||||
|
||||
fun parse(args: Array<String>) {
|
||||
@ -125,5 +129,6 @@ object CommandLineArguments {
|
||||
RunConfiguration.VERBOSE_LOGGING = namespace.getBoolean("verbose")
|
||||
|
||||
RunConfiguration.IGNORE_YGGDRASIL = namespace.getBoolean("ignore_yggdrasil")
|
||||
RunConfiguration.IGNORE_MODS = namespace.getBoolean("ignore_mods")
|
||||
}
|
||||
}
|
||||
|
@ -66,4 +66,6 @@ object RunConfiguration {
|
||||
|
||||
|
||||
var IGNORE_YGGDRASIL = false
|
||||
|
||||
var IGNORE_MODS = false
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user