MCPcopy Create free account
hub / github.com/Shazbot/WH3-Mod-Manager / mergeMods

Function mergeMods

src/packFileSerializer.ts:922–1014  ·  view source on GitHub ↗
(mods: Mod[], existingPath?: string)

Source from the content-addressed store, hash-verified

920 return compareModNames(packFirst.name, packSecond.name);
921};
922export const mergeMods = async (mods: Mod[], existingPath?: string) => {
923 const dataFolder = appData.gamesToGameFolderPaths[appData.currentGame].dataFolder;
924 if (!dataFolder) return;
925 let outFile: BinaryFile | undefined;
926 try {
927 const targetPath =
928 existingPath ||
929 nodePath.join(dataFolder, "merged-" + format(new Date(), "dd-MM-yyyy-HH-mm-ss") + ".pack");
930 await fsExtra.ensureDirSync(nodePath.dirname(targetPath));
931 const packFieldsSettled = await Promise.allSettled(
932 mods.map((mod) => readPack(mod.path, { skipParsingTables: true })),
933 );
934 const sources = (
935 packFieldsSettled.filter((pfs) => pfs.status === "fulfilled") as PromiseFulfilledResult<Pack>[]
936 )
937 .map((r) => r.value)
938 .filter((packData) => packData);
939 const header = gameToPackHeader[appData.currentGame];
940 const byteMask = 3;
941 const refFileCount = 0;
942 const pack_file_index_size = 0;
943 outFile = new BinaryFile(targetPath, "w", true);
944 await outFile.open();
945 await outFile.writeString(header);
946 await outFile.writeInt32(byteMask);
947 await outFile.writeInt32(refFileCount);
948 await outFile.writeInt32(pack_file_index_size);
949 const packedFileNameToPackFileLookup: Record<string, PackedFile> = {};
950 const packedFileNameToPackSource: Record<string, Pack> = {};
951 const reverseSortedPacksByName = sources.sort(sortByPackName).reverse();
952 for (const sourcePack of reverseSortedPacksByName) {
953 for (const packFile of sourcePack.packedFiles) {
954 const packedFileName = packFile.name;
955 packedFileNameToPackFileLookup[packedFileName] = packFile;
956 packedFileNameToPackSource[packedFileName] = sourcePack;
957 }
958 }
959 await outFile.writeInt32(Object.keys(packedFileNameToPackFileLookup).length);
960 const index_size = Object.keys(packedFileNameToPackFileLookup).reduce(
961 (acc, name) => acc + new Blob([name]).size + 1 + 5,
962 0,
963 );
964 await outFile.writeInt32(index_size);
965 await outFile.writeInt32(0x7fffffff); // header_buffer
966 const sortedPackFileNames = Object.keys(packedFileNameToPackFileLookup).sort(compareModNames);
967 const sortedPackFileNamesDBFirst = sortedPackFileNames
968 .filter((name) => name.startsWith("db\\"))
969 .concat(sortedPackFileNames.filter((name) => !name.startsWith("db\\")));
970 for (const packedFileName of sortedPackFileNamesDBFirst) {
971 const packedFile = packedFileNameToPackFileLookup[packedFileName];
972 const { name, file_size } = packedFile;
973 await outFile.writeInt32(file_size);
974 await outFile.writeInt8(0);
975 await outFile.writeString(name + "\0");
976 }
977 const packNameToFileHandle: Record<string, BinaryFile> = {};
978 for (const sourcePack of sources) {
979 const sourceFile = new BinaryFile(sourcePack.path, "r", true);

Callers 2

registerIpcMainListenersFunction · 0.90
ModsMerger.tsxFile · 0.85

Calls 2

closeMethod · 0.80
readPackFunction · 0.70

Tested by

no test coverage detected