diff --git a/.gitignore b/.gitignore
index 98b8f68..d7ca3f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,7 @@ object_script*
server/__pycache__
discord/
*.TMP
+
+# Jetbrains config and build dir (CLion)
+.idea/
+cmake-build-*
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 72cfa8f..0000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -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!
diff --git a/README.md b/README.md
index 3916a17..483e031 100644
--- a/README.md
+++ b/README.md
@@ -2,35 +2,56 @@
  
-[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
diff --git a/README_BUILD.md b/README_BUILD.md
deleted file mode 100644
index f7441b8..0000000
--- a/README_BUILD.md
+++ /dev/null
@@ -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.
-
diff --git a/README_TEST.md b/README_TEST.md
deleted file mode 100644
index 774ad3c..0000000
--- a/README_TEST.md
+++ /dev/null
@@ -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
diff --git a/scripts/launch.sh b/scripts/launch.sh
index 7846ef7..dcf6e7a 100644
--- a/scripts/launch.sh
+++ b/scripts/launch.sh
@@ -1,3 +1,5 @@
#!/bin/sh
+
+# Required in CI to launch correctly
chmod +x Attorney_Online
-LD_LIBRARY_PATH=. ./Attorney_Online
\ No newline at end of file
+LD_LIBRARY_PATH=. ./Attorney_Online
diff --git a/scripts/macos_post_build.sh b/scripts/macos_release.sh
old mode 100755
new mode 100644
similarity index 100%
rename from scripts/macos_post_build.sh
rename to scripts/macos_release.sh
diff --git a/scripts/package.json b/scripts/package.json
deleted file mode 100644
index 126a392..0000000
--- a/scripts/package.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "ao-ci-scripts",
- "version": "1.0.0",
- "main": "update_manifest.js",
- "dependencies": {
- "argparse": "^1.0.10"
- },
- "license": "ISC"
-}
diff --git a/scripts/release_macos.sh b/scripts/release_macos.sh
deleted file mode 100755
index 50acb40..0000000
--- a/scripts/release_macos.sh
+++ /dev/null
@@ -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
diff --git a/scripts/update_manifest.js b/scripts/update_manifest.js
deleted file mode 100755
index bbd2a5f..0000000
--- a/scripts/update_manifest.js
+++ /dev/null
@@ -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: "", type: isFile
-});
-argParser.addArgument("version", {
- metavar: ""
-});
-argParser.addArgument([ "-f", "--full" ], {
- metavar: "", type: isFile, nargs: 1,
- dest: "fullZipFileArgs"
-});
-argParser.addArgument([ "-i", "--incremental" ], {
- type: isFile, nargs: 2, dest: "incrementalArgs",
- metavar: ["", ""]
-});
-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));
diff --git a/scripts/update_program_manifest.js b/scripts/update_program_manifest.js
deleted file mode 100755
index 9efc814..0000000
--- a/scripts/update_program_manifest.js
+++ /dev/null
@@ -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 `);
- 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));
\ No newline at end of file
diff --git a/scripts/windows/Dockerfile b/scripts/windows/Dockerfile
deleted file mode 100644
index 9d3cca0..0000000
--- a/scripts/windows/Dockerfile
+++ /dev/null
@@ -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 ..
\ No newline at end of file
diff --git a/scripts/windows/Dockerfile-mxe b/scripts/windows/Dockerfile-mxe
deleted file mode 100644
index 873e144..0000000
--- a/scripts/windows/Dockerfile-mxe
+++ /dev/null
@@ -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 /
diff --git a/scripts/windows/how-to-push.md b/scripts/windows/how-to-push.md
deleted file mode 100644
index 8c1c18d..0000000
--- a/scripts/windows/how-to-push.md
+++ /dev/null
@@ -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.