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());
+ }
+ }
+ }
+
+}