LuaCASC is an implementation of the CASC file system in Lua, capable of reading from local installations and/or CDN-hosted data.

Dependencies

The following Lua modules are recommended; if they are not available, casc/platform.lua resorts to using less efficient and in some cases platform-dependent solutions.

Generally, it should work even without these modules if gzip and curl are available.

On Windows, you may use the following binaries, which require only the VS2013 run-time components to be installed:

Installation

The casc/ directory should go somewhere matched by Lua's package.path. This might be the current working directory, /usr/local/share/lua/5.1/, or the lua subdirectory in the directory containing your Lua executable.

Using LuaCASC

You can use LuaCASC to read information from locally-stored Data directories, from CDNs, or both at the same time, using local data when it has already been downloaded.

local casc = require("casc")
local handle, err = casc.open("./World of Warcraft/", {verifyHashes=false})
if not handle then
   -- Could not select a local build; query the patch server instead
   handle, err = casc.open("http://us.patch.battle.net:1119/wow/#eu")
end
local content = assert(handle:readFile("Interface/Icons/Temp.blp"))
local h = io.open("Temp.blp", "w")
h:write(content)
h:close()

Additional examples are included in examples/ directory of the ZIP file.

API Functions

casc = require("casc")
Loads the LuaCASC module.
handle = casc.open(conf)
Returns a new handle to a CASC data store specified by the conf table, or, in case of errors, nil and an error message. The following keys can be set in conf:
bkey (string)
MD5 hash of the build configuration file, 32-character hexadecimal string.
base (string, optional)
Path to the local Data directory to load local content from.
cdn (string/table, optional)
CDN base URL(s) to download data from. If a table containing multiple base URLs is passed, LuaCASC will automatically switch CDN hosts when a download fails and try again.
ckey (string, required with cdn)
MD5 hash of the CDN configuration file, 32-character hexadecimal string.
cache (string, optional)
Path to a directory that will be used to cache metadata downloaded from the CDN. If not specified, defaults to the LUACASC_CACHE environment variable.
verifyHashes (boolean, default: true)
Boolean value indicating whether LuaCASC should verify MD5 hashes prior to returning file content.
locale (function or string, optional)
Specifies the ranking function used when looking up file data based on a file name. You may either provide a function which, when given a file variant's (localeFlags, typeFlags, isRemote), returns either a number indicating preference for that variant (greater values indicate more preferable variants), or a falsy value indicating that the variant is entirely unaceptable, and should never be returned; or one of the keys in casc.locale (BR, CN, DE, ES, FR, GB, IT, KR, MX, PT, RU, TW, US) to use the corresponding ranking function. The CN locale prefers alternative variants of certain model files.
If not specified, a default ranking function is used, preferring locally available, British English files, in that order.
mergeInstall (boolean/string, default: false)
If truthy, files installed outside the CASC store will be made available through the handle:read* methods using the CDN. If a string is specified, it is interpreted as a semicolon-delimited list of file tags; only files matching all specified tags will be made accessible.
Common file tags are: x86_32, x86_64, OSX, Windows.
usePatchEntries (boolean, default: true)
If true, allows key files specified in the CASC patch configuration to be patched from local/cached old versions instead of being downloaded directly.
requireRootFile (boolean, default: true)
If set to false, LuaCASC will create a CASC handle even if it fails to parse the root file. This allows retrieving content using content or encoding hashes, but not file names or IDs.
keys (table, default: nil)
An optional table mapping encryption key names to keys, both expressed as hexadecimal strings. Entries in this table override those returned by the user-provided casc.keys module, which is automatically loaded if it exists.
zerofillEncryptedChunks (boolean, default: false)
If set to true, BLTE chunks encrypted using unknown keys will be replaced by zeroes, disabling content hash verification for the file. By default, or if false is specified, attempting to read a file with such a chunk will fail.
At least one of conf.base and (conf.cdn, conf.ckey) must be provided.
handle = casc.open("localRoot"[, conf])
handle = casc.open("patchURL"[, conf])
Returns a new handle to a CASC data store, or nil and an error message if an error occurs. Equivalent to calling casc.open(casc.conf(...)).
conf = casc.conf("localRoot"[, conf])
Returns a CASC configuration table based on a local installation. localRoot specifies a path to a local game directory containing a .build.info file and a Data directory, with build and CDN configuration derived from the build marked active in the .build.info file. If the conf table is provided, its keys override those derived from the .build.info file.
Note that .build.info includes CDN configuration, allowing files not available locally to be retrieved from the CDN; to only use local files, set conf.cdn = false.
conf = casc.conf("patchURL"[, conf])
Returns a CASC configuration table based on a remote patch server. patchURL is the URL of the CDN server directory containing versions and cdns files, and a fragment specifying the desired region. If the conf table is provided, its keys override those derived from the patch server.
"bkey", cdn, "ckey", "version", build = casc.cdnbuild("patchBase", "region")
Returns information about the build offered by the patch server for a particular region:
patchBase
URL of the patch server to query, terminating with the directory containing the versions and cdns files.
region
Region name to return current build information for, e.g. eu.
bkey
MD5 hash of the build configuration file; 32-character hexadecimal string.
cdn
Base URL(s) for a CDN host serving the build.
ckey
MD5 hash of the CDN configuration file; 32-character hexadecimal string.
version
Version string.
build
Build number.
If an error occurs, this function returns nil and an error message.
"bkey", cdn, "ckey", "version" = casc.localbuild("buildInfoPath", selectBuild)
Parses the .build.info file specified by buildInfoPath, and calls selectBuild to determine which build to return information about. You may use casc.selectActiveBuild to select the build marked Active in the local installation, or casc.selectUserBuild to prompt the user to select a build via standard I/O.
If an error occurs, this function returns nil and an error message.
regions, versions, cdns = casc.cdnbuild("patchURL")
Returns information about all regions and CDNs listed at the specified CDN root.
branches, buildInfo = casc.localbuild("buildInfoPath")
Returns information about all locally-available builds.
handle:setLocale("localeKey" or rankFunc or nil)
Changes the handle's locale, determining which file variant is retrieved by handle:readFile("path"); see conf.locale for possible values.
variants = handle:getFileVariants("path" or fileID)
For a given file, identified by a virtual path (e.g. Interface/FrameXML/FrameXML.toc) or file ID (e.g. 841788), returns a table mapping available content hashes to an array of locale idenfiers (e.g. GB) the variant is flagged for. The path is case insensitive; \ and / are interchangeable.
If an error occurs, returns nil and an error message.
"hash" = handle:getFileContentHash("path" or fileID[, locale])
Returns the content has of a file identified by a virtual path (e.g. Interface/FrameXML/FrameXML.toc) or file ID (e.g. 841788). If locale is specified, it overrides the handle's current locale. The path is case insensitive; \ and / are interchangeable.
If an error occurs, returns nil and an error message.
"content" = handle:readFile("path" or fileID[, locale[, cache]])
Returns content of the file specified by a virtual path (e.g. Interface/FrameXML/FrameXML.toc) or file ID (e.g. 841788).
Equivalent to handle:readFileByContentHash(handle:getFileContentHash(path, locale), cache).
If an error occurs, returns nil and an error message.
"content" = handle:readFileByEncodingHash("hash"[, cache])
Returns file content by the MD5 hash derived from its BLTE encoding (either a 32-character hexadecimal string, or a 9/16-character raw binary string).
If an error occurs, returns nil and an error message.
"content" = handle:readFileByContentHash("hash"[, cache])
Returns file content by its MD5 hash (either a 32-character hexadecimal string, or a 16-character raw binary string).
If an error occurs, returns nil and an error message.
fileID = handle.root:getFileID("path")
Returns the fileID corresponding to the specified path. This function is only available for handles using WoW root files.