Created
May 12, 2017 14:53
-
-
Save Choonster/527498fc692840686c7dd899b240973c to your computer and use it in GitHub Desktop.
A Lua script to extract Minecraft's assets from the repository format used by the Mojang launcher and ForgeGradle into regular directories. Requires Lua 5.2+/LuaJIT, LuaJSON, Penlight and LuaFileSystem
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
-- Extracts Minecraft's assets from the repository format used by the Mojang launcher and ForgeGradle into regular directories. | |
-- Requires Lua 5.2+/LuaJIT, LuaJSON, Penlight and LuaFileSystem | |
--------------------- | |
-- Start of Config -- | |
--------------------- | |
-- The location of the index JSON file | |
local INDEX_FILE = [[C:\Users\USER\.gradle\caches\minecraft\assets\indexes\1.11.json]] | |
-- The directory to extract the assets to | |
local OUTPUT_DIR = [[C:\Users\USER\Documents\Minecraft\Mods\TestMod3\TestMod3_1.11.2\vanilla_assets]] | |
------------------- | |
-- End of Config -- | |
------------------- | |
local json = require("json") | |
local path = require("pl.path") | |
local file = require("pl.file") | |
local pretty = require("pl.pretty") | |
--- Calls string.format and prints the result. | |
local function printf(formatStr, ...) | |
print(formatStr:format(...)) | |
end | |
--- Formats a number with thousands comma separators. | |
local function formatNumber(number) | |
return pretty.number(number, "T") | |
end | |
--- Creates a directory, also creating any intermediate directories if they don't exist. | |
-- @return true on success or nil, the directory that couldn't be created and an error message on failure | |
local function mkdirs(directoryPath) | |
local baseDirectory, thisDir = path.splitpath(directoryPath) | |
if not path.isdir(baseDirectory) then -- If the base directory doesn't exist, try to create it | |
local success, failedDirectory, errorMessage = mkdirs(baseDirectory) | |
if not success then -- If creating the base directory fails, we can't create this directory | |
return nil, failedDirectory, errorMessage | |
end | |
end | |
local success, errorMessage = path.mkdir(directoryPath) | |
if success then | |
return true | |
else | |
return nil, directoryPath, errorMessage | |
end | |
end | |
local function extractRepository(indexFilePath, outputDirPath) | |
print("Extracting files from repository") | |
printf("Index file: %s", indexFilePath) | |
printf("Output dir: %s", outputDirPath) | |
print("\n") | |
local numSucceeded, numFailed, numSkipped = 0, 0, 0 | |
local function succeeded(...) | |
numSucceeded = numSucceeded + 1 | |
printf(...) | |
end | |
local function failed(...) | |
numFailed = numFailed + 1 | |
printf(...) | |
end | |
local function skipped(...) | |
numSkipped = numSkipped + 1 | |
printf(...) | |
end | |
local index = json.decode(file.read(indexFilePath)) | |
local indexesDirPath = path.splitpath(indexFilePath) | |
local objectsDirPath = path.join(indexesDirPath, "../objects") | |
for filePath, fileData in pairs(index.objects) do | |
local hash = fileData.hash | |
local repositoryFilePath = path.join(hash:sub(1, 2), hash) | |
local fullRepositoryFilePath = path.join(objectsDirPath, repositoryFilePath) | |
filePath = path.normpath(filePath) | |
local outputFilePath = path.join(outputDirPath, filePath) | |
local outputSubDirPath = path.join(outputDirPath, (path.splitpath(filePath))) | |
printf("Copying %s to %s...", repositoryFilePath, filePath) | |
if not path.isdir(outputSubDirPath) then | |
local success, failedDirectory, errorMessage = mkdirs(outputSubDirPath) | |
if not success then | |
failed("Failed to create directory %s: %s", failedDirectory, errorMessage) | |
goto continue | |
end | |
end | |
if path.exists(outputFilePath) then | |
skipped("Skipping file as it already exists") | |
else | |
local success, errorMessage = file.copy(fullRepositoryFilePath, outputFilePath) | |
if success then | |
succeeded("Successfully copied file") | |
else | |
failed("Failed to copy file: %s", errorMessage) | |
end | |
end | |
::continue:: | |
print() | |
end | |
print() | |
printf("Finished extracting %s files with %s successes, %s failures and %s skipped", formatNumber(numSucceeded + numFailed + numSkipped), formatNumber(numSucceeded), formatNumber(numFailed), formatNumber(numSkipped)) | |
end | |
extractRepository(INDEX_FILE, OUTPUT_DIR) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment