Unreal series games mod community content indexer, static site generator, and related tooling.
Scans, categorises and produces metadata for Unreal, Unreal Tournament, Unreal
Tournament 2003/4, and Unreal Tournament 3 content, and builds a static
browsable website of the content, currently published at
https://unrealarchive.org/.
Tested with both OpenJDK 21 on Linux and Azul’s Zulu Java 21 on Windows.
The project is build with Gradle. The provided gradlew
wrapper may be
invoked as follows to produce an executable file:
./gradlew jlink
To run, execute:
./build/unreal-archive/bin/unreal-archive
gradlew.bat jlink
To run, execute:
build\unreal-archive\bin\unreal-archive.bat
The project is arranged into several modules, and published as Java Modules so
components may be reused by other software projects.
These are:
common
: the usual assortment of shared boilerplate code and utility classescontent
: the definition of the content types, Maps, Map Packs, Skins, Gamestorage
: the remote storage/mirror implementations, for S3 and Azure andwww
: the code and templates responsible for generating the static websiteTODO: complete this section
Run with no arguments to see input arguments and additional help for each command.
Browsing and Information:
ls
: List indexed content filtered by game, type or author.filter
: List indexed content filtered by attribute=value
pairs.show
: Show data for the content items specified.summary
: Show stats and counters for the content index.General Content Management
scan
: Dry-run scan the contents of files or paths, comparing to known content where possible.index
: Index the contents of files or paths, writing the results to the content path.edit
: Edit the metadata for the set
: Convenience, set an attribute for the set <hash> author Bob
.sync
: Sync managed files’ local files to remote storage.Gametype Management
gametype
:init <game> <gametype name>
: Create a skeleton gametype file structure.locate <game> <gametype name>
: Show the local file path to the provided gametype.index <game> <game type name> <release name>
: Indexes the content of the release specified.add <game> <game type name> <release name> <file>
:
Convenience, which adds a gametype if it does not yet exist, adds a release, and indexes
the release. A `sync` command afterwards is still required to sync download files to
mirrors.
addmirror <game> <game type name> <release name> <url>
: Adds a secondary mirror to the
gametype specified.
Mirrors:
local-mirror
: Create a local mirror of all file content.mirror
: Create a remote mirror of all file content and add mirror links.Utilities and Tools:
unpack
: Unpack the contents of a umod file to a directory.install
: Unpack the contents of a file, URL or hash, and place within an Unreal
game's standard directory layout (Maps, System, Textures etc).
Website Build:
www
: Generate the HTML website for browsing content.Submission
instance is created._override.yml
file, that file isSubmissionOverride
instance and associated with theSubmission
.Submission
is used to instantiate an Incoming
instance, which7z
and unrar
).Incoming
instance is passed to ContentType.classify()
for contentContent
element of the appropriate typeIndexHandler
instance, which will take the new Content
instance andConsumer<>
, and this is thenContentManager
, which will write the content metadataMost of this process uses Consumer<>
s for providing feedback, with the
intention of eventually being able to make this process more parallelised for
better performance. Currently the performance is “good enough” that such
parallel behaviour is not quite worth the implementation time.
If you have storage capacity available and would like to contribute some of it
as a public mirror for archive content, the following steps should be taken.
unreal-archive-data
unreal-archive
project binaryunreal-archive mirror
with the following command-line options:--content-path=/path/to/unreal-archive-data
--store=[dav|s3|az]
and appropriate--concurrency=3
with an appropriate concurrency value for your bandwidth--since=yyyy-mm-dd
[optional] - only mirror content added after theCtrl+C
git commit
yourunreal-archive-data
repository and push to your fork,master
A storage backend must be configured in order to store content during indexing.
When interrogating, mirroring or downloading content, no store needs to be
specified, the default no-op store (--store=nop
) will be used.
Environment variables may be used for configuration, eg.: replace--s3-key-images=key
with S3_KEY_IMAGES=key
.
This is mostly for testing purposes, but in some circumstances may be useful.
--store=dav
--store-[images|attachments|content]=dav
--dav-url=http://hostname/path/
--dav-url-[images|attachments|content]=...
Supports S3-compatible storage implementations.
--store=s3
--store-[images|attachments|content]=bs3
--s3-key=key-id
--s3-key-[images|attachments|content]=key-id
--s3-secret=secret
--s3-secret-[images|attachments|content]=secret
--s3-bucket=bucket-id
--s3-bucket-[images|attachments|content]=bucket-id
--s3-endpoint=https://s3.amazonaws.com/
--s3-endpoint-[images|attachments|content]=https://s3.amazonaws.com/
--s3-url=https://__BUCKET__.s3.eu-west-2.amazonaws.com/__NAME__
__BUCKET__
and __NAME__
will be replaced by the bucket and uploadedNote: Amazon S3 bucket policy to allow public downloads:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::testing-unreal-archive-mirror/*"
}
]
}
--store=az
--store-[images|attachments|content]=az
--az-acc=storage-account-name
--az-acc-[images|attachments|content]=storage-account-name
--az-container
--az-container-[images|attachments|content]=container-name
--az-sas
--az-sas-[images|attachments|content]="shared-access-signature"
--az-endpoint
(Optional, default=”blob.core.windows.net”)--az-endpoint-[images|attachments|content]=endpoint-suffix
Note: The shared access signature (SAS) should be created with full permissions to the specified container.
Use double quotes around the SAS when specifying it via the command line.