Initial commit
This commit is contained in:
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@@ -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/
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -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
|
7
.idea/discord.xml
generated
Normal file
7
.idea/discord.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="PROJECT_FILES" />
|
||||
<option name="description" value="" />
|
||||
</component>
|
||||
</project>
|
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
15
.idea/misc.xml
generated
Normal file
15
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="workspaceImportForciblyTurnedOn" value="true" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
17
pom.xml
Normal file
17
pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>me.finn.tofivem</groupId>
|
||||
<artifactId>ToFiveM</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
80
src/main/java/me/finn/tofivem/FileManager.java
Normal file
80
src/main/java/me/finn/tofivem/FileManager.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
66
src/main/java/me/finn/tofivem/Main.java
Normal file
66
src/main/java/me/finn/tofivem/Main.java
Normal file
@@ -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!");
|
||||
}
|
||||
}
|
53
src/main/java/me/finn/tofivem/ManifestGenerator.java
Normal file
53
src/main/java/me/finn/tofivem/ManifestGenerator.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
54
src/main/java/me/finn/tofivem/OIVSetup.java
Normal file
54
src/main/java/me/finn/tofivem/OIVSetup.java
Normal file
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
69
src/main/java/me/finn/tofivem/RPFSetup.java
Normal file
69
src/main/java/me/finn/tofivem/RPFSetup.java
Normal file
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user