You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@BloodWorkXGaming Kannst du das Vlt. fixen???
I went on for 3 Hours making an older version of this compatible with the new API
and now i am here to see it has already been done???
aww man i need to sleep now
i literally sat there for 4 hours implementing the new api because i thought i had to do it myself...
anyways i did this:
--- Edit -> I downloaded the serverstarter from here to find out my pain was not in vain
The following is a Problem:
the page you used in your project as an api got removed
I edited the code so that this Error:
[12:31:02] [ERROR] Error while trying to get URL from cursemeta for mod ModEntryRaw(projectID=405744, fileID=3296428)
java.io.IOException: Request to https://cursemeta.dries007.net/405744/3296428.json was not successful.
at atm.bloodworkxgaming.serverstarter.packtype.curse.CursePackType.downloadMods$lambda-3(CursePackType.kt:203)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:754)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Does not happen anymore
you may use this code in your project
you are welcome
(maaan i really felt so dumb when i read the latest push: moved to new api, But it turns out i wasn't wrong...)
package atm.bloodworkxgaming.serverstarter.packtype.curse
import atm.bloodworkxgaming.serverstarter.InternetManager
import atm.bloodworkxgaming.serverstarter.ServerStarter.Companion.LOGGER
import atm.bloodworkxgaming.serverstarter.config.ConfigFile
import atm.bloodworkxgaming.serverstarter.packtype.AbstractZipbasedPackType
import atm.bloodworkxgaming.serverstarter.packtype.writeToFile
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import okhttp3.Request
import org.apache.commons.io.FileUtils
import org.apache.commons.io.FilenameUtils
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.io.InputStreamReader
import java.net.URISyntaxException
import java.nio.file.PathMatcher
import java.nio.file.Paths
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicInteger
import java.util.regex.Pattern
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
open class CursePackType(private val configFile: ConfigFile) : AbstractZipbasedPackType(configFile) {
private var forgeVersion: String = configFile.install.loaderVersion
private var mcVersion: String = configFile.install.mcVersion
private val oldFiles = File(basePath + "OLD_TO_DELETE/")
override fun cleanUrl(url: String): String {
if (url.contains("curseforge.com") && !url.endsWith("/download"))
return "$url/download"
return url
}
/**
* Gets the forge version, can be based on the version from the downloaded pack
*
* @return String representation of the version
*/
override fun getForgeVersion(): String {
return forgeVersion
}
/**
* Gets the forge version, can be based on the version from the downloaded pack
*
* @return String representation of the version
*/
override fun getMCVersion(): String {
return mcVersion
}
@Throws(IOException::class)
override fun handleZip(file: File, pathMatchers: List<PathMatcher>) {
// delete old installer folder
FileUtils.deleteDirectory(oldFiles)
// start with deleting the mods folder as it is not guaranteed to have override mods
val modsFolder = File(basePath + "mods/")
if (modsFolder.exists())
FileUtils.moveDirectory(modsFolder, File(oldFiles, "mods"))
LOGGER.info("Moved the mods folder")
LOGGER.info("Starting to unzip files.")
// unzip start
try {
ZipInputStream(FileInputStream(file)).use { zis ->
var entry: ZipEntry? = zis.nextEntry
loop@ while (entry != null) {
LOGGER.info("Entry in zip: $entry", true)
val name = entry.name
// special manifest treatment
if (name == "manifest.json")
zis.writeToFile(File(basePath + "manifest.json"))
// overrides
if (name.startsWith("overrides/")) {
val path = entry.name.substring(10)
when {
pathMatchers.any { it.matches(Paths.get(path)) } ->
LOGGER.info("Skipping $path as it is on the ignore List.", true)
!name.endsWith("/") -> {
val outfile = File(basePath + path)
LOGGER.info("Copying zip entry to = $outfile", true)
outfile.parentFile?.mkdirs()
zis.writeToFile(outfile)
}
name != "overrides/" -> {
val newFolder = File(basePath + path)
if (newFolder.exists())
FileUtils.moveDirectory(newFolder, File(oldFiles, path))
LOGGER.info("Folder moved: " + newFolder.absolutePath, true)
}
}
}
entry = zis.nextEntry
}
zis.closeEntry()
}
} catch (e: IOException) {
LOGGER.error("Could not unzip files", e)
}
LOGGER.info("Done unzipping the files.")
}
@Throws(IOException::class)
override fun postProcessing() {
val mods = ArrayList<ModEntryRaw>()
InputStreamReader(FileInputStream(File(basePath + "manifest.json")), "utf-8").use { reader ->
val json = JsonParser().parse(reader).asJsonObject
LOGGER.info("manifest JSON Object: $json", true)
val mcObj = json.getAsJsonObject("minecraft")
if (mcVersion.isEmpty()) {
mcVersion = mcObj.getAsJsonPrimitive("version").asString
}
// gets the forge version
if (forgeVersion.isEmpty()) {
val loaders = mcObj.getAsJsonArray("modLoaders")
if (loaders.size() > 0) {
forgeVersion = loaders[0].asJsonObject.getAsJsonPrimitive("id").asString.substring(6)
}
}
// gets all the mods
for (jsonElement in json.getAsJsonArray("files")) {
val obj = jsonElement.asJsonObject
mods.add(ModEntryRaw(
obj.getAsJsonPrimitive("projectID").asString,
obj.getAsJsonPrimitive("fileID").asString))
}
}
downloadMods(mods)
}
/**
* Downloads the mods specified in the manifest
* Gets the data from cursemeta
*
* @param mods List of the mods from the manifest
*/
private fun downloadMods(mods: List<ModEntryRaw>) {
val ignoreSet = HashSet<String>()
val ignoreListTemp = configFile.install.getFormatSpecificSettingOrDefault<List<Any>>("ignoreProject", null)
if (ignoreListTemp != null)
for (o in ignoreListTemp) {
if (o is String)
ignoreSet.add(o)
if (o is Int)
ignoreSet.add(o.toString())
}
val urls = ConcurrentLinkedQueue<String>()
LOGGER.info("Requesting Download links from cursemeta.")
mods.parallelStream().forEach { mod ->
if (ignoreSet.isNotEmpty() && ignoreSet.contains(mod.projectID)) {
LOGGER.info("Skipping mod with projectID: " + mod.projectID)
return@forEach
}
val url = "https://api.cfwidget.com/${mod.projectID}?version=${mod.fileID}"
LOGGER.info("Download url is: $url", true)
try {
val request = Request.Builder()
.url(url)
.header("User-Agent", "All the mods server installer.")
.header("Content-Type", "application/json")
.build()
val res = InternetManager.httpClient.newCall(request).execute()
if (!res.isSuccessful)
throw IOException("Request to $url was not successful.")
val body = res.body ?: throw IOException("Request to $url returned a null body.")
try {
val jsonRes = JsonParser().parse(body.string()).asJsonObject
LOGGER.info("Response from manifest query: $jsonRes", true)
var arr = jsonRes.asJsonObject.getAsJsonObject("download");
var part1 = mod.fileID.subSequence(0, 4).toString();
var part2 = mod.fileID.split(part1)[1];
// https://mediafilez.forgecdn.net/files/2743/38/useful_backpacks-1.16.5-1.12.1.90.jar
// https://mediafilez.forgecdn.net/files/3350/860/useful_backpacks-1.16.5-1.12.1.90.jar
// https://mediafilez.forgecdn.net/files/3871/353/MouseTweaks-forge-mc1.19-2.23.jar
// https://mediafilez.forgecdn.net/files/3398//CosmeticArmorReworked-1.16.5-v4.jar
// https://mediafilez.forgecdn.net/files/3398/0/CosmeticArmorReworked-1.16.5-v4.jar
// https://mediafilez.forgecdn.net/files/3407/020/archers_paradox-1.16.5-1.3.1.jar
// https://mediafilez.forgecdn.net/files/3407/20/archers_paradox-1.16.5-1.3.1.jar
val regx = "^0+\$".toRegex();
if(!regx.containsMatchIn(part2))
part2 = part2.replace("^0*".toRegex(),"");
else
part2 = "0";
var url = "https://mediafilez.forgecdn.net/files/$part1/$part2/${arr["name"].asString.replace("+","%2B")}"
LOGGER.info(url)
urls.add(url)
}
catch(e:Exception)
{
}
} catch (e: IOException) {
LOGGER.error("Error while trying to get URL from cursemeta for mod $mod", e)
}
}
LOGGER.info("Mods to download: $urls", true)
processMods(urls)
}
/**
* Downloads all mods, with a second fallback if failed
* This is done in parallel for better performance
*
* @param mods List of urls
*/
private fun processMods(mods: Collection<String>) {
// constructs the ignore list
val ignorePatterns = ArrayList<Pattern>()
for (ignoreFile in configFile.install.ignoreFiles) {
if (ignoreFile.startsWith("mods/")) {
ignorePatterns.add(Pattern.compile(ignoreFile.substring(ignoreFile.lastIndexOf('/'))))
}
}
// downloads the mods
val count = AtomicInteger(0)
val totalCount = mods.size
val fallbackList = ArrayList<String>()
mods.stream().parallel().forEach { s -> processSingleMod(s, count, totalCount, fallbackList, ignorePatterns) }
val secondFail = ArrayList<String>()
fallbackList.forEach { s -> processSingleMod(s, count, totalCount, secondFail, ignorePatterns) }
if (secondFail.isNotEmpty()) {
LOGGER.warn("Failed to download (a) mod(s):")
for (s in secondFail) {
LOGGER.warn("\t" + s)
}
}
}
/**
* Downloads a single mod and saves to the /mods directory
*
* @param mod URL of the mod
* @param counter current counter of how many mods have already been downloaded
* @param totalCount total count of mods that have to be downloaded
* @param fallbackList List to write to when it failed
* @param ignorePatterns Patterns of mods which should be ignored
*/
private fun processSingleMod(mod: String, counter: AtomicInteger, totalCount: Int, fallbackList: MutableList<String>, ignorePatterns: List<Pattern>) {
try {
val modName = FilenameUtils.getName(mod)
for (ignorePattern in ignorePatterns) {
if (ignorePattern.matcher(modName).matches()) {
LOGGER.info("[" + counter.incrementAndGet() + "/" + totalCount + "] Skipped ignored mod: " + modName)
}
}
InternetManager.downloadToFile(mod, File(basePath + "mods/" + modName))
LOGGER.info("[" + String.format("% 3d", counter.incrementAndGet()) + "/" + totalCount + "] Downloaded mod: " + modName)
} catch (e: IOException) {
LOGGER.error("Failed to download mod", e)
fallbackList.add(mod)
} catch (e: URISyntaxException) {
LOGGER.error("Invalid url for $mod", e)
}
}
}
/**
* Data class to keep projectID and fileID together
*/
data class ModEntryRaw(val projectID: String, val fileID: String)
The text was updated successfully, but these errors were encountered:
anonymusdennis
changed the title
Are you kidding me
Are you kidding me... no you not (FIX FOR API REMOVAL)
Nov 26, 2022
@BloodWorkXGaming Kannst du das Vlt. fixen???
I went on for 3 Hours making an older version of this compatible with the new API
and now i am here to see it has already been done???
aww man i need to sleep now
i literally sat there for 4 hours implementing the new api because i thought i had to do it myself...
anyways i did this:
--- Edit -> I downloaded the serverstarter from here to find out my pain was not in vain
The following is a Problem:
the page you used in your project as an api got removed
I edited the code so that this Error:
Does not happen anymore
you may use this code in your project
you are welcome
(maaan i really felt so dumb when i read the latest push: moved to new api, But it turns out i wasn't wrong...)
The text was updated successfully, but these errors were encountered: