Skip to content

Instantly share code, notes, and snippets.

@Choonster
Created May 12, 2017 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Choonster/527498fc692840686c7dd899b240973c to your computer and use it in GitHub Desktop.
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
-- 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