Launcher/LaunchServer/src/main/java/pro/gravit/launchserver/binary/BuildContext.java

188 lines
7.1 KiB
Java
Raw Normal View History

package pro.gravit.launchserver.binary;
2018-09-19 16:14:50 +03:00
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.launcher.serialize.stream.StreamObject;
2019-10-19 19:46:04 +03:00
import pro.gravit.launchserver.binary.tasks.MainBuildTask;
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper;
import pro.gravit.utils.helper.SecurityHelper;
2019-10-19 19:46:04 +03:00
2018-09-19 16:14:50 +03:00
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
2018-09-19 16:29:31 +03:00
import java.util.Set;
import java.util.function.Predicate;
import java.util.jar.JarFile;
2018-09-19 16:14:50 +03:00
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
2018-09-19 16:14:50 +03:00
import java.util.zip.ZipOutputStream;
import static pro.gravit.utils.helper.IOHelper.UNICODE_CHARSET;
import static pro.gravit.utils.helper.IOHelper.newZipEntry;
2018-09-19 16:14:50 +03:00
public class BuildContext {
public final ZipOutputStream output;
public final List<JarFile> readerClassPath;
public final MainBuildTask task;
public final HashSet<String> fileList;
public final HashSet<String> clientModules;
public BuildContext(ZipOutputStream output, List<JarFile> readerClassPath, MainBuildTask task) {
2018-09-19 16:14:50 +03:00
this.output = output;
this.readerClassPath = readerClassPath;
this.task = task;
fileList = new HashSet<>(1024);
clientModules = new HashSet<>();
2018-09-19 16:14:50 +03:00
}
2018-09-22 17:33:00 +03:00
public void pushFile(String filename, InputStream inputStream) throws IOException {
2018-09-19 16:14:50 +03:00
ZipEntry zip = IOHelper.newZipEntry(filename);
output.putNextEntry(zip);
2018-09-22 17:33:00 +03:00
IOHelper.transfer(inputStream, output);
output.closeEntry();
fileList.add(filename);
}
2020-04-05 10:27:04 +03:00
public void pushFile(String filename, StreamObject object) throws IOException {
ZipEntry zip = IOHelper.newZipEntry(filename);
output.putNextEntry(zip);
object.write(new HOutput(output));
output.closeEntry();
fileList.add(filename);
}
2020-04-05 10:27:04 +03:00
public void pushFile(String filename, Object object, Type type) throws IOException {
String bytes = Launcher.gsonManager.gson.toJson(object, type);
pushBytes(filename, bytes.getBytes(UNICODE_CHARSET));
}
2020-04-05 10:27:04 +03:00
public void pushDir(Path dir, String targetDir, Map<String, byte[]> hashMap, boolean hidden) throws IOException {
IOHelper.walk(dir, new RuntimeDirVisitor(output, hashMap, dir, targetDir), hidden);
}
public void pushBytes(String filename, byte[] bytes) throws IOException {
ZipEntry zip = IOHelper.newZipEntry(filename);
output.putNextEntry(zip);
output.write(bytes);
output.closeEntry();
fileList.add(filename);
2018-09-19 16:14:50 +03:00
}
2020-04-05 10:27:04 +03:00
@Deprecated
public void pushJarFile(ZipInputStream input) throws IOException {
2018-09-19 16:14:50 +03:00
ZipEntry e = input.getNextEntry();
while (e != null) {
if (fileList.contains(e.getName())) {
e = input.getNextEntry();
continue;
}
2018-12-26 16:17:47 +03:00
output.putNextEntry(IOHelper.newZipEntry(e));
2018-09-22 17:33:00 +03:00
IOHelper.transfer(input, output);
fileList.add(e.getName());
2018-09-19 16:14:50 +03:00
e = input.getNextEntry();
}
}
2020-04-05 10:27:04 +03:00
@Deprecated
public void pushJarFile(ZipInputStream input, Set<String> blacklist) throws IOException {
2018-09-19 16:29:31 +03:00
ZipEntry e = input.getNextEntry();
while (e != null) {
2019-09-30 10:01:41 +03:00
if (fileList.contains(e.getName()) || blacklist.contains(e.getName())) {
2018-09-19 16:29:31 +03:00
e = input.getNextEntry();
continue;
}
2018-12-26 16:17:47 +03:00
output.putNextEntry(IOHelper.newZipEntry(e));
2018-09-22 17:33:00 +03:00
IOHelper.transfer(input, output);
fileList.add(e.getName());
2018-09-19 16:29:31 +03:00
e = input.getNextEntry();
}
}
2020-04-05 10:27:04 +03:00
public void pushJarFile(Path jarfile, Predicate<ZipEntry> filter, Predicate<String> needTransform) throws IOException {
pushJarFile(jarfile.toUri().toURL(), filter, needTransform);
}
2020-04-05 10:27:04 +03:00
public void pushJarFile(URL jarfile, Predicate<ZipEntry> filter, Predicate<String> needTransform) throws IOException {
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(jarfile))) {
ZipEntry e = input.getNextEntry();
2020-04-05 10:27:04 +03:00
while (e != null) {
String filename = e.getName();
2020-04-05 10:27:04 +03:00
if (e.isDirectory() || fileList.contains(filename) || filter.test(e)) {
e = input.getNextEntry();
continue;
}
try {
output.putNextEntry(IOHelper.newZipEntry(e));
} catch (ZipException ex) {
LogHelper.warning("Write %s failed: %s", filename, ex.getMessage() == null ? "null" : ex.getMessage());
e = input.getNextEntry();
continue;
}
if (filename.endsWith(".class")) {
String classname = filename.replace('/', '.').substring(0,
filename.length() - ".class".length());
2020-04-05 10:27:04 +03:00
if (!needTransform.test(classname)) {
IOHelper.transfer(input, output);
2020-04-05 10:27:04 +03:00
} else {
byte[] bytes = IOHelper.read(input);
bytes = task.transformClass(bytes, classname, this);
output.write(bytes);
}
} else
IOHelper.transfer(input, output);
fileList.add(filename);
e = input.getNextEntry();
}
}
}
2020-04-05 10:27:04 +03:00
private final static class RuntimeDirVisitor extends SimpleFileVisitor<Path> {
private final ZipOutputStream output;
private final Map<String, byte[]> hashs;
private final Path sourceDir;
private final String targetDir;
private RuntimeDirVisitor(ZipOutputStream output, Map<String, byte[]> hashs, Path sourceDir, String targetDir) {
this.output = output;
this.hashs = hashs;
this.sourceDir = sourceDir;
this.targetDir = targetDir;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
String dirName = IOHelper.toString(sourceDir.relativize(dir));
output.putNextEntry(newEntry(dirName + '/'));
return super.preVisitDirectory(dir, attrs);
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String fileName = IOHelper.toString(sourceDir.relativize(file));
if (hashs != null)
hashs.put(fileName, SecurityHelper.digest(SecurityHelper.DigestAlgorithm.MD5, file));
// Create zip entry and transfer contents
output.putNextEntry(newEntry(fileName));
IOHelper.transfer(file, output);
// Return result
return super.visitFile(file, attrs);
}
private ZipEntry newEntry(String fileName) {
return newZipEntry(targetDir + IOHelper.CROSS_SEPARATOR + fileName);
}
}
2018-09-19 16:14:50 +03:00
}