Created
June 30, 2020 19:15
-
-
Save lmcintyre/be5f1dd03574f97873cffca7b38c3558 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.fragmenterworks.ffxivextract; | |
import com.fragmenterworks.ffxivextract.models.SqPack_IndexFile; | |
import com.fragmenterworks.ffxivextract.storage.HashDatabase; | |
import java.io.*; | |
import java.nio.file.*; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
public class MassPathSearcher { | |
private static final String basePath = "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\"; | |
private static SqPack_IndexFile currentIndexFile; | |
private static String loadedCat = ""; | |
static int lastFolder = 0; | |
static int lastFile = 0; | |
private static HashMap<String, String> folderToIndexMap = new HashMap<String, String>() {{1 | |
put("common", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\000000.win32.index"); | |
put("bgcommon", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\010000.win32.index"); | |
put("bg", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\020000.win32.index"); | |
put("cut", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\030000.win32.index"); | |
put("chara", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\040000.win32.index"); | |
put("shader", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\050000.win32.index"); | |
put("ui", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\060000.win32.index"); | |
put("sound", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\070000.win32.index"); | |
put("vfx", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\080000.win32.index"); | |
// put("ui_script", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\090000.win32.index"); | |
put("exd", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\0A0000.win32.index"); | |
put("game_script", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\0B0000.win32.index"); | |
// put("test", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\120000.win32.index"); | |
put("_debug", "C:\\Program Files (x86)\\SquareEnix\\Final Fantasy XIV - A Realm Reborn\\game\\sqpack\\ffxiv\\130000.win32.index"); | |
}}; | |
private static String[] categories = new String[] { | |
"common", | |
"bgcommon", | |
"bg", | |
"cut", | |
"chara", | |
"shader", | |
"ui", | |
"sound", | |
"vfx", | |
// "ui_script", | |
"exd", | |
// "game_script", | |
"test", | |
"_debug" | |
}; | |
private static HashMap<String, char[]> preCatBlackListMap = new HashMap<String, char[]>() {{ | |
put("common/", new char[] {'g', '/'}); | |
put("bg/", new char[] {'_'}); | |
put("vfx/", new char[] {'_', '/'}); | |
put("sound/", new char[] {'_'}); | |
}}; | |
public static void main(String[] args) throws Exception { | |
HashDatabase.init(); | |
String outpath = "C:\\Users\\Liam\\Desktop\\MassSearch\\"; | |
// for (String cat : categories) { | |
for (int i = 0; i < categories.length; i++) { | |
String cat = categories[i]; | |
loadIndexForCategory(cat); | |
// for (String cat2 : categories) { | |
String cat2 = "ex1"; | |
String catOut = outpath + "search_" + cat + "_" + cat2 + ".txt"; | |
List<String> results = doStringSearch(cat2 + "/"); | |
Files.write(Paths.get(catOut), results); | |
System.out.println("\nwrote " + results.size() + " paths to " + catOut); | |
// } | |
} | |
} | |
private static List<String> doStringSearch(String string) { | |
ArrayList<String> matches = new ArrayList<>(); | |
for (int i = lastFolder; i < currentIndexFile.getPackFolders().length; i++) { | |
SqPack_IndexFile.SqPack_Folder f = currentIndexFile.getPackFolders()[i]; | |
for (int j = lastFile; j < f.getFiles().length; j++) { | |
SqPack_IndexFile.SqPack_File fi = f.getFiles()[j]; | |
byte[] data; | |
try { | |
data = currentIndexFile.extractFile(fi.dataoffset, null); | |
// System.out.print("."); | |
if (data == null) | |
continue; | |
for (int i2 = 0; i2 < data.length - string.length(); i2++) { | |
for (int j2 = 0; j2 < string.length(); j2++) { | |
if (Character.toLowerCase(data[i2 + j2]) == Character.toLowerCase(string.charAt(j2))) { | |
if (j2 == string.length() - 1 && prevCharValid(string, (char) data[i2 - 1])) { | |
int length = 100; | |
StringBuilder sbpre = new StringBuilder(); | |
StringBuilder sbpost = new StringBuilder(); | |
try { | |
for (int q = 1; q < length && (char) Character.toLowerCase(data[i2 + j2 + q]) != '\u0000'; q++) | |
sbpost.append((char) Character.toLowerCase(data[i2 + j2 + q])); | |
for (int q = 1; q < length && (char) Character.toLowerCase(data[i2 - q]) != '\u0000'; q++) | |
sbpre.append((char) Character.toLowerCase(data[i2 - q])); | |
} catch (IndexOutOfBoundsException ignored) {} | |
String path = clean(sbpre.reverse().toString().concat(string.concat(sbpost.toString()))); | |
// String path = clean(string.concat(sbpost.toString())); | |
matches.add(path); | |
} | |
} else | |
break; | |
} | |
} | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
} | |
} | |
return matches; | |
} | |
private static boolean prevCharValid(String cat, char prev) { | |
char[] map = preCatBlackListMap.getOrDefault(cat, null); | |
if (map == null) | |
return true; | |
else | |
for (char p : map) | |
if (prev == p) | |
return false; | |
return true; | |
} | |
private static String clean(String toClean) { | |
// strips off all non-ASCII characters | |
toClean = toClean.replaceAll("[^\\x00-\\x7F]", ""); | |
// erases all the ASCII control characters | |
toClean = toClean.replaceAll("[\\p{Cntrl}&&[^\r\n\t]]", ""); | |
// removes non-printable characters from Unicode | |
toClean = toClean.replaceAll("\\p{C}", ""); | |
return toClean.trim(); | |
} | |
private static String getCategory(String path) { | |
int index = path.indexOf("/"); | |
if (index < 0) | |
return "null"; | |
return path.substring(0, index); | |
} | |
private static boolean isCategoryValid(String path) { | |
String cat = getCategory(path); | |
return cat.equalsIgnoreCase("chara") || | |
cat.equalsIgnoreCase("bg") || | |
cat.equalsIgnoreCase("common") || | |
cat.equalsIgnoreCase("bgcommon") || | |
cat.equalsIgnoreCase("cut") || | |
cat.equalsIgnoreCase("shader") || | |
cat.equalsIgnoreCase("ui") || | |
cat.equalsIgnoreCase("sound") || | |
cat.equalsIgnoreCase("vfx") || | |
cat.equalsIgnoreCase("ui_script") || | |
cat.equalsIgnoreCase("exd") || | |
cat.equalsIgnoreCase("game_script") || | |
cat.equalsIgnoreCase("_debug"); | |
} | |
private static void loadIndexForCategory(String cat) throws Exception { | |
String path = folderToIndexMap.get(cat); | |
currentIndexFile = new SqPack_IndexFile(path, false); | |
loadedCat = cat; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment