mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-04-12 18:30:26 +08:00
HMCL modpack output model
This commit is contained in:
parent
d83291eac0
commit
86cef86fc9
@ -22,12 +22,21 @@ import org.jackhuang.hmcl.download.game.VersionJSONSaveTask
|
||||
import org.jackhuang.hmcl.mod.Modpack
|
||||
import org.jackhuang.hmcl.setting.Profile
|
||||
import org.jackhuang.hmcl.task.Task
|
||||
import org.jackhuang.hmcl.util.GSON
|
||||
import org.jackhuang.hmcl.util.fromJson
|
||||
import org.jackhuang.hmcl.util.readTextFromZipFile
|
||||
import org.jackhuang.hmcl.util.unzipSubDirectory
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import sun.misc.IOUtils
|
||||
import jdk.nashorn.internal.objects.NativeFunction.call
|
||||
import org.jackhuang.hmcl.task.TaskResult
|
||||
import org.jackhuang.hmcl.util.*
|
||||
import sun.plugin2.util.PojoUtil.toJson
|
||||
import sun.tools.jar.resources.jar
|
||||
import java.util.Collections.addAll
|
||||
import java.util.ArrayList
|
||||
import java.util.Arrays
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read the manifest in a HMCL modpack.
|
||||
@ -70,4 +79,43 @@ class HMCLModpackInstallTask(profile: Profile, private val zipFile: File, privat
|
||||
if (repository.getVersionJson(name) != json)
|
||||
json.delete()
|
||||
}
|
||||
}
|
||||
|
||||
val MODPACK_BLACK_LIST = listOf("usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "AMD", "TCNodeTracker", "screenshots", "natives", "native", "\$native", "pack.json", "launcher.jar", "minetweaker.log", "launcher.pack.lzma", "hmclmc.log")
|
||||
val MODPACK_SUGGESTED_BLACK_LIST = listOf("fonts", "saves", "servers.dat", "options.txt", "optionsof.txt", "journeymap", "optionsshaders.txt", "mods/VoxelMods")
|
||||
|
||||
class HMCLModpackExportTask @JvmOverloads constructor(
|
||||
private val repository: DefaultGameRepository,
|
||||
private val version: String,
|
||||
private val blacklist: List<String>,
|
||||
private val modpack: Modpack,
|
||||
private val output: File,
|
||||
override val id: String = ID): TaskResult<ZipEngine>() {
|
||||
override fun execute() {
|
||||
val b = ArrayList<String>(MODPACK_BLACK_LIST)
|
||||
b.addAll(blacklist)
|
||||
b.add(version + ".jar")
|
||||
b.add(version + ".json")
|
||||
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker")
|
||||
ZipEngine(output).use { zip ->
|
||||
zip.putDirectory(repository.getRunDirectory(version)) a@ { x: String, y: Boolean ->
|
||||
for (s in b)
|
||||
if (y) {
|
||||
if (x.startsWith(s + "/"))
|
||||
return@a null
|
||||
} else if (x == s)
|
||||
return@a null
|
||||
"minecraft/" + x
|
||||
}
|
||||
|
||||
val mv = repository.getVersion(version).resolve(repository)
|
||||
val gameVersion = minecraftVersion(repository.getVersionJar(version)) ?: throw IllegalStateException("Cannot parse the version of $version")
|
||||
zip.putTextFile(GSON.toJson(mv), "minecraft/pack.json")
|
||||
zip.putTextFile(GSON.toJson(modpack.copy(gameVersion = gameVersion)), "modpack.json")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = "zip_engine"
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ data class Modpack @JvmOverloads constructor(
|
||||
val name: String = "",
|
||||
val author: String = "",
|
||||
val version: String = "",
|
||||
val gameVersion: String = "",
|
||||
val description: String = "",
|
||||
val manifest: Any? = null
|
||||
)
|
126
HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/ZipEngine.kt
Normal file
126
HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/ZipEngine.kt
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* 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 {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util
|
||||
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.HashSet
|
||||
import java.io.*
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
|
||||
/**
|
||||
* Non thread-safe
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
class ZipEngine
|
||||
@Throws(IOException::class)
|
||||
constructor(f: File) : Closeable {
|
||||
|
||||
val buf = ByteArray(1024)
|
||||
val zos: ZipOutputStream = ZipOutputStream(BufferedOutputStream(f.outputStream()))
|
||||
private val names = HashSet<String>()
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun close() {
|
||||
zos.closeEntry()
|
||||
zos.close()
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件
|
||||
*
|
||||
* @param sourceDir 源文件夹
|
||||
* @param pathNameCallback callback(pathName, isDirectory) returns your
|
||||
* modified pathName
|
||||
*
|
||||
* @throws java.io.IOException 压缩失败或无法读取
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
@JvmOverloads
|
||||
fun putDirectory(sourceDir: File, pathNameCallback: ((String, Boolean) -> String?)? = null) {
|
||||
putDirectoryImpl(sourceDir, if (sourceDir.isDirectory) sourceDir.path else sourceDir.parent, pathNameCallback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件压缩成zip文件
|
||||
*
|
||||
* @param source zip文件路径
|
||||
* @param basePath 待压缩文件根目录
|
||||
* @param zos zip文件的os
|
||||
* @param pathNameCallback callback(pathName, isDirectory) returns your
|
||||
* modified pathName, null if you dont want this file zipped
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
private fun putDirectoryImpl(source: File, basePath: String, pathNameCallback: ((String, Boolean) -> String?)?) {
|
||||
val files: Array<File>?
|
||||
if (source.isDirectory)
|
||||
files = source.listFiles()
|
||||
else
|
||||
files = arrayOf(source)
|
||||
if (files == null)
|
||||
return
|
||||
var pathName: String? //存相对路径(相对于待压缩的根目录)
|
||||
for (file in files)
|
||||
if (file.isDirectory) {
|
||||
pathName = file.path.substring(basePath.length + 1) + "/"
|
||||
pathName = pathName.replace('\\', '/')
|
||||
if (pathNameCallback != null)
|
||||
pathName = pathNameCallback(pathName, true)
|
||||
if (pathName == null)
|
||||
continue
|
||||
put(ZipEntry(pathName))
|
||||
putDirectoryImpl(file, basePath, pathNameCallback)
|
||||
} else {
|
||||
if (".DS_Store" == file.name) // For Mac computers.
|
||||
continue
|
||||
pathName = file.path.substring(basePath.length + 1)
|
||||
pathName = pathName.replace('\\', '/')
|
||||
if (pathNameCallback != null)
|
||||
pathName = pathNameCallback(pathName, false)
|
||||
if (pathName == null)
|
||||
continue
|
||||
putFile(file, pathName)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun putFile(file: File, pathName: String) =
|
||||
file.inputStream().use { putStream(it, pathName) }
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun putStream(inputStream: InputStream, pathName: String) {
|
||||
put(ZipEntry(pathName))
|
||||
inputStream.copyTo(zos, buf)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun putTextFile(text: String, pathName: String) =
|
||||
putTextFile(text, "UTF-8", pathName)
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun putTextFile(text: String, encoding: String, pathName: String) =
|
||||
putStream(ByteArrayInputStream(text.toByteArray(charset(encoding))), pathName)
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun put(entry: ZipEntry) {
|
||||
if (names.add(entry.name))
|
||||
zos.putNextEntry(entry)
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user