commit 031d38affe2c9482a9f5b1c878150c4f073fded0 Author: Finn <83773882+UnlegitDqrk@users.noreply.github.com> Date: Wed Apr 3 17:09:22 2024 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..279c2a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store + +## Run ### +/run/ \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..d8e9561 --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..de4b033 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4f59b0b --- /dev/null +++ b/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + me.finn.tofivem + ToFiveM + 1.0-SNAPSHOT + + + 21 + 21 + UTF-8 + + + \ No newline at end of file diff --git a/src/main/java/me/finn/tofivem/FileManager.java b/src/main/java/me/finn/tofivem/FileManager.java new file mode 100644 index 0000000..7815a16 --- /dev/null +++ b/src/main/java/me/finn/tofivem/FileManager.java @@ -0,0 +1,80 @@ +package me.finn.tofivem; + +import java.io.*; +import java.net.URL; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class FileManager { + + + public static void deleteDirectoryRecursion(File file) { + if (file.exists() && file.isDirectory()) { + File[] entries = file.listFiles(); + if (entries != null) for (File entry : entries) deleteDirectoryRecursion(entry); + } + + if (!file.exists()) { + System.err.println("File '" + file.toPath() + "' does not exists!"); + return; + } + + if (!file.delete()) System.err.println("Failed to delete '" + file.toPath() + "'!"); + } + + public static String getName(String fileName) { + String[] splitName = fileName.split("\\."); + return splitName[splitName.length - 2]; + } + + public static void unzip(File source, String outputDirectory) throws IOException { + try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) { + ZipEntry entry = zis.getNextEntry(); + + while (entry != null) { + File file = new File(outputDirectory, entry.getName()); + + if (entry.isDirectory()) file.mkdirs(); + else { + File parent = file.getParentFile(); + if (!parent.exists()) parent.mkdirs(); + + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) { + int bufferSize = Math.toIntExact(entry.getSize()); + byte[] buffer = new byte[bufferSize > 0 ? bufferSize : 1]; + int location; + + while ((location = zis.read(buffer)) != -1) bos.write(buffer, 0, location); + } + } + + entry = zis.getNextEntry(); + } + } + } + + public static File checkFile(File file, File folder, int stage) { + if (!file.exists()) return file; + + file = new File(folder, stage + file.getName()); + int newStage = stage + 1; + + if (!file.exists()) return file; + else return checkFile(file, folder, newStage); + } + + public static void downloadFile(String urlStr, File outputFile) throws IOException { + URL url = new URL(urlStr); + + BufferedInputStream bufferedInputStream = new BufferedInputStream(url.openStream()); + FileOutputStream fileOutputStream = new FileOutputStream(outputFile); + + byte[] buffer = new byte[1024]; + int count=0; + + while((count = bufferedInputStream.read(buffer,0,1024)) != -1) fileOutputStream.write(buffer, 0, count); + + fileOutputStream.close(); + bufferedInputStream.close(); + } +} diff --git a/src/main/java/me/finn/tofivem/Main.java b/src/main/java/me/finn/tofivem/Main.java new file mode 100644 index 0000000..11fe01c --- /dev/null +++ b/src/main/java/me/finn/tofivem/Main.java @@ -0,0 +1,66 @@ +package me.finn.tofivem; + +import java.io.*; +import java.util.*; + +public class Main { + + public static void main(String[] args) throws IOException, InterruptedException { + Scanner scanner = new Scanner(System.in); + + File filesFolder = new File("files"); + File tempFolder = new File("temp"); + + File gtaUtilFolder = new File("gtautil"); + File gtaUtilZip = new File("gtautil.zip"); + + if (tempFolder.exists()) FileManager.deleteDirectoryRecursion(tempFolder); + + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + scanner.close(); + if (tempFolder.exists()) FileManager.deleteDirectoryRecursion(tempFolder); + if (gtaUtilFolder.exists()) FileManager.deleteDirectoryRecursion(gtaUtilFolder); + })); + + filesFolder.mkdir(); + tempFolder.mkdir(); + gtaUtilFolder.mkdir(); + + FileManager.downloadFile("https://github.com/indilo53/gtautil/releases/download/2.2.7/gtautil-2.2.7.zip", gtaUtilZip); + FileManager.unzip(gtaUtilZip, gtaUtilFolder.getAbsolutePath()); + + gtaUtilZip.delete(); + + System.out.print("Please press 'ANY KEY' when you placed all files in 'files'-Folder!"); + scanner.nextLine(); + System.out.println(System.lineSeparator() + System.lineSeparator()); + + for (File file : filesFolder.listFiles()) initFile(file, gtaUtilFolder, scanner, filesFolder, tempFolder); + } + + public static void initFile(File file, File gtaUtilFolder, Scanner scanner, File filesFolder, File tempFolder) throws IOException, InterruptedException { + System.out.println("Setup: " + file.getName()); + + FileManager.deleteDirectoryRecursion(tempFolder); + tempFolder.mkdir(); + + if (file.isDirectory()) for (File dirFiles : filesFolder.listFiles()) initFile(dirFiles, gtaUtilFolder, scanner, filesFolder, tempFolder); + + File scriptFolder = new File("fivem_" + FileManager.getName(file.getName()).replace(" ", "-")); + File streamFolder = new File(scriptFolder, "stream"); + File dataFolder = new File(scriptFolder, "data"); + File manifestFile = new File(scriptFolder, "fxmanifest.lua"); + + if (!scriptFolder.exists()) scriptFolder.mkdir(); + if (!streamFolder.exists()) streamFolder.mkdir(); + if (!dataFolder.exists()) dataFolder.mkdir(); + if (!manifestFile.exists()) manifestFile.createNewFile(); + + ManifestGenerator.setupManifestFile(manifestFile, scanner); + System.out.println(System.lineSeparator()); + + if (file.getName().endsWith("oiv")) OIVSetup.start(file, gtaUtilFolder, filesFolder, tempFolder, scriptFolder, streamFolder, dataFolder, manifestFile, scanner); + else if (file.getName().endsWith("rpf")) RPFSetup.start(file, gtaUtilFolder, filesFolder, tempFolder, scriptFolder, streamFolder, dataFolder, manifestFile, scanner); + else System.err.println("Unsupported file type!"); + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/tofivem/ManifestGenerator.java b/src/main/java/me/finn/tofivem/ManifestGenerator.java new file mode 100644 index 0000000..ae40f33 --- /dev/null +++ b/src/main/java/me/finn/tofivem/ManifestGenerator.java @@ -0,0 +1,53 @@ +package me.finn.tofivem; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.Scanner; + +public class ManifestGenerator { + + private static String generateManifestFile(String author, String version, String description, boolean useLua54) { + return "-- Generated with ToFiveM by PhoenixV" + System.lineSeparator() + + "fx_version 'cerulean'" + System.lineSeparator() + + (useLua54 ? "lua54 'yes'" + System.lineSeparator() : "") + + "game 'gta5'" + System.lineSeparator() + System.lineSeparator() + + "author 'Original author: " + author + " | Converted by ToFiveM by PhoenixV' -- Do not remove/change this" + System.lineSeparator() + + "description '" + description + "'" + System.lineSeparator() + + "version '" + version + "'"; + } + + public static void setupManifestFile(File manifestFile, Scanner scanner) throws IOException { + System.out.print("Author of original file (Default: Unknown): "); + String author = scanner.nextLine(); + + System.out.print("Version of original file (Default: 1.0.0): "); + String version = scanner.nextLine(); + + System.out.print("Description of original file (Default: Converted by ToFiveM by PhoenixV): "); + String description = scanner.nextLine(); + + if (author.isBlank() || author.isEmpty()) author = "Unknown"; + if (version.isBlank() || version.isEmpty()) version = "1.0.0"; + if (description.isBlank() || description.isEmpty()) description = "Converted by ToFiveM by PhoenixV"; + + Files.writeString(manifestFile.toPath(), generateManifestFile(author, version, description, setupLua54(scanner)), StandardCharsets.UTF_8, StandardOpenOption.WRITE); + } + + private static boolean setupLua54(Scanner scanner) { + System.out.print("Use lua54 (y/N): "); + String answer = scanner.nextLine(); + + if (answer.equalsIgnoreCase("yes") || answer.equalsIgnoreCase("true") || answer.equalsIgnoreCase("1") || + answer.equalsIgnoreCase("y")) return true; + else if (answer.equalsIgnoreCase("no") || answer.equalsIgnoreCase("false") || answer.equalsIgnoreCase("0") || + answer.equalsIgnoreCase("n")) return false; + else { + System.out.println("Wrong answer!"); + return setupLua54(scanner); + } + } + +} diff --git a/src/main/java/me/finn/tofivem/OIVSetup.java b/src/main/java/me/finn/tofivem/OIVSetup.java new file mode 100644 index 0000000..8a1549d --- /dev/null +++ b/src/main/java/me/finn/tofivem/OIVSetup.java @@ -0,0 +1,54 @@ +package me.finn.tofivem; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.Scanner; + +public class OIVSetup { + public static void start(File oivFile, File gtaUtilFolder, File filesFolder, File tempFolder, File scriptFolder, File streamFolder, File dataFolder, File manifestFile, Scanner scanner) throws IOException { + String fileName = oivFile.getName(); + + String newFileName = fileName + ".zip"; + File zipFile = new File(tempFolder, newFileName); + + if (!zipFile.exists()) zipFile.createNewFile(); + + // Creating manifest file and renaming oiv file and unzipping + Files.copy(oivFile.toPath(), zipFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + FileManager.unzip(zipFile, tempFolder.getAbsolutePath()); + + // Moving all files + for (File allContent : tempFolder.listFiles()) { + if (!allContent.isDirectory()) continue; // TODO: Check file type + for (File unzippedFileContent : allContent.listFiles()) { + if (!unzippedFileContent.isDirectory()) continue; // TODO: Check file type + moveFile(streamFolder, unzippedFileContent); + } + } + + System.out.println("Done!" + System.lineSeparator() + System.lineSeparator()); + } + + private static void moveFile(File streamFolder, File unzippedFileContent) throws IOException { + for (File contentFile : unzippedFileContent.listFiles()) { + if (!(contentFile.getName().toLowerCase().endsWith(".ytd") || contentFile.getName().toLowerCase().endsWith(".yft") || + contentFile.getName().toLowerCase().endsWith(".ydr") || contentFile.getName().toLowerCase().endsWith(".png") || + contentFile.getName().toLowerCase().endsWith(".dds") || contentFile.getName().toLowerCase().endsWith(".bmp") || + contentFile.getName().toLowerCase().endsWith(".jpg") || contentFile.getName().toLowerCase().endsWith(".jpeg"))) continue; // TODO: Handle + + if (contentFile.isDirectory()) moveFile(streamFolder, contentFile); + + File targetFile = new File(streamFolder, contentFile.getName()); + File targetContentFile = FileManager.checkFile(targetFile, streamFolder, 1); + + System.out.println("Moving: " + contentFile.toPath()); + System.out.println("To: " + targetContentFile.toPath()); + + Files.copy(contentFile.toPath(), targetContentFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + + System.out.println(System.lineSeparator() + System.lineSeparator() + "Done: " + targetContentFile.toPath()); + } + } +} diff --git a/src/main/java/me/finn/tofivem/RPFSetup.java b/src/main/java/me/finn/tofivem/RPFSetup.java new file mode 100644 index 0000000..a9a875f --- /dev/null +++ b/src/main/java/me/finn/tofivem/RPFSetup.java @@ -0,0 +1,69 @@ +package me.finn.tofivem; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.Scanner; + +public class RPFSetup { + + public static void start(File rpfFile, File gtaUtilFolder, File filesFolder, File tempFolder, File scriptFolder, File streamFolder, File dataFolder, File manifestFile, Scanner scanner) throws IOException, InterruptedException { + String fileName = rpfFile.getName(); + + ProcessBuilder builder = new ProcessBuilder("powershell", "cd '" + gtaUtilFolder.getAbsolutePath() + "' ; " + + "./gtautil extractarchive --input '" + rpfFile.getAbsolutePath() + "' --output '" + scriptFolder.getAbsolutePath() + "'"); + Process process = builder.start(); + process.waitFor(); + + // Moving all files + for (File allContent : tempFolder.listFiles()) { + if (!allContent.isDirectory()) continue; // TODO: Check file type + for (File unzippedFileContent : allContent.listFiles()) { + if (!unzippedFileContent.isDirectory()) continue; // TODO: Check file type + moveFile(streamFolder, dataFolder, unzippedFileContent); + } + } + + System.out.println("Done!" + System.lineSeparator() + System.lineSeparator()); + } + + private static void moveFile(File streamFolder, File dataFolder, File unzippedFileContent) throws IOException { + for (File contentFile : unzippedFileContent.listFiles()) { + if (!(contentFile.getName().toLowerCase().endsWith("meta") || contentFile.getName().toLowerCase().endsWith("ytd") || + contentFile.getName().toLowerCase().endsWith("ydr") || contentFile.getName().toLowerCase().endsWith("yft") || + contentFile.getName().toLowerCase().endsWith(".png") || contentFile.getName().toLowerCase().endsWith(".dds") || + contentFile.getName().toLowerCase().endsWith(".bmp") || contentFile.getName().toLowerCase().endsWith(".jpg") || + contentFile.getName().toLowerCase().endsWith(".jpeg"))) continue; // TODO: Handle + + if (contentFile.isDirectory()) moveFile(streamFolder, dataFolder, contentFile); + + if (contentFile.getName().toLowerCase().endsWith("meta")) { + File targetFile = new File(dataFolder, contentFile.getName()); + File targetContentFile = FileManager.checkFile(targetFile, dataFolder, 1); + + System.out.println("Moving: " + contentFile.toPath()); + System.out.println("To: " + targetContentFile.toPath()); + + Files.copy(contentFile.toPath(), targetContentFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + System.out.println(System.lineSeparator() + System.lineSeparator() + "Done: " + targetContentFile.toPath()); + } + + if (contentFile.getName().toLowerCase().endsWith(".ytd") || contentFile.getName().toLowerCase().endsWith(".yft") || + contentFile.getName().toLowerCase().endsWith(".ydr") || contentFile.getName().toLowerCase().endsWith(".png") || + contentFile.getName().toLowerCase().endsWith(".dds") || contentFile.getName().toLowerCase().endsWith(".bmp") || + contentFile.getName().toLowerCase().endsWith(".jpg") || contentFile.getName().toLowerCase().endsWith(".jpeg")) { + + File targetFile = new File(streamFolder, contentFile.getName()); + File targetContentFile = FileManager.checkFile(targetFile, streamFolder, 1); + + System.out.println("Moving: " + contentFile.toPath()); + System.out.println("To: " + targetContentFile.toPath()); + + Files.copy(contentFile.toPath(), targetContentFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + System.out.println(System.lineSeparator() + System.lineSeparator() + "Done: " + targetContentFile.toPath()); + } + } + } + +}