Skip to content

Latest commit

 

History

History
222 lines (182 loc) · 9.48 KB

File metadata and controls

222 lines (182 loc) · 9.48 KB

Attorney Online v2.11.0.0 (AO2-Client)

Project Overview

Attorney Online is an open-source courtroom drama simulator client. Players connect to servers, choose characters, and act out cases in real time using animated sprites, chat messages, sound effects, and music. The client communicates with servers via the AO2 network protocol over WebSockets.

  • Version: 2.11.0.0
  • License: GPLv3
  • Original client by FanatSors; this remake by OmniTroid and contributors

Tech Stack

Component Detail
Language C++20
UI Framework Qt 6 (recommended: 6.5.3)
Qt Modules Core, Gui, Network, Widgets, Concurrent, WebSockets, UiTools
Build System CMake (minimum 3.7.0) + Ninja
Compiler (Win) MinGW 64-bit (bundled with Qt)
Compiler (Unix) GCC / G++ (system)
Audio BASS 2.4 + BASSOPUS 2.4 (un4seen.com)
Image Plugin QtApng (APNG support, built from source)
Discord RPC discord-rpc v3.4.0 (optional, enabled by default)
Code Formatter clang-format (LLVM-based, see .clang-format)
Test Framework Qt Test (QtTest module)

Folder Structure

AO2-Client/
├── bin/                  # Build output directory (executables, DLLs, plugins)
│   ├── base/             # Game content (themes, characters, sounds) — not in repo
│   │   └── themes/       # Cloned from AO2-Themes repo by configure.sh
│   └── imageformats/     # QtApng plugin output (qapng.dll / libqapng.so)
├── data/                 # Qt resource data (data.qrc, logo-client.rc for Windows)
├── lib/                  # Third-party library headers and import libs
│   │                     # (bass.h, bassopus.h, discord_rpc.h, *.lib / *.so)
│   │                     # Populated by configure.sh — not committed to repo
├── scripts/              # Helper and release scripts
│   ├── APPIMAGE_INSTALL.sh
│   ├── Attorney_Online.desktop
│   ├── DYNAMIC_INSTALL.sh
│   ├── macos_release.sh
│   ├── wasabi.sh
│   └── wasabi_program.sh
├── src/                  # All application source code
│   ├── network/          # Network layer
│   │   ├── serverinfo.h / serverinfo.cpp
│   │   └── websocketconnection.h / websocketconnection.cpp
│   ├── widgets/          # Standalone dialog/widget classes
│   │   ├── aooptionsdialog.h / aooptionsdialog.cpp
│   │   ├── direct_connect_dialog.h / direct_connect_dialog.cpp
│   │   ├── moderator_dialog.h / moderator_dialog.cpp
│   │   ├── playerlistwidget.h / playerlistwidget.cpp
│   │   └── server_editor_dialog.h / server_editor_dialog.cpp
│   ├── main.cpp
│   ├── aoapplication.h / aoapplication.cpp   # Central application class
│   ├── lobby.h / lobby.cpp                   # Server browser / lobby window
│   ├── courtroom.h / courtroom.cpp           # Main gameplay window
│   ├── networkmanager.h / networkmanager.cpp # Manages server connections
│   ├── aopacket.h / aopacket.cpp             # AO2 network packet encode/decode
│   ├── packet_distribution.cpp               # Routes incoming packets
│   ├── datatypes.h                           # Shared enums and structs
│   ├── options.h / options.cpp               # User settings (QSettings-backed)
│   ├── animationlayer.h / animationlayer.cpp # Sprite animation rendering layer
│   ├── animationloader.h / animationloader.cpp
│   ├── aoblipplayer.h / aoblipplayer.cpp     # Blip (typewriter) audio
│   ├── aomusicplayer.h / aomusicplayer.cpp   # Music playback (BASS)
│   ├── aosfxplayer.h / aosfxplayer.cpp       # SFX playback (BASS)
│   ├── aobutton / aocharbutton / aoemotebutton / aoevidencebutton  # custom Qt buttons
│   ├── aoimage.h / aoimage.cpp               # Image display widget
│   ├── aoevidencedisplay / aotextarea / aotextboxwidgets / aoclocklabel / aoemotepreview
│   ├── chatlogpiece.h / chatlogpiece.cpp     # Chat log entry model
│   ├── serverdata.h / serverdata.cpp         # Server metadata
│   ├── demoserver.h / demoserver.cpp         # Demo/replay server
│   ├── discord_rich_presence.h / discord_rich_presence.cpp
│   ├── debug_functions.h / debug_functions.cpp
│   ├── file_functions.h / file_functions.cpp
│   ├── hardware_functions.h / hardware_functions.cpp
│   ├── charselect.cpp    # Character selection logic
│   ├── emotes.cpp        # Emote handling logic
│   └── evidence.cpp      # Evidence handling logic
├── test/                 # Unit tests
│   ├── CMakeLists.txt
│   ├── test_aopacket.cpp # AOPacket encode/decode tests (Qt Test)
│   ├── missle.png        # Test asset
│   └── snackoo.png       # Test asset
├── CMakeLists.txt
├── configure.sh          # Cross-platform setup + build script
└── .clang-format         # Code formatting rules

Build System

CMake Options

Option Default Description
AO_BUILD_TESTS ON Build unit test programs
AO_ENABLE_DISCORD_RPC ON Enable Discord Rich Presence support

The executable is output to ./bin/ via RUNTIME_OUTPUT_DIRECTORY.

configure.sh — Primary Setup Script

configure.sh is the one-stop entry point for setting up and building the project.

./configure.sh                        # Auto-detect Qt, build Debug
./configure.sh QT_ROOT=/c/Qt          # Specify Qt root explicitly
./configure.sh clean                  # Remove lib/, bin/, tmp/, qtapng/
./configure.sh -h                     # Print help

What configure.sh does:

  1. Detects platform (windows / linux / macos) via uname -s
  2. Locates Qt installation root and resolves versioned Qt 6.5.3 paths
  3. Finds CMake, MinGW (Windows), and Ninja bundled with Qt
  4. Downloads and installs dependencies into ./lib/ and ./bin/:
    • BASS from https://www.un4seen.com/files/bass24.zip
    • BASSOPUS from https://www.un4seen.com/files/bassopus24.zip
    • discord-rpc v3.4.0 from GitHub releases
    • QtApng (cloned from GitHub, built with CMake+Ninja)
    • Themes (cloned into ./bin/base/themes)
  5. Runs CMake and Ninja to build the project
  6. On Windows Release: runs windeployqt to copy Qt DLLs
  7. Saves the full CMake command to cmake_cmd.txt for IDE reference

Manual Build (after dependencies are in place)

mkdir cbuild && cd cbuild
cmake .. -G Ninja -DCMAKE_PREFIX_PATH=/path/to/Qt/6.5.3/gcc_64
ninja

Base Game Content

The vanilla base content (characters, sounds, backgrounds) is not in the repository. Download and extract into ./bin/base/:

https://ao-dl.b-cdn.net/vanilla_full_2024_8_2.zip

Scripts

Script Purpose
APPIMAGE_INSTALL.sh Linux AppImage installation
DYNAMIC_INSTALL.sh Linux dynamic library installation
Attorney_Online.desktop Linux desktop entry file
macos_release.sh macOS release packaging
wasabi.sh / wasabi_program.sh Wasabi (S3-compatible) asset upload/sync

Code Style and Naming Conventions

All code must be formatted with clang-format before committing. The CI pipeline enforces this.

clang-format -i src/**/*.cpp src/**/*.h

.clang-format Summary

  • Base style: LLVM
  • Indent width: 2 spaces
  • Column limit: 486 (effectively no hard wrap)
  • Brace style: Allman — every opening brace on its own line
  • Short blocks: Only empty blocks on a single line
  • Pointer alignment: Right (int *ptr)
  • Qualifier alignment: Left (const int)
  • Constructor initializers: Each on its own line (BeforeComma)

Naming Conventions

Element Convention Example
Classes PascalCase AOApplication, Courtroom, AOPacket
AO-prefixed classes AO + PascalCase AOButton, AOImage, AOBlipPlayer
Member variables m_ prefix + snake_case m_header, m_content
Public member vars snake_case (no prefix) net_manager, w_lobby
Functions / methods snake_case construct_lobby(), send_server_packet()
Parameters p_ prefix + snake_case (some older code) p_packet
Enums SCREAMING_SNAKE_CASE CHAT_MESSAGE, EMOTE_MOD_TYPE
File names lowercase snake_case file_functions.cpp, debug_functions.h
Header guards #pragma once

Include Order

  1. Corresponding .h for a .cpp file
  2. Project headers ("filename.h")
  3. Third-party library headers (<bass.h>)
  4. Qt headers (<QObject>, <QString>, etc.)
  5. Standard library headers

Testing

Tests use the Qt Test framework and are built when AO_BUILD_TESTS=ON (default).

# Build and run tests
cd cbuild && make test

# Run test binary directly
./test/test

Existing Tests

Test Source What it tests
test_aopacket test_aopacket.cpp AOPacket construction, encode(), decode(), special character substitutions

AOPacket wire format: HEADER#arg1#arg2#%. Special character substitutions: #<num>, %<percent>, $<dollar>, &<and>.

Tests tagged [noci] are excluded from GitHub Actions CI (e.g. tests requiring audio hardware).

CI

GitHub Actions runs .github/workflows/build.yml which checks:

  • Clean compilation
  • clang-format compliance (formatting check fails CI on unformatted code)
  • Tests (excluding [noci] tagged tests)