mirror of
https://github.com/Anvilcraft/modpacktools
synced 2024-06-11 15:09:24 +02:00
Merge branch 'master' of https://github.com/Anvilcraft/modpacktools
Conflicts: src/main/kotlin/ley/anvil/modpacktools/util/Util.kt
This commit is contained in:
commit
3a5a26a9b7
|
@ -32,20 +32,31 @@ private val httpClient0 = lazy {
|
|||
.build()
|
||||
}
|
||||
val HTTP_CLIENT by httpClient0
|
||||
private val helpMessage by lazy {
|
||||
val sb = StringBuilder().append("Commands:\n\n")
|
||||
LOADER.commands.entries.stream()
|
||||
//Sort by name
|
||||
.sorted(Comparator.comparing {e: MutableMap.MutableEntry<String, ICommand> -> e.key})
|
||||
.forEach {sb.append("${it.key}: ${it.value.helpMessage}\n")}
|
||||
sb.toString()
|
||||
}
|
||||
|
||||
|
||||
fun main(args: Array<out String>) {
|
||||
if(args.isEmpty()) {
|
||||
printHelp()
|
||||
println(helpMessage)
|
||||
} else {
|
||||
|
||||
try {
|
||||
val ret = LOADER.runCommand(args[0], args)
|
||||
if(ret.hasRet())
|
||||
println(ret.ret)
|
||||
} catch(e: NoSuchElementException) {
|
||||
println(e.message)
|
||||
printHelp()
|
||||
println("Command ${args[0]} not found")
|
||||
println(helpMessage)
|
||||
} catch(e: CommandLoader.ConfigMissingException) {
|
||||
println("Config is needed for this command yet it is not present. Run 'init' to generate")
|
||||
} catch(e: CommandLoader.ModpackJsonMissingException) {
|
||||
println("Modpackjson is needed for this command yet it is not present.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,11 +66,3 @@ fun main(args: Array<out String>) {
|
|||
HTTP_CLIENT.connectionPool.evictAll()
|
||||
}
|
||||
}
|
||||
|
||||
fun printHelp() {
|
||||
println("Commands:")
|
||||
LOADER.commands.entries.stream()
|
||||
//Sort by name
|
||||
.sorted(Comparator.comparing {e: MutableMap.MutableEntry<String, ICommand> -> e.key})
|
||||
.forEach {println("${it.key}: ${it.value.helpMessage}")}
|
||||
}
|
|
@ -2,9 +2,10 @@ package ley.anvil.modpacktools.command
|
|||
|
||||
import ley.anvil.modpacktools.CONFIG
|
||||
import ley.anvil.modpacktools.MPJH
|
||||
import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
|
||||
import org.reflections.Reflections
|
||||
import org.reflections.scanners.SubTypesScanner
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
/**
|
||||
* The command loader will scan the given package for {@link ICommand} classes and add them to the command list
|
||||
|
@ -12,15 +13,28 @@ import org.reflections.scanners.SubTypesScanner
|
|||
* @param pkg The package to scan for commands
|
||||
*/
|
||||
class CommandLoader(private val pkg: String) {
|
||||
class ConfigMissingException : IllegalStateException()
|
||||
class ModpackJsonMissingException : IllegalStateException()
|
||||
|
||||
val commands = HashMap<String, ICommand>()
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Runs a command statically.
|
||||
*
|
||||
* @param args the args to pass to the command
|
||||
* @throws ConfigMissingException if the command requires a config and it is not found
|
||||
* @throws ModpackJsonMissingException if the command requires a modpackjson file and it is not found
|
||||
*/
|
||||
@JvmStatic
|
||||
@Throws(ConfigMissingException::class, ModpackJsonMissingException::class)
|
||||
fun ICommand.runStatic(args: Array<out String>): CommandReturn {
|
||||
if(this.needsConfig && !CONFIG.configExists())
|
||||
return fail("Config is needed for this command yet it is not present. Run 'init' to generate")
|
||||
if(this.needsConfig && !CONFIG.exists)
|
||||
throw ConfigMissingException()
|
||||
|
||||
if(this.needsModpackjson && MPJH.asWrapper == null)
|
||||
return fail("Modpackjson is needed for this command yet it is not present.")
|
||||
throw ModpackJsonMissingException()
|
||||
|
||||
return this.execute(args)
|
||||
}
|
||||
}
|
||||
|
@ -35,11 +49,14 @@ class CommandLoader(private val pkg: String) {
|
|||
val refs = Reflections(pkg, SubTypesScanner(false))
|
||||
|
||||
refs.getSubTypesOf(ICommand::class.java).stream()
|
||||
.map {it.kotlin}
|
||||
//Only annotated classes
|
||||
.filter {it.isAnnotationPresent(LoadCommand::class.java)}
|
||||
//Cannot use it.hasAnnotation because it is experimental and requires everything to be annotated so this makes more sense
|
||||
.filter {it.annotations.any {ann -> ann.annotationClass == LoadCommand::class}}
|
||||
//can be object
|
||||
.map {it.kotlin.objectInstance ?: it}
|
||||
.forEach {if(it is ICommand) addCommand(it) else addClass(it as Class<out ICommand>)}
|
||||
.map {it.objectInstance ?: it}
|
||||
//create new instance if it is a class, otherwise just add the current instance
|
||||
.forEach {if(it is ICommand) addCommand(it) else addClass(it as KClass<out ICommand>)}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +65,7 @@ class CommandLoader(private val pkg: String) {
|
|||
* @param clazz the class to add
|
||||
* @return if it was successful
|
||||
*/
|
||||
fun addClass(clazz: Class<out ICommand>) = addCommand(clazz.newInstance())
|
||||
fun addClass(clazz: KClass<out ICommand>) = addCommand(clazz.createInstance())
|
||||
|
||||
/**
|
||||
* Adds a command to the command list with the name that getName() returns
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ley.anvil.modpacktools.commands
|
||||
|
||||
import j2html.TagCreator.*
|
||||
import j2html.utils.CSSMin.compressCss
|
||||
import ley.anvil.addonscript.wrapper.ASWrapper
|
||||
import ley.anvil.addonscript.wrapper.ArtifactDestination
|
||||
import ley.anvil.addonscript.wrapper.MetaData
|
||||
|
@ -12,8 +13,10 @@ import ley.anvil.modpacktools.command.ICommand
|
|||
import ley.anvil.modpacktools.command.LoadCommand
|
||||
import org.apache.commons.csv.CSVFormat
|
||||
import org.apache.commons.csv.CSVPrinter
|
||||
import org.apache.commons.io.IOUtils
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
@LoadCommand
|
||||
object CreateModlist : ICommand {
|
||||
|
@ -61,30 +64,7 @@ object CreateModlist : ICommand {
|
|||
head(
|
||||
style(
|
||||
//Fancy css!
|
||||
"""
|
||||
a:link {
|
||||
color: #ff5555;
|
||||
}
|
||||
a:visited {
|
||||
color: #cc55cc;
|
||||
}
|
||||
body {
|
||||
background-color: #333333;
|
||||
color: #ffffff
|
||||
}
|
||||
.img {
|
||||
width:100px;
|
||||
}
|
||||
td {
|
||||
border: #999999 3px;
|
||||
border-style: solid;
|
||||
}
|
||||
.description {
|
||||
width: 100%
|
||||
}
|
||||
"""
|
||||
//trim unnecessary chars
|
||||
.trimIndent().filter {it != '\n'}
|
||||
compressCss(IOUtils.toString(ClassLoader.getSystemResourceAsStream("commands/createmodlist/style.css"), StandardCharsets.UTF_8))
|
||||
)
|
||||
),
|
||||
body(
|
||||
|
@ -97,10 +77,10 @@ td {
|
|||
),
|
||||
each(getMods()) {
|
||||
tr(
|
||||
td(a(
|
||||
td(if(it.icon != null) a(
|
||||
img().withSrc(it.icon)
|
||||
.withClass("img")
|
||||
).withHref(it.website)
|
||||
).withHref(it.website) else null
|
||||
),
|
||||
td(a(it.name)
|
||||
.withHref(it.website)
|
||||
|
@ -112,7 +92,9 @@ td {
|
|||
li(contr.key)
|
||||
}
|
||||
)),
|
||||
td(it.description?.joinToString("<br />") ?: "")
|
||||
td(each(it.description?.asList() ?: listOf()) {d: String ->
|
||||
p(d)
|
||||
})
|
||||
.withClass("description")
|
||||
)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ object Init : ICommand {
|
|||
override val needsModpackjson: Boolean = false
|
||||
|
||||
override fun execute(args: Array<out String>): CommandReturn {
|
||||
if(CONFIG.configExists())
|
||||
if(CONFIG.exists)
|
||||
return fail("Config exists")
|
||||
CONFIG.copyConfig()
|
||||
return success("Config Created")
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
package ley.anvil.modpacktools.util
|
||||
|
||||
import ley.anvil.addonscript.curse.ManifestJSON
|
||||
import ley.anvil.addonscript.wrapper.ASWrapper
|
||||
|
||||
fun convertAStoManifest(addonscript: ASWrapper): ManifestLinksPair {
|
||||
var ml = ManifestLinksPair()
|
||||
var ver = addonscript.defaultVersion
|
||||
var manifest = ManifestJSON()
|
||||
|
||||
var mcv = ver.version?.mcversion!![0]
|
||||
manifest.minecraft = ManifestJSON.Minecraft()
|
||||
manifest.minecraft.version = mcv
|
||||
manifest.minecraft.modLoaders = mutableListOf()
|
||||
manifest.files = mutableListOf()
|
||||
|
||||
manifest.manifestType = "minecraftModpack"
|
||||
manifest.manifestVersion = 1
|
||||
manifest.name = addonscript.json.meta!!.name
|
||||
if (manifest.name == null)
|
||||
manifest.name = addonscript.json.id
|
||||
manifest.version = ver.versionName
|
||||
manifest.author = addonscript.json!!.meta!!.contributors[0].name
|
||||
|
||||
|
||||
for (rel in ver.getRelations(arrayOf("client"), null)) {
|
||||
if (rel.isModloader) {
|
||||
if (rel.relation.id == "forge") {
|
||||
var forge = ManifestJSON.Modloader()
|
||||
forge.primary = true
|
||||
forge.id = "forge-" + rel.versions.latestKnown
|
||||
manifest.minecraft.modLoaders.add(forge)
|
||||
} else {
|
||||
println("Curse only allows Forge as a modloader. " + rel.relation.id + " is not allowed!")
|
||||
}
|
||||
} else if (rel.hasFile()) {
|
||||
var file = rel.file
|
||||
if (file.file.installer == "internal.jar") {
|
||||
println("internal.jar is not supportet on Curse")
|
||||
continue
|
||||
} else if (file.isArtifact) {
|
||||
var art = file.artifact
|
||||
if (art.isCurseforge) {
|
||||
var f = ManifestJSON.File()
|
||||
f.fileID = art.fileID
|
||||
f.projectID = art.projectID
|
||||
f.required = rel.options.contains("required")
|
||||
manifest.files.add(f);
|
||||
}
|
||||
} else if (rel.options.contains("required")) {
|
||||
ml.links.put(file.get(), file.file.installer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (file in ver.getFiles(arrayOf("client", "required"), null)) {
|
||||
if (file.file.installer == "internal.jar") {
|
||||
println("internal.jar is not supportet on Curse")
|
||||
continue
|
||||
} else if (file.isArtifact) {
|
||||
var art = file.artifact
|
||||
if (art.isCurseforge) {
|
||||
var f = ManifestJSON.File()
|
||||
f.fileID = art.fileID
|
||||
f.projectID = art.projectID
|
||||
f.required = true
|
||||
manifest.files.add(f);
|
||||
}
|
||||
} else {
|
||||
ml.links.put(file.get(), file.file.installer)
|
||||
}
|
||||
}
|
||||
ml.manifest = manifest
|
||||
|
||||
return ml
|
||||
}
|
|
@ -4,21 +4,7 @@ import org.apache.commons.io.FileUtils
|
|||
import java.io.File
|
||||
|
||||
class Config(val configName: String) {
|
||||
val jarLocation by lazy {
|
||||
//Get the Location of the jarfile
|
||||
var file = File(
|
||||
this::class.java
|
||||
.protectionDomain
|
||||
.codeSource
|
||||
.location
|
||||
.toURI()
|
||||
)
|
||||
//Ensure That JAR_LOCATION is the jarfile's directory and not the file itself
|
||||
if(file.isFile)
|
||||
file = file.parentFile
|
||||
file
|
||||
}
|
||||
val configLocation by lazy {File(jarLocation, configName)}
|
||||
val configLocation by lazy {File(configName)}
|
||||
val config by lazy {readConfig()}
|
||||
|
||||
/**
|
||||
|
@ -27,7 +13,7 @@ class Config(val configName: String) {
|
|||
* @return the Toml object of the config file
|
||||
*/
|
||||
private fun readConfig(): CustomToml {
|
||||
return if(configExists()) {
|
||||
return if(exists) {
|
||||
//parse file to toml
|
||||
CustomToml().read(configLocation) as CustomToml
|
||||
//reads config from resources if no config file exists as a default value. commands that require the config still won't run without it
|
||||
|
@ -39,7 +25,7 @@ class Config(val configName: String) {
|
|||
*
|
||||
* @return true if the config file exists
|
||||
*/
|
||||
fun configExists(): Boolean = configLocation.exists()
|
||||
val exists: Boolean = configLocation.exists()
|
||||
|
||||
/**
|
||||
* Copies the Config file from the resources into the tool's folder
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
package ley.anvil.modpacktools.util
|
||||
|
||||
import com.moandjiezana.toml.Toml
|
||||
import kotlin.reflect.full.functions
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
|
||||
class CustomToml : Toml() {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun Toml.get(key: String): Any? {
|
||||
//Getting Around things being private for no reason 101 (dont look :P)
|
||||
val getFunc = this::class.functions.reduce {a, b -> if(b.name == "get") b else a}
|
||||
getFunc.isAccessible = true
|
||||
return getFunc.call(this, key)
|
||||
val getFunc by lazy {Toml::class.getFun("get")}
|
||||
return getFunc?.call(this, key)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
package ley.anvil.modpacktools.util
|
||||
|
||||
import ley.anvil.addonscript.curse.ManifestJSON
|
||||
import ley.anvil.addonscript.wrapper.FileOrLink
|
||||
|
||||
class ManifestLinksPair {
|
||||
|
||||
var manifest: ManifestJSON? = null
|
||||
var links: MutableMap<FileOrLink, String> = HashMap()
|
||||
|
||||
}
|
|
@ -15,6 +15,10 @@ import java.net.URL
|
|||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.full.functions
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
|
||||
/**
|
||||
* Reads a Json File
|
||||
|
@ -90,6 +94,14 @@ fun URL.sanitize(): URL? {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a function from the receiver and makes it accessible
|
||||
*
|
||||
* @param name the name of the function to get
|
||||
* @receiver the class to get the function from
|
||||
*/
|
||||
fun KClass<*>.getFun(name: String): KFunction<*>? = this.functions.find {it.name == name}?.apply {isAccessible = true}
|
||||
|
||||
fun zipDir(dir: File, parent: String?, zip: ZipOutputStream) {
|
||||
for (file in dir.listFiles()){
|
||||
println(file.name)
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package ley.anvil.modpacktools.util.manifest
|
||||
|
||||
import ley.anvil.addonscript.curse.ManifestJSON
|
||||
import ley.anvil.addonscript.wrapper.ASWrapper
|
||||
|
||||
fun convertAStoManifest(addonscript: ASWrapper): ManifestLinksPair {
|
||||
val ml = ManifestLinksPair()
|
||||
val ver = addonscript.defaultVersion
|
||||
val manifest = ManifestJSON()
|
||||
|
||||
val mcv = ver.version!!.mcversion[0]
|
||||
manifest.minecraft = ManifestJSON.Minecraft()
|
||||
manifest.minecraft.version = mcv
|
||||
manifest.minecraft.modLoaders = mutableListOf()
|
||||
manifest.files = mutableListOf()
|
||||
|
||||
manifest.manifestType = "minecraftModpack"
|
||||
manifest.manifestVersion = 1
|
||||
manifest.name = addonscript.json.meta!!.name ?: addonscript.json.id
|
||||
manifest.version = ver.versionName
|
||||
manifest.author = addonscript.json!!.meta!!.contributors[0].name
|
||||
|
||||
|
||||
for(rel in ver.getRelations(arrayOf("client"), null)) {
|
||||
if(rel.isModloader) {
|
||||
if(rel.relation.id == "forge") {
|
||||
val forge = ManifestJSON.Modloader()
|
||||
forge.primary = true
|
||||
forge.id = "forge-" + rel.versions.latestKnown
|
||||
manifest.minecraft.modLoaders.add(forge)
|
||||
} else {
|
||||
println("Curse only allows Forge as a modloader. ${rel.relation.id} is not allowed!")
|
||||
}
|
||||
} else if(rel.hasFile()) {
|
||||
val file = rel.file
|
||||
//TODO deduplicate this
|
||||
if(file.file.installer == "internal.jar") {
|
||||
println("internal.jar is not supported on Curse")
|
||||
continue
|
||||
} else if(file.isArtifact) {
|
||||
val art = file.artifact
|
||||
if(art.isCurseforge) {
|
||||
val f = ManifestJSON.File()
|
||||
f.fileID = art.fileID
|
||||
f.projectID = art.projectID
|
||||
f.required = rel.options.contains("required")
|
||||
manifest.files.add(f)
|
||||
}
|
||||
} else if(rel.options.contains("required")) {
|
||||
ml.links[file.get()] = file.file.installer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(file in ver.getFiles(arrayOf("client", "required"), null)) {
|
||||
if(file.file.installer == "internal.jar") {
|
||||
println("internal.jar is not supported on Curse")
|
||||
continue
|
||||
} else if(file.isArtifact) {
|
||||
val art = file.artifact
|
||||
if(art.isCurseforge) {
|
||||
val f = ManifestJSON.File()
|
||||
f.fileID = art.fileID
|
||||
f.projectID = art.projectID
|
||||
f.required = true
|
||||
manifest.files.add(f)
|
||||
}
|
||||
} else {
|
||||
ml.links[file.get()] = file.file.installer
|
||||
}
|
||||
}
|
||||
ml.manifest = manifest
|
||||
|
||||
return ml
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package ley.anvil.modpacktools.util.manifest
|
||||
|
||||
import ley.anvil.addonscript.curse.ManifestJSON
|
||||
import ley.anvil.addonscript.wrapper.FileOrLink
|
||||
|
||||
data class ManifestLinksPair (
|
||||
var manifest: ManifestJSON? = null,
|
||||
var links: MutableMap<FileOrLink, String> = mutableMapOf()
|
||||
)
|
21
src/main/resources/commands/createmodlist/style.css
Normal file
21
src/main/resources/commands/createmodlist/style.css
Normal file
|
@ -0,0 +1,21 @@
|
|||
a:link {
|
||||
color: #ff5555;
|
||||
}
|
||||
a:visited {
|
||||
color: #cc55cc;
|
||||
}
|
||||
body {
|
||||
background-color: #333333;
|
||||
color: #ffffff;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
.img {
|
||||
width: 100px;
|
||||
}
|
||||
td {
|
||||
border: #999999 3px;
|
||||
border-style: solid;
|
||||
}
|
||||
.description {
|
||||
width: 100%;
|
||||
}
|
Loading…
Reference in a new issue