Readme and script cleanup (#995)

* Ignore .idea

* Ignore build dir too

* Remove unused Windows Docker files

* Remove somewhat cryptic launch.sh script

* Remove kebab (javascript)

* Remove outdated release_macos script and rename the most up-to-date one to macos_release

* Clean up README.md and delete the other ones

* Add preliminary configure script

* Add hint in dependencies

* Remove obsolete CONTRIBUTING.md

* let's write the configure script later

* Adding this is so supremely ironic that I can't even

* Update QtApng repo

* Actually we needed that

* Add comment

* Contact should be h2
This commit is contained in:
OmniTroid 2024-07-01 18:00:23 +02:00 committed by GitHub
parent 2b970ec4a3
commit 36345612d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 47 additions and 458 deletions

4
.gitignore vendored
View File

@ -40,3 +40,7 @@ object_script*
server/__pycache__
discord/
*.TMP
# Jetbrains config and build dir (CLion)
.idea/
cmake-build-*

View File

@ -1,44 +0,0 @@
## Compiling
The traditional route is by undergoing the [AO2 Rite of Passage](https://gist.github.com/oldmud0/6c645bd1667370c3e92686f7d0642c38).
However, these days it is easy to get away with using the default Qt toolchain on any platform, which creates a dynamic executable. (Don't forget to invoke windeployqt when creating a release.)
### Dependencies
- [BASS](http://un4seen.com) (optional; may use Qt Multimedia instead)
- [Discord Rich Presence](https://github.com/discordapp/discord-rpc) (optional)
## Release instructions
Follow these steps to make a new full release:
- Set a new AO version in the `.pro` file and in `aoapplication.h`.
- Compile the project.
- Commit the version bump and and create a tag for the commit.
- Rename the executable to `Attorney_Online`.
- Create a temp directory.
- Copy a fresh `base` folder to the temp dir. Ensure that the timestamps are consistent.
- Ignore this step if creating a client-only release.
- Copy the repository's `base` folder to the temp dir.
- Append `.sample` to the names of all `.ini` files, including `serverlist.txt`.
- Copy the game executable to the temp dir.
- Copy `bass.dll`, `discord-rpc.dll`, and `qapng.dll` if applicable.
- Copy `README.md` as `README.md.txt` with CRLF line endings.
- Copy `LICENSE` as `LICENSE.txt` with CRLF line endings.
- Compress the contents of the temp dir to an archive with maximum compression, but
be sure that the contents are placed inside the root directory of the archive and not
within a subdirectory.
- Compute the SHA-1 hash of the archive.
- Upload the archive to the Wasabi bucket and an additional mirror (e.g. MEGA or OneDrive)
(if this is a full release).
- Publish a GitHub release and upload the archive there (if this is a client-only release).
- Add the new version to the `program.json` manifest for the respective platform
(if this is a client-only release).
- Update the following on the website for the respective platform:
- Full download links (Wasabi and mirror)
- Client download link
- Full download hash
- Client download hash
Repeat for each platform (currently 32-bit Windows and 64-bit Linux). Once you're done, don't forget to announce your release!

View File

@ -2,35 +2,56 @@
![CI build](https://github.com/AttorneyOnline/AO2-Client/actions/workflows/build.yml/badge.svg?event=push) ![license](https://img.shields.io/github/license/AttorneyOnline/AO2-Client?color=blue) ![contributors](https://img.shields.io/github/contributors/AttorneyOnline/AO2-Client)<br>
[Attorney Online](https://aceattorneyonline.com) is an online version of the world-renowned courtroom drama simulator that allows you to create and play out cases in an off-the-cuff format.
[Attorney Online](https://aceattorneyonline.com) is a world-renowned courtroom drama simulator that allows you to create and play out cases in an off-the-cuff format.
**[Refer to the docs](https://github.com/AttorneyOnline/docs/blob/master/docs/index.md) for more information.**
Linux users will need to install the system dependencies related to Qt. These are the commands to run on a terminal for some distributions:
* Ubuntu 22.04 LTS:
```
$ sudo apt-get install qt6base-dev libqt6websockets6 qt6-image-formats-plugins libqt6svg6
```
* Arch:
```
$ sudo pacman -Syu qt6-base qt6-websockets qt6-imageformats qt6-svg
```
* Fedora:
```
$ sudo dnf install qt6-qtbase qt6-qtwebsockets qt6-qtimageformats qt6-qtsvg
## Setting up for development
This program's main dependency is Qt and the currently recommended version for development is **6.5.3**. See [this link](https://doc.qt.io/qt-6/qt-online-installation.html)
on how to install Qt.
### Other dependencies
* BASS (http://www.un4seen.com/bass.html)
* BASS Opus Plugin (http://www.un4seen.com/bass.html#addons)
* BASS Midi Plugin (http://www.un4seen.com/bass.html#addons)
* Discord Rich Presence (https://github.com/discordapp/discord-rpc/releases)
* Qt Apng Plugin (https://github.com/jurplel/QtApng/releases)
(see .github/workflows/build.yml for exact installation commands)
## Running Tests
Running tests requires Catch2 and cmake
```sh
mkdir cbuild && cd cbuild
cmake ..
make test
# usage: run all tests
./test/test
# usage: Optionally specify tests and success verbosity
./test/test [bass] --success
```
`[noci]` tag is used to disable a test on GitHub actions
## Credits
This is a open-source remake of Attorney Online written by OmniTroid. The original Attorney Online client was written by FanatSors in Delphi.
The original Attorney Online client was created by FanatSors.
The logo (`logo.png` and `logo.ico`) was designed by Lucas Carbi. The characters depicted in the logo are owned by Capcom.
This is an open-source remake of that client created by OmniTroid.
### Project
The logo (`logo.png` and `logo.ico`) was designed by Lucas Carbí. The characters depicted in the logo are owned by Capcom.
## Copyright
The project is dual-licensed; you are free to copy, modify and distribute AO2 under the GPLv3 or the MIT license.
Copyright (c) 2016-2018 David "OmniTroid" Skoland
Copyright (c) 2016-2018 OmniTroid
Modifications copyright (c) 2017-2018 oldmud0
@ -38,14 +59,6 @@ Case Café additions copyright (c) 2018 Cerapter
Killing Fever Online additions copyright (c) 2019 Crystalwarrior
### Qt
## Contact
This project uses Qt 6.5.3, which is licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.txt) with [certain licensing restrictions and exceptions](https://www.qt.io/qt-licensing-terms/). To comply with licensing requirements for static linking, object code is available if you would like to relink with an alternative version of Qt, and the source code for Qt may be found at https://github.com/qt/qtbase, http://code.qt.io/cgit/, or at https://qt.io.
Copyright (c) 2016 The Qt Company Ltd.
### BASS
This project depends on the BASS shared library. Get it here: http://www.un4seen.com/
Copyright (c) 1999-2016 Un4seen Developments Ltd. All rights reserved.
You can find us in the official Attorney Online Discord server: https://discord.gg/wWvQ3pw

View File

@ -1,61 +0,0 @@
### Dependencies
This program has five main dependencies
* Qt 5.6+ (https://www.qt.io/download)
* BASS (http://www.un4seen.com/bass.html)
* BASS Opus Plugin (http://www.un4seen.com/bass.html#addons)
* Discord Rich Presence (https://github.com/discordapp/discord-rpc/releases)
* Qt Apng Plugin (https://github.com/Skycoder42/QtApng/releases)
### Help
If you're having issues with any of this, ask in the offical Discord: https://discord.gg/wWvQ3pw
Alternatively, you can ask OmniTroid#4004 on Discord.
### How to build dynamically (the easy way)
#### General preparation
What you want to do is first download the latest version of Qt from the first link. (get the prebuilt dynamic version)
After going through the OS-specific steps below, compiling in Qt creator should work.
#### Windows
If you're on Windows, you need to go find all the dependencies (see above) and put them in the lib/ folder.
#### MacOS
If you're on MacOS, you can simply go to terminal and run ./scripts/configure_macos.sh
This will automatically fetch all the required dependencies. Additionally, if you need to create a standalone release, just run ./scripts/release_macos.sh
This will make the .app bundle in bin/ able to execute as a standalone.
#### Ubuntu
If you're on Ubuntu, just go to terminal and run ./scripts/configure_ubuntu.sh
This should fetch all the required dependencies automatically.
#### Other Linux
With some tweaks to the ubuntu script, it shouldn't be a big hassle to compile it on a modern linux. Look in the script and see what you may have to modify.
### How to build statically (the hard way)
You're gonna have a bad time.
Building statically means you can distribute the final program without needing to pack alongside a lot of dynamic libraries.
This is a tricky process and is not recommended unless you know what you're doing.
First, you need to build the entirety of Qt statically. To do this, check the desired version under "Sources" in the Qt maintenance tool.
After this is done, follow these instructions: https://dimitris.apeiro.gr/2015/06/24/build-a-static-qt5-for-windows-by-compiling/
This guide is specifically for Windows, but Qt is cross-platform and you should be good with or without some minor adjustments to the guide.
Note that this **is** a computationally heavy process and will take a lot of time on a slow computer.
After this, you need to configure the project to use the static version of qmake (see http://doc.qt.io/qtcreator/creator-build-settings.html)
BASS and BASS Opus only comes as dynamic libraries and is not open-source. That means you can't link it statically in the program.
For Discord RPC, you can download prebuilt static libraries for your platform. Just put them in lib/.
For Qt Apng Plugin, you need to compile it statically. This guide does not go into detail how to configure this to build a static library. You may have to add Q_IMPORT_PLUGIN(ApngImagePlugin); in main.cpp. See more about importing static plugins here: http://doc.qt.io/qt-5/plugins-howto.html#static-plugins
It's also possible to just link this dynamically.

View File

@ -1,17 +0,0 @@
Running tests requires Catch2 and cmake
# Running Tests
```sh
mkdir cbuild && cd cbuild
cmake ..
make test
# usage: run all tests
./test/test
# usage: Optionally specify tests and success verbosity
./test/test [bass] --success
```
# Writing Tests
`[noci]` tag is used to disable a test on Github actions

View File

@ -1,3 +1,5 @@
#!/bin/sh
# Required in CI to launch correctly
chmod +x Attorney_Online
LD_LIBRARY_PATH=. ./Attorney_Online

View File

View File

@ -1,9 +0,0 @@
{
"name": "ao-ci-scripts",
"version": "1.0.0",
"main": "update_manifest.js",
"dependencies": {
"argparse": "^1.0.10"
},
"license": "ISC"
}

View File

@ -1,22 +0,0 @@
#!/bin/sh
# This script prepares the compiled bundle for shipping as a standalone release
# Assumes the Qt bin folder is in PATH
# Should be used on a "Release" build from QT creator
# Note that this DOES NOT add the base/ folder
# Exit on errors and unset variables
set -eu
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
cd ${ROOT_DIR}
# This thing basically does all the work
macdeployqt ../bin/Attorney_Online.app
# Need to add the dependencies
cp ../lib/* ../bin/Attorney_Online.app/Contents/Frameworks
# libbass has a funny path for some reason, just use rpath
install_name_tool -change @loader_path/libbass.dylib @rpath/libbass.dylib ../bin/Attorney_Online.app/Contents/MacOS/Attorney_Online

View File

@ -1,149 +0,0 @@
#!/usr/bin/env node
const fs = require("fs");
const crypto = require("crypto");
const path = require("path");
const ArgumentParser = require("argparse").ArgumentParser;
function isFile(file) {
if (!fs.existsSync(file)) {
console.error(`File '${file}' not found. Try again.`);
throw Error();
}
return file;
}
const argParser = new ArgumentParser({
addHelp: true,
description: "Adds a new latest version to the manifest file based on the " +
"provided zip file, including an incremental update."
});
argParser.addArgument("manifestFile", {
metavar: "<manifest file>", type: isFile
});
argParser.addArgument("version", {
metavar: "<version>"
});
argParser.addArgument([ "-f", "--full" ], {
metavar: "<full zip file>", type: isFile, nargs: 1,
dest: "fullZipFileArgs"
});
argParser.addArgument([ "-i", "--incremental" ], {
type: isFile, nargs: 2, dest: "incrementalArgs",
metavar: ["<incremental zip file>", "<file containing list of changed files>"]
});
argParser.addArgument([ "-e", "--executable" ], {
metavar: "[executable file]", nargs: 1,
dest: "executableArgs"
});
const {
manifestFile,
version,
fullZipFileArgs,
incrementalArgs,
executableArgs
} = argParser.parseArgs();
const [incrementalZipFile, changesFile] = incrementalArgs || [];
const [fullZipFile] = fullZipFileArgs || [];
const [executable] = executableArgs || [];
// Do one final check
if (!incrementalZipFile && !fullZipFile) {
console.error("No download archive specified! Abort.");
process.exit(1);
}
// Do a quick litmus test to prevent deleting everything incorrectly
if (changesFile && !fs.existsSync("base")) {
console.error("The working directory must be set to an " +
"asset folder in order for deleted directories " +
"to be calculated correctly. Abort.");
process.exit(1);
}
const manifest = JSON.parse(fs.readFileSync(manifestFile));
const dirsDeleted = new Set();
const specialActions = changesFile ?
fs.readFileSync(changesFile)
.toString()
.trim()
.split("\n")
.map(line => line.split("\t"))
.map(([mode, target, source]) => {
switch (mode[0]) {
case "D": // Deleted
// Check if the folder exists relative to the working
// directory, and if not, add it to the dirsDeleted list.
// Keep going up the tree to see how many directories were
// deleted.
let dir = path.dirname(target);
while (!dirsDeleted.has(dir) && !fs.existsSync(dir)) {
dirsDeleted.add(dir);
dir = path.dirname(dir);
}
return { action: "delete", target };
case "R": // Renamed
// NOTE: Make sure that the launcher's implementation of
// the move action also creates directories when needed.
return { action: "move", source, target};
default:
return null;
}
})
// Remove ignored file mode changes
.filter(action => action !== null)
// Create actions based on directories to be deleted.
// Always have deeper directories first, to guarantee that deleting
// higher-level directories will succeed.
.concat(Array.from(dirsDeleted.values())
.sort((a, b) => b.split("/").length - a.split("/").length)
.map(dir => ({ action: "deleteDir", target: dir })))
: [];
const urlBase = "https://s3.wasabisys.com/ao-downloads/";
const versionEntry = {
version,
executable,
prev: manifest.versions[0] ? manifest.versions[0].version : undefined,
full: fullZipFile ? [
{
action: "dl",
url: urlBase + encodeURIComponent(path.basename(fullZipFile)),
hash: crypto.createHash("sha1")
.update(fs.readFileSync(fullZipFile))
.digest("hex")
}
] : undefined,
update: incrementalArgs ? [
...specialActions,
{
action: "dl",
url: urlBase + encodeURIComponent(path.basename(incrementalZipFile)),
hash: crypto.createHash("sha1")
.update(fs.readFileSync(incrementalZipFile))
.digest("hex")
}
] : undefined
};
console.log("Generated version entry:", versionEntry);
const existingVersions = manifest.versions.filter(v => v.version == version);
if (existingVersions.length > 0) {
console.warn(`Warning: version ${version} already exists. Adding new values.`);
// Don't overwrite prev - it will cause headaches
delete versionEntry.prev;
Object.assign(existingVersions[0], versionEntry);
console.log("Merged version entry:", existingVersions[0]);
} else {
manifest.versions = [versionEntry, ...manifest.versions];
}
fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 4));

View File

@ -1,39 +0,0 @@
#!/usr/bin/env node
const fs = require("fs");
const crypto = require("crypto");
const [ _nodeExe, _jsPath, manifestFile, version, zipFile ] = process.argv;
if (!manifestFile || !version || !zipFile) {
console.log(`Usage: update_program_manifest <manifest file> <version> <zip file>`);
console.log(`Adds a new latest version to the manifest file based on the ` +
`provided zip file.`);
process.exit(1);
}
if (!fs.existsSync(manifestFile)) {
console.error(`Manifest file '${manifestFile}' not found. Try again.`);
process.exit(2);
}
if (!fs.existsSync(zipFile)) {
console.error(`Zip file '${zipFile}' not found. Try again.`);
process.exit(2);
}
const manifest = JSON.parse(fs.readFileSync(manifestFile));
manifest.versions = [{
version,
executable: "Attorney_Online.exe",
full: [
{
action: "dl",
url: "https://s3.wasabisys.com/ao-downloads/" + encodeURIComponent(zipFile),
hash: crypto.createHash("sha1").update(fs.readFileSync(zipFile)).digest("hex")
}
]
}, ...manifest.versions];
fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 4));

View File

@ -1,26 +0,0 @@
FROM oldmud0/mxe-qt:5.13.0-win32-static-posix
#FROM fffaraz/qt:windows
ENV TARGET_SPEC i686-w64-mingw32.static.posix
# Build libarchive statically
WORKDIR /opt/mxe
RUN make -j4 MXE_TARGETS=${TARGET_SPEC} libarchive bzip2 xz lz4 zstd nettle expat libxml2
WORKDIR /
# Build Discord RPC statically
RUN git clone https://github.com/discordapp/discord-rpc
WORKDIR discord-rpc/build
RUN /opt/mxe/usr/bin/${TARGET_SPEC}-cmake .. -DCMAKE_INSTALL_PREFIX=/opt/mxe/usr/${TARGET_SPEC}
RUN /opt/mxe/usr/bin/${TARGET_SPEC}-cmake --build . --config Release --target install
WORKDIR ../..
# Build QtApng statically
RUN git clone https://github.com/Skycoder42/QtApng
WORKDIR QtApng
# libpng contains a self-test entry point that takes precedence for some reason
# over the final build's entry point.
RUN sed -i "s/^main(/libpng_main(/g" src/3rdparty/libpng/src/pngtest.c
RUN /opt/mxe/usr/${TARGET_SPEC}/qt5/bin/qmake
RUN make && make install
WORKDIR ..

View File

@ -1,44 +0,0 @@
FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install -y \
autoconf \
automake \
autopoint \
bash \
bison \
bzip2 \
flex \
g++ \
g++-multilib \
gettext \
git \
gperf \
intltool \
libc6-dev-i386 \
libgdk-pixbuf2.0-dev \
libltdl-dev \
libssl-dev \
libtool-bin \
libxml-parser-perl \
lzip \
make \
openssl \
p7zip-full \
patch \
perl \
pkg-config \
python \
ruby \
sed \
unzip \
wget \
xz-utils
RUN git clone https://github.com/mxe/mxe.git
RUN mv mxe /opt/mxe
WORKDIR /opt/mxe
RUN make -j4 MXE_TARGETS="i686-w64-mingw32.static.posix" qtbase qtmultimedia libarchive
ENV PATH=/opt/mxe/usr/bin:$PATH
WORKDIR /

View File

@ -1,19 +0,0 @@
When you want to build a new version of Qt:
```docker
docker build -t mxe-windows-static . -f Dockerfile-mxe
docker tag mxe-windows-static oldmud0/mxe-qt:5.12.1-win32-static-posix
docker push oldmud0/mxe-qt:5.12.1-win32-static-posix
```
Remember to log into Docker Hub before attempting to push.
When you want to build a new version of any dependency required for building AO:
```docker
docker build -t mxe-windows-static-ao . -f Dockerfile
docker tag mxe-windows-static-ao registry.gitlab.com/attorneyonline/ao2-client/builder-windows-i686
docker push registry.gitlab.com/attorneyonline/ao2-client/builder-windows-i686
```
Remember to create an access token in GitLab before attempting to push.
GitLab CI depends on `builder-windows-i686` image to be present in the repository's registry in order for the Windows build to succeed.