Compare commits

..

3 commits

11095 changed files with 254876 additions and 394481 deletions

View file

@ -1,7 +1,7 @@
---
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
# We base things of WebKit + Allman braces
# Compatible with clang-format-22 (enforced by tools/run_clang_format.py)
# Compatible with clang-format-20
Language: Cpp
# Access modifiers
@ -28,7 +28,8 @@ AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: None
AllowShortLoopsOnASingleLine: false
LambdaBodyIndentation: Signature
# Note: LambdaBodyIndentation not available in clang-format-20
# Template declarations
AlwaysBreakTemplateDeclarations: Yes
@ -70,8 +71,6 @@ BinPackParameters: false
# Namespaces
CompactNamespaces: false
NamespaceIndentation: None
WrapNamespaceBodyWithEmptyLines: Always
SeparateDefinitionBlocks: Always
# Braced lists and initializers
Cpp11BracedListStyle: false
@ -90,7 +89,8 @@ MaxEmptyLinesToKeep: 1
# Pointer and reference alignment
PointerAlignment: Left
ReferenceAlignment: Pointer
QualifierAlignment: Left # West Const
# Note: QualifierAlignment not available in clang-format-20, use manual const placement
# Comments
ReflowComments: Always

View file

@ -11,9 +11,7 @@
"remoteUser": "xiadmin",
"remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" },
"features": {
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
"moby": false
}
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
},
"customizations": {
"vscode": {

View file

@ -80,18 +80,6 @@ indent_brace_style = allman # This is unfortunately ignored in Visual Studio
[Makefile]
indent_style = tab
[*.{yml,yaml}]
[*.yml]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.json]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

2
.gitattributes vendored
View file

@ -12,8 +12,6 @@
*.h text eol=lf
*.sql text eol=lf
*.sh text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
# Retaining CRLF line ends in the documentation dir (for now..)
*.txt text eol=crlf

View file

@ -15,9 +15,9 @@ jobs:
name: Clang Tidy
uses: ./.github/workflows/runner_build.yml
with:
runner: ubuntu-26.04
runner: ubuntu-24.04
compiler: clang
compiler_version: 22
compiler_version: 20
build_type: Debug
tracy: false
build_modules: false
@ -64,9 +64,9 @@ jobs:
upload_artifact: false
clang_tidy: false
- build_type: Debug
runner: ubuntu-26.04
runner: ubuntu-24.04
compiler: gcc
compiler_version: 15
compiler_version: 14
tracy: false
build_modules: false
save_cache: true
@ -93,8 +93,8 @@ jobs:
- build_type: Release
os: ubuntu
compiler: gcc
compiler_version: 15
clang_format_version: 22
compiler_version: 14
clang_format_version: 20
tracy: false
build_modules: false
save_cache: false
@ -110,8 +110,8 @@ jobs:
- build_type: Release
os: alpine
compiler: clang
compiler_version: 22
clang_format_version: 22
compiler_version: 20
clang_format_version: 20
tracy: false
build_modules: false
save_cache: false

View file

@ -9,15 +9,14 @@ on:
jobs:
Publish_Changelog:
name: Generate and Publish Changelog
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- run: git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
- run: git config --global user.name "github-actions[bot]"
- uses: actions/checkout@v1
- uses: fregante/setup-git-user@v1
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y python3
sudo apt-get install -y python3.7
pip3 install requests
- name: Generate changelog
run: |

View file

@ -13,7 +13,7 @@ jobs:
permissions: write-all
steps:
- name: Comment on unchecked boxes in template
uses: actions/github-script@v9
uses: actions/github-script@v7
with:
script: |
function count_instances(string, word)

View file

@ -36,16 +36,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v3
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y software-properties-common cmake libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev binutils-dev libzstd-dev libdwarf-dev
sudo apt-get install -y software-properties-common cmake libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev binutils-dev
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@v2
with:
trap-caching: false
languages: ${{ matrix.language }}
@ -57,7 +57,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
# - name: Autobuild
# uses: github/codeql-action/autobuild@v4
# uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@ -73,7 +73,7 @@ jobs:
cmake --build build -j4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@v2
with:
# https://josh-ops.com/posts/github-codeql-ignore-files/
upload: false # disable the upload here - we will upload in a different action
@ -89,6 +89,6 @@ jobs:
output: sarif-results/${{ matrix.language }}.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v4
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: sarif-results/${{ matrix.language }}.sarif

View file

@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Comment on keywords in Discussion
uses: actions/github-script@v9
uses: actions/github-script@v6
with:
script: |
// Define the keywords to check (all lower-case for case-insensitive matching)

View file

@ -67,13 +67,13 @@ jobs:
echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
- uses: docker/login-action@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 1
@ -88,12 +88,12 @@ jobs:
f.write("renamer\n")
EOF
- uses: docker/setup-buildx-action@v4
- uses: docker/setup-buildx-action@v3
id: setup_buildx
- name: Restore build cache
if: ${{ !inputs.save_cache }}
uses: actions/cache/restore@v5
uses: actions/cache/restore@v4
env:
cmake_hash: ${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
source_hash: ${{ hashFiles('src/**/*', 'ext/**/*') }}
@ -108,7 +108,7 @@ jobs:
- name: Cache build
id: cache_build
if: ${{ inputs.save_cache }}
uses: actions/cache@v5
uses: actions/cache@v4
env:
cmake_hash: ${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
source_hash: ${{ hashFiles('src/**/*', 'ext/**/*') }}
@ -121,7 +121,7 @@ jobs:
${{ format('buildcache-docker-{0}-{1}{2}-{3}-{4}-', inputs.os, inputs.compiler, inputs.compiler_version, inputs.build_type, env.cmake_hash) }}
- name: Inject cache into container
uses: reproducible-containers/buildkit-cache-dance@v3.4.0
uses: reproducible-containers/buildkit-cache-dance@v3.2.0
with:
builder: ${{ steps.setup_buildx.outputs.name }}
cache-map: |
@ -145,7 +145,7 @@ jobs:
- name: Docker meta
id: docker-meta
uses: docker/metadata-action@v6
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ env.REPO }}
tags: |
@ -161,7 +161,7 @@ jobs:
- name: Build devtools image
if: ${{ inputs.publish && vars.PUBLISH_DOCKER != '' }}
uses: docker/build-push-action@v7
uses: docker/build-push-action@v6
with:
context: .
file: ${{ format('./docker/{0}.Dockerfile', inputs.os) }}
@ -173,7 +173,7 @@ jobs:
tags: ${{ format('ghcr.io/{0}/devtools:{1}', env.REPO_OWNER, inputs.os) }}
- name: Docker build and push
uses: docker/build-push-action@v7
uses: docker/build-push-action@v6
with:
context: .
file: ${{ format('./docker/{0}.Dockerfile', inputs.os) }}
@ -194,7 +194,7 @@ jobs:
- name: Archive image
if: ${{ inputs.upload_artifact || (inputs.publish && vars.PUBLISH_DOCKER == '') }}
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: ${{ format('LSB_{0}_image_{1}', inputs.os, github.sha) }}
path: ${{ format('{0}/LSB_{1}_image_{2}.tar', runner.temp, inputs.os, github.sha) }}

View file

@ -57,21 +57,21 @@ jobs:
echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: recursive # For navmeshes
- name: Download artifact
if: ${{ github.event_name == 'pull_request' }}
uses: actions/download-artifact@v8
uses: actions/download-artifact@v4
with:
name: ${{ env.artifact_name }}
path: ${{ runner.temp }}
- name: Download previous artifact
if: ${{ (github.event_name == 'workflow_run' || github.event_name == 'workflow_dispatch') && vars.PUBLISH_DOCKER == ''}}
uses: dawidd6/action-download-artifact@v21
uses: dawidd6/action-download-artifact@v3
with:
run_id: ${{ github.event.workflow_run.id }}
name: ${{ env.artifact_name }}
@ -91,7 +91,7 @@ jobs:
--user root \
--network ${{ job.services.database.network }} \
--mount type=bind,src=./navmeshes,dst=/server/navmeshes \
--mount type=bind,src=./ximeshes,dst=/server/ximeshes \
--mount type=bind,src=./losmeshes,dst=/server/losmeshes \
--mount type=bind,src=./modules,dst=/server/modules \
--mount type=bind,src=.,dst=/server/log \
--env XI_NETWORK_SQL_HOST=database \
@ -119,7 +119,7 @@ jobs:
- name: Run xi_test
id: xi_test
continue-on-error: true
run: docker exec test-server /bin/bash -c './xi_test --keep-going --retry 5 --output log/tests.ctrf.json'
run: docker exec test-server /bin/bash -c './xi_test --keep-going --output log/tests.ctrf.json'
- name: Publish Test Report
if: ${{ !cancelled() }}

View file

@ -29,7 +29,7 @@ jobs:
# $GITHUB_WORKSPACE is the workspace in the container (/__w/server/server)
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0
@ -46,7 +46,7 @@ jobs:
run: tr -d '\r' < sanity_checks_summary.md >> $GITHUB_STEP_SUMMARY
- name: Upload changed files as artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: changed-files
path: changed-files.txt
@ -63,7 +63,7 @@ jobs:
shell: bash
steps:
- name: Download Changed Files
uses: actions/download-artifact@v8
uses: actions/download-artifact@v4
with:
name: changed-files
@ -82,7 +82,7 @@ jobs:
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
- uses: actions/checkout@v6
- uses: actions/checkout@v4
if: ${{ steps.check-changes.outputs.lua_changes == 'true' }}
with:
fetch-depth: 0
@ -93,10 +93,6 @@ jobs:
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade -r ./tools/requirements.txt
- name: Generate codegen Lua enums
if: ${{ steps.check-changes.outputs.lua_changes == 'true' }}
run: python -m tools.codegen "$RUNNER_TEMP/codegen-out"
- name: Run Lua Language Server
id: run_lls
if: ${{ steps.check-changes.outputs.lua_changes == 'true' }}
@ -133,137 +129,14 @@ jobs:
echo "Lua Language Server failed. See summary for details."
exit 1
Schema_Validation:
needs: Sanity_Checks
name: Data validation
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Download Changed Files
uses: actions/download-artifact@v8
with:
name: changed-files
- name: Check for data/ or codegen changes
id: changed
run: |
mapfile -t changed_files < changed-files.txt
touched=false
for f in "${changed_files[@]}"; do
if [[ $f == data/* || $f == tools/codegen/* ]]; then
touched=true
break
fi
done
echo "touched=$touched" >> "$GITHUB_OUTPUT"
echo "Touched: $touched"
- uses: actions/checkout@v6
if: steps.changed.outputs.touched == 'true'
- name: Setup Python
if: steps.changed.outputs.touched == 'true'
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install Python dependencies
if: steps.changed.outputs.touched == 'true'
run: python -m pip install jinja2 jsonschema pyyaml
- name: Run codegen --validate
if: steps.changed.outputs.touched == 'true'
run: |
mkdir -p "$RUNNER_TEMP/codegen-out"
python -m tools.codegen "$RUNNER_TEMP/codegen-out" --validate
Formatting:
needs: Sanity_Checks
name: Data formatting
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Download Changed Files
uses: actions/download-artifact@v8
with:
name: changed-files
- name: Filter data/ changed files
id: changed
run: |
mapfile -t changed_files < changed-files.txt
yaml_files=()
other_files=()
for f in "${changed_files[@]}"; do
if [[ $f == data/*.yaml || $f == data/*.yml ]]; then
yaml_files+=("$f")
elif [[ $f == data/* ]]; then
other_files+=("$f")
fi
done
echo "yaml=${yaml_files[*]}" >> "$GITHUB_OUTPUT"
echo "other=${other_files[*]}" >> "$GITHUB_OUTPUT"
echo "Changed YAML: ${yaml_files[*]}"
echo "Changed other: ${other_files[*]}"
- uses: actions/checkout@v6
if: steps.changed.outputs.yaml != '' || steps.changed.outputs.other != ''
- name: Setup Python
if: steps.changed.outputs.yaml != ''
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install Python dependencies
if: steps.changed.outputs.yaml != ''
run: python -m pip install pyyaml ruamel.yaml
- name: Check YAML formatting
if: steps.changed.outputs.yaml != ''
run: python tools/yaml/format.py ${{ steps.changed.outputs.yaml }} --check
- name: Cache prettier results
if: steps.changed.outputs.other != ''
uses: actions/cache@v5
with:
path: /tmp/prettier-cache
key: prettier-cache-${{ hashFiles('data/**/*.json') }}
restore-keys: prettier-cache-
- name: Run prettier
if: steps.changed.outputs.other != ''
run: |
set +e
FAILED=$(npx --yes prettier@3 --cache --cache-strategy content --cache-location /tmp/prettier-cache --list-different ${{ steps.changed.outputs.other }})
set -e
if [ -z "$FAILED" ]; then
echo "All files use Prettier code style!"
exit 0
fi
echo "::group::Files needing reformat"
echo "$FAILED"
echo "::endgroup::"
echo "::group::Diff"
for f in $FAILED; do
diff -u "$f" <(npx --yes prettier@3 "$f") || true
done
echo "::endgroup::"
echo "Run \`npx prettier --write data\` locally to fix."
exit 1
Clang_Tidy:
needs: Sanity_Checks
name: Clang Tidy
uses: ./.github/workflows/runner_build.yml
with:
runner: ubuntu-26.04
runner: ubuntu-24.04
compiler: clang
compiler_version: 22
compiler_version: 20
build_type: Debug
build_modules: false
tracy: false
@ -287,9 +160,9 @@ jobs:
compiler: appleClang
build_modules: false
- build_type: Debug
runner: ubuntu-26.04
runner: ubuntu-24.04
compiler: gcc
compiler_version: 15
compiler_version: 14
build_modules: false
uses: ./.github/workflows/runner_build.yml
with:
@ -316,9 +189,9 @@ jobs:
- runner: macos-26
test_modules: false
multi_process: false
xi_test: true
xi_test: false
startup_checks: true
- runner: ubuntu-26.04
- runner: ubuntu-24.04
test_modules: false
multi_process: false
xi_test: true

View file

@ -16,7 +16,7 @@ jobs:
permissions: write-all
steps:
- name: Check for blocking labels
uses: actions/github-script@v9
uses: actions/github-script@v7
with:
script: |
const response = await github.rest.issues.listLabelsOnIssue({

View file

@ -5,8 +5,8 @@ on:
branches:
- base
paths:
- './losmeshes/**'
- './navmeshes/**'
- './ximeshes/**'
- '.gitmodules'
workflow_dispatch:
@ -23,23 +23,23 @@ jobs:
echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
submodules: true
- name: Login to GHCR
uses: docker/login-action@v4
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v6
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ env.REPO_OWNER }}/ximeshes
tags: |
@ -50,7 +50,7 @@ jobs:
org.opencontainers.image.description=Line-of-sight and navigation meshes for use with LandSandBoat server.
- name: Build and push
uses: docker/build-push-action@v7
uses: docker/build-push-action@v6
env:
BUILDX_NO_DEFAULT_ATTESTATIONS: 1
with:

View file

@ -64,7 +64,7 @@ jobs:
steps:
- name: Download changed files artifact
if: ${{ inputs.optional_build }}
uses: actions/download-artifact@v8
uses: actions/download-artifact@v4
with:
name: changed-files
@ -92,14 +92,14 @@ jobs:
- name: Checkout
if: ${{ env.SKIP_BUILD != 'true' }}
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Install dependencies (macOS)
if: ${{ runner.os == 'macOS' && env.SKIP_BUILD != 'true' }}
run: |
brew install --quiet \
brew update && brew install --quiet \
mariadb \
zeromq \
luajit \
@ -108,7 +108,7 @@ jobs:
- name: Setup LLVM Clang (macOS)
if: ${{ runner.os == 'macOS' && startsWith(inputs.compiler, 'clang') && env.SKIP_BUILD != 'true' }}
run: |
brew install --quiet \
brew update && brew install --quiet \
llvm@${{ inputs.compiler_version }} \
lld@${{ inputs.compiler_version }}
@ -128,7 +128,7 @@ jobs:
- name: Setup GCC (macOS)
if: ${{ runner.os == 'macOS' && startsWith(inputs.compiler, 'gcc') && env.SKIP_BUILD != 'true' }}
run: |
brew install --quiet gcc@${{ inputs.compiler_version }}
brew update && brew install --quiet gcc@${{ inputs.compiler_version }}
GCC_PREFIX=$(brew --prefix gcc@${{ inputs.compiler_version }})
echo "PATH=$GCC_PREFIX/bin:$PATH" >> $GITHUB_ENV
echo "CC=$GCC_PREFIX/bin/gcc-${{ inputs.compiler_version }}" >> $GITHUB_ENV
@ -139,7 +139,6 @@ jobs:
run: |
sudo apt-get update && sudo apt-get install --assume-yes --no-install-recommends --quiet \
binutils-dev \
libdwarf-dev \
libluajit-5.1-dev \
libmariadb-dev-compat \
libssl-dev \
@ -147,8 +146,7 @@ jobs:
luajit \
mariadb-client \
tzdata \
zlib1g-dev \
libzstd-dev
zlib1g-dev
- name: Setup GCC (Linux)
if: ${{ runner.os == 'Linux' && startsWith(inputs.compiler, 'gcc') && env.SKIP_BUILD != 'true' }}
@ -175,25 +173,21 @@ jobs:
- name: Setup MSVC
if: ${{ runner.os == 'Windows' && env.SKIP_BUILD != 'true' }}
uses: TheMrMilchmann/setup-msvc-dev@v4
uses: TheMrMilchmann/setup-msvc-dev@v3
with:
arch: x64
- name: Setup sccache
if: ${{ env.SKIP_BUILD != 'true' }}
uses: mozilla-actions/sccache-action@v0.0.10
uses: mozilla-actions/sccache-action@v0.0.9
with:
disable_annotations: ${{ !inputs.save_cache }}
- name: Setup Python
if: ${{ env.SKIP_BUILD != 'true' }}
uses: actions/setup-python@v6
uses: actions/setup-python@v5
with:
python-version: '3.14'
- name: Install Python codegen deps
if: ${{ env.SKIP_BUILD != 'true' }}
run: python -m pip install jinja2 jsonschema pyyaml
python-version: '3.12'
- name: Enable modules
if: ${{ inputs.build_modules && env.SKIP_BUILD != 'true' }}
@ -209,7 +203,7 @@ jobs:
- name: Restore build cache
if: ${{ env.SKIP_BUILD != 'true' }}
id: restore_build
uses: actions/cache/restore@v5
uses: actions/cache/restore@v4
env:
cmake_hash: ${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
source_hash: ${{ hashFiles('src/**/*', 'ext/**/*') }}
@ -236,25 +230,16 @@ jobs:
- name: Upload artifact
if: ${{ inputs.upload_artifact && env.SKIP_BUILD != 'true' }}
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: ${{ format('LSB_{0}_{1}_{2}', runner.os, inputs.build_type, github.sha) }}
path: |
xi_*
tracy.tar.gz
- name: Remove exes from build cache
if: ${{ inputs.save_cache && env.SKIP_BUILD != 'true' && steps.restore_build.outputs.cache-hit != 'true' }}
run: |
rm -f build/src/login/xi_connect*
rm -f build/src/map/xi_map*
rm -f build/src/search/xi_search*
rm -f build/src/test/xi_test*
rm -f build/src/world/xi_world*
- name: Cache build
if: ${{ inputs.save_cache && env.SKIP_BUILD != 'true' && steps.restore_build.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v5
uses: actions/cache/save@v4
with:
path: build
key: ${{ steps.restore_build.outputs.cache-primary-key }}

View file

@ -53,7 +53,7 @@ jobs:
XI_NETWORK_SQL_LOGIN: xiadmin
XI_NETWORK_SQL_PASSWORD: 'password'
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: recursive # For navmeshes
@ -80,7 +80,6 @@ jobs:
sudo apt-get update && sudo apt-get install --assume-yes --no-install-recommends --quiet \
binutils \
git \
libdwarf1 \
libmariadb-dev-compat \
libzmq5 \
lua5.1 \
@ -110,10 +109,10 @@ jobs:
${{ env.MYSQL_CMD }} -e "GRANT ALL PRIVILEGES ON ${{ env.XI_NETWORK_SQL_DATABASE }}.* TO '${{ env.XI_NETWORK_SQL_LOGIN }}'@'%';"
${{ env.MYSQL_CMD }} -e "FLUSH PRIVILEGES;"
- uses: actions/setup-python@v6
- uses: actions/setup-python@v5
id: setup_python
with:
python-version: '3.14'
python-version: '3.12'
- name: Install Python dependencies
run: |
@ -127,19 +126,16 @@ jobs:
echo "${{ runner.os == 'Windows' && '.venv/Scripts' || '.venv/bin' }}" >> $GITHUB_PATH
echo "VIRTUAL_ENV=$(pwd)/.venv" >> $GITHUB_ENV
- name: Generate codegen Lua enums
run: python -m tools.codegen "$RUNNER_TEMP/codegen-out"
- name: Download artifact
if: ${{ github.event_name == 'pull_request' }}
uses: actions/download-artifact@v8
uses: actions/download-artifact@v4
with:
name: ${{ format('LSB_{0}_{1}_{2}', runner.os, inputs.build_type, github.sha) }}
path: .
- name: Download previous artifact
if: ${{ github.event_name == 'workflow_run' || github.event_name == 'workflow_dispatch' }}
uses: dawidd6/action-download-artifact@v21
uses: dawidd6/action-download-artifact@v3
with:
run_id: ${{ github.event.workflow_run.id }}
name: ${{ format('LSB_{0}_{1}_{2}', runner.os, inputs.build_type, github.sha) }}
@ -168,7 +164,7 @@ jobs:
if: ${{ inputs.xi_test }}
id: xi_test
continue-on-error: true
run: ./xi_test --keep-going --retry 5 --output tests.ctrf.json
run: ./xi_test --keep-going --output tests.ctrf.json
- name: Publish Test Report
if: ${{ !cancelled() && inputs.xi_test }}
@ -189,7 +185,7 @@ jobs:
- name: Startup checks
if: ${{ inputs.startup_checks }}
id: startup_checks
uses: nick-fields/retry@v4
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3

View file

@ -25,7 +25,7 @@ jobs:
shell: bash
steps:
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0
@ -47,13 +47,10 @@ jobs:
shell: bash
steps:
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate codegen Lua enums
run: python -m tools.codegen "$RUNNER_TEMP/codegen-out"
- name: Run Lua Language Server
id: run_lls
run: python ./tools/ci/lua_lang_server.py
@ -101,7 +98,7 @@ jobs:
build_type: Release
test_modules: false
multi_process: true
xi_test: true
xi_test: ${{ !startsWith(matrix.runner, 'macos') }}
startup_checks: true
Docker_Test:

8
.gitignore vendored
View file

@ -14,7 +14,6 @@
# Build results
build/
build*/
.cpm-cache/
lbuild/
build_mariadb_32/
build_mariadb_64/
@ -163,7 +162,6 @@ src/common/stamp-h1
*.sw?
navmeshes/*.nav
ximeshes/*.ximesh
tags
log/**
!log/.gitkeep
@ -219,8 +217,6 @@ ip.txt
# Tracy download
ext/tracy/
tracy.tar.gz
tracy*
**/*.tracy
# Valgrind
*.memcheck.log
@ -269,7 +265,3 @@ __pycache__
sanity_checks_summary.md
changed-files.txt
clang_tidy_summary.md
# YAML codegen
*.codegen.json
*.codegen.lua

10
.gitmodules vendored
View file

@ -1,6 +1,6 @@
[submodule "navmeshes"]
path = navmeshes
url = https://github.com/LandSandBoat/xiNavmeshes.git
[submodule "ximeshes"]
path = ximeshes
url = https://github.com/InoUno/ximeshes.git
path = navmeshes
url = https://github.com/LandSandBoat/xiNavmeshes.git
[submodule "losmeshes"]
path = losmeshes
url = https://github.com/LandSandBoat/losmeshes.git

View file

@ -1,11 +0,0 @@
*.codegen.json
*.codegen.lua
# YAML is formatted by tools/yaml/format.py
*.yaml
*.yml
build/
build*/
cmake-*/
out/

View file

@ -1,6 +0,0 @@
{
"tabWidth": 2,
"useTabs": false,
"printWidth": 120,
"endOfLine": "lf"
}

View file

@ -11,9 +11,6 @@
"ms-vscode.cpptools-extension-pack",
"ms-vscode.cpptools",
"jeff-hykin.better-cpp-syntax",
"bierner.github-markdown-preview",
"esbenp.prettier-vscode",
"redhat.vscode-yaml",
"jkillian.custom-local-formatters"
"bierner.github-markdown-preview"
]
}

15
.vscode/settings.json vendored
View file

@ -335,7 +335,6 @@
"GetSynergyRecipeByID",
"GetSynergyRecipeByTrade",
"ReloadSynthRecipes",
"LoadExpDifficultyCurves",
],
"Lua.diagnostics.disable": [
"lowercase-global"
@ -355,20 +354,6 @@
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true
},
"[yaml]": {
"editor.defaultFormatter": "jkillian.custom-local-formatters",
"editor.formatOnSave": true
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"yaml.format.enable": false,
"customLocalFormatters.formatters": [
{
"command": "python tools/yaml/format.py --stdin",
"languages": ["yaml"]
}
],
"files.associations": {
"algorithm": "cpp",
"any": "cpp",

View file

@ -4,35 +4,15 @@ cmake_minimum_required(VERSION 3.25)
cmake_policy(SET CMP0141 NEW)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded)
# On macOS, pin the deployment target to the host OS version (must happen before
# project()). Without this, some compilers infer it from the Darwin kernel version
# using the pre-macOS-26 numbering scheme (e.g. Homebrew LLVM 20 maps Darwin 25 to
# "macOS 16.0" instead of 26), and every link against a Homebrew dylib stamped with
# the real version warns:
# ld: warning: building for macOS-16.0, but linking with dylib built for newer version 26.0
# Overridable as usual via -DCMAKE_OSX_DEPLOYMENT_TARGET or MACOSX_DEPLOYMENT_TARGET.
if(CMAKE_HOST_APPLE AND "${CMAKE_OSX_DEPLOYMENT_TARGET}" STREQUAL "" AND "$ENV{MACOSX_DEPLOYMENT_TARGET}" STREQUAL "")
execute_process(
COMMAND sw_vers -productVersion
OUTPUT_VARIABLE host_macos_version
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REGEX MATCH "^[0-9]+" host_macos_major "${host_macos_version}")
if(host_macos_major)
set(CMAKE_OSX_DEPLOYMENT_TARGET "${host_macos_major}.0")
endif()
endif()
project(server C CXX)
# https://cmake.org/cmake/help/latest/policy/CMP0069.html
cmake_policy(SET CMP0069 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
set(LINKER_LANGUAGE CXX)
set(USE_FOLDERS ON)
@ -69,16 +49,6 @@ elseif ("${CMAKE_BUILD_TYPE_UPPER}" STREQUAL "RELEASE")
message(STATUS "CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
elseif ("${CMAKE_BUILD_TYPE_UPPER}" STREQUAL "RELWITHDEBINFO")
message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
elseif ("${CMAKE_BUILD_TYPE_UPPER}" STREQUAL "ASAN")
message(STATUS "CMAKE_CXX_FLAGS_ASAN: ${CMAKE_CXX_FLAGS_ASAN}")
elseif ("${CMAKE_BUILD_TYPE_UPPER}" STREQUAL "UBSAN")
message(STATUS "CMAKE_CXX_FLAGS_UBSAN: ${CMAKE_CXX_FLAGS_UBSAN}")
elseif ("${CMAKE_BUILD_TYPE_UPPER}" STREQUAL "TSAN")
message(STATUS "CMAKE_CXX_FLAGS_TSAN: ${CMAKE_CXX_FLAGS_TSAN}")
elseif ("${CMAKE_BUILD_TYPE_UPPER}" STREQUAL "MSAN")
message(STATUS "CMAKE_CXX_FLAGS_MSAN: ${CMAKE_CXX_FLAGS_MSAN}")
elseif ("${CMAKE_BUILD_TYPE_UPPER}" STREQUAL "LSAN")
message(STATUS "CMAKE_CXX_FLAGS_LSAN: ${CMAKE_CXX_FLAGS_LSAN}")
else()
message(FATAL_ERROR "Did not recognise CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} to print out compiler flags.")
endif()
@ -92,22 +62,6 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
link_libraries(${CMAKE_THREAD_LIBS_INIT})
CPMAddPackage(
NAME ZLIB
GITHUB_REPOSITORY madler/zlib
GIT_TAG v1.3.1
OPTIONS "ZLIB_BUILD_EXAMPLES OFF"
)
if(ZLIB_ADDED)
add_library(ZLIB::ZLIB ALIAS zlibstatic)
endif()
CPMAddPackage(
NAME utfcpp
GITHUB_REPOSITORY nemtrif/utfcpp
GIT_TAG v4.0.8
)
# Find Python (defines ${Python_EXECUTABLE})
find_package(Python REQUIRED)
message(STATUS "Python_EXECUTABLE: ${Python_EXECUTABLE}")
@ -118,6 +72,7 @@ endif()
# Find MariaDB
find_package(MariaDB REQUIRED)
find_package(MariaDBCPP REQUIRED)
# Find ZMQ
find_package(ZeroMQ REQUIRED)
@ -132,39 +87,29 @@ find_package(OpenSSLlibcrypto REQUIRED)
find_package(OpenSSLlibssl REQUIRED)
if(UNIX AND NOT APPLE)
# zstd is sometimes a prereq for binutils
find_package(Zstd REQUIRED)
find_package(Binutils REQUIRED)
endif()
# Link this 'library' to set the c++ standard / compile-time options requested
add_library(project_options INTERFACE)
target_compile_features(project_options INTERFACE cxx_std_23)
# Windows-only preprocessor defines for our first-party code ONLY.
if(WIN32)
target_compile_definitions(project_options INTERFACE
NOMINMAX
WIN32_LEAN_AND_MEAN
_CRT_SECURE_NO_WARNINGS
)
endif()
target_compile_features(project_options INTERFACE cxx_std_17)
# Link this 'library' to use the warnings specified in CompilerWarnings.cmake
add_library(project_warnings INTERFACE)
set_project_warnings(project_warnings)
add_compile_definitions(
# Globally define SOL_ALL_SAFETIES_ON so sol can be included anywhere.
SOL_ALL_SAFETIES_ON=1
# If SOL_NO_CHECK_NUMBER_PRECISION is defined, turns off number precision and integer
# precision fitting when pushing numbers into sol.
SOL_NO_CHECK_NUMBER_PRECISION=1
SOL_DEFAULT_PASS_ON_ERROR=1
SOL_PRINT_ERRORS=0
SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_DEBUG
XI_CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
XI_BUILD_TYPE="$<CONFIG>"
# Globally define SOL_ALL_SAFETIES_ON so sol can be included anywhere
# If SOL_NO_CHECK_NUMBER_PRECISION is defined, turns off number precision and integer
# precision fitting when pushing numbers into sol
# RC_FAST_MATH informs recastnavigation to not try to use infinity because we use -ffast-math
# add_compile_definitions() comes with CMake 3.12
add_definitions(
-DSOL_ALL_SAFETIES_ON=1
-DSOL_NO_CHECK_NUMBER_PRECISION=1
-DSOL_DEFAULT_PASS_ON_ERROR=1
-DSOL_PRINT_ERRORS=0
-DRC_FAST_MATH=1
-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_DEBUG
)
# For external libs
@ -206,45 +151,6 @@ if (NOT IPC_EXIT_CODE EQUAL 0)
message(FATAL_ERROR "Failed to generate IPC stubs")
endif()
execute_process(
COMMAND ${Python_EXECUTABLE} -c "import jinja2, jsonschema, yaml"
RESULT_VARIABLE CODEGEN_DEPS_EXIT_CODE
OUTPUT_QUIET
ERROR_QUIET
)
if(NOT CODEGEN_DEPS_EXIT_CODE EQUAL 0)
message(FATAL_ERROR
"Codegen requires the Python packages jinja2, jsonschema, and pyyaml, "
"but they are not installed for the interpreter CMake selected:\n"
" ${Python_EXECUTABLE}\n"
"Install them by running this command exactly as shown (the interpreter path "
"matters, so the packages land in the environment this build uses):\n"
" ${Python_EXECUTABLE} -m pip install -r ${CMAKE_SOURCE_DIR}/tools/requirements.txt"
)
endif()
add_custom_target(data_codegen
COMMAND ${Python_EXECUTABLE} -m tools.codegen ${CMAKE_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
BYPRODUCTS
${CMAKE_BINARY_DIR}/generated/.codegen.stamp
${CMAKE_BINARY_DIR}/generated/data/all.h
USES_TERMINAL
VERBATIM
)
if(NOT EXISTS ${CMAKE_BINARY_DIR}/generated/.codegen.stamp)
message(STATUS "Bootstrapping data codegen")
execute_process(
COMMAND ${Python_EXECUTABLE} -m tools.codegen ${CMAKE_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE CODEGEN_EXIT_CODE
)
if(NOT CODEGEN_EXIT_CODE EQUAL 0)
message(FATAL_ERROR "Bootstrap codegen failed")
endif()
endif()
include_directories(${CMAKE_BINARY_DIR}/generated) # Globally include the build/generated directory
add_subdirectory(src)

View file

@ -1,42 +0,0 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default (RelWithDebInfo)",
"description": "Optimized build with debug info. The standard configuration.",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
},
{
"name": "debug",
"displayName": "Debug",
"description": "Unoptimized build with full debug info.",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}
],
"buildPresets": [
{
"name": "default",
"displayName": "Default (RelWithDebInfo)",
"configurePreset": "default",
"configuration": "RelWithDebInfo"
},
{
"name": "debug",
"displayName": "Debug",
"configurePreset": "debug",
"configuration": "Debug"
}
]
}

View file

@ -30,10 +30,6 @@ Discussions are similar to forum posts. Please open a new discussion post in the
*If you are encountering an issue, please open an issue and not a discussion!* It's much easier for us to track and you're more likely to get resolution through an issue.
### AI Agents and their use
If you're a human using AI agents or an AI agent you should go read `./documentation/ai_agents/README.md`.
## LICENSE
LandSandBoat is licensed under [GNU GPL v3](https://github.com/LandSandBoat/server/blob/base/LICENSE)

View file

@ -81,7 +81,6 @@ function(set_project_warnings project_name)
CLANG_WARNINGS
-Wno-nan-infinity-disabled # TODO: fmt triggers this, a combination of the fast-math flag and `isfinite`
-Wunused-private-field # warn on unused private fields
-Wno-nontrivial-memcall # recastnavigation memsets non-trivially-copyable types (e.g. dtMeshTile)
)
endif()

275
cmake/FindMariaDBCPP.cmake Normal file
View file

@ -0,0 +1,275 @@
if(NOT WIN32)
message(STATUS "Building MariaDB Connector/C++ from source")
CPMAddPackage(
NAME mariadb-connector-cpp
GITHUB_REPOSITORY zach2good/mariadb-connector-cpp
GIT_TAG fa70cf8927d259374ed711b0d2f1770c70e5b437
DOWNLOAD_ONLY YES
)
if(mariadb-connector-cpp_ADDED)
set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 0)
set(PROJECT_VERSION_PATCH 0)
configure_file(
${mariadb-connector-cpp_SOURCE_DIR}/src/Version.h.in
${mariadb-connector-cpp_SOURCE_DIR}/src/Version.h
)
configure_file(
${mariadb-connector-cpp_SOURCE_DIR}/src/maconncpp.def.in
${mariadb-connector-cpp_SOURCE_DIR}/src/maconncpp.def
)
set(MACPP_SOURCES
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDriver.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/DriverManager.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/UrlParser.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDatabaseMetaData.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/HostAddress.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/Consts.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/SQLString.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbConnection.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbStatement.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBException.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBWarning.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/Identifier.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbSavepoint.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/SqlStates.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/Results.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnType.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnDefinition.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/MasterProtocol.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/QueryProtocol.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/ConnectProtocol.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/ColumnDefinitionCapi.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCache.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCacheKey.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Value.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Utils.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/util/String.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/NoLogger.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/LoggerFactory.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/ProtocolLoggingProxy.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ParameterHolder.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/options/Options.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/options/DefaultOptions.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/GlobalStateInfo.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/Pools.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/failover/FailoverProxy.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/CredentialPluginLoader.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/SelectResultSet.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/SelectResultSetCapi.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/ColumnNameMap.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/io/StandardPacketInputStream.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/Charset.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/ClientSidePreparedStatement.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/BasePrepareStatement.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbFunctionStatement.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbProcedureStatement.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/ServerSidePreparedStatement.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BigDecimalParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BooleanParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteArrayParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DateParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DefaultParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DoubleParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/FloatParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/IntParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/LongParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ULongParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/NullParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ParameterHolder.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ReaderParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ShortParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StreamParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimeParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimestampParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StringParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbPooledConnection.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbParameterMetaData.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbResultSetMetaData.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/CallParameter.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/CallableParameterMetaData.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/Packet.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/Credential.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/util/LogQueryTool.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ClientPrepareResult.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareResult.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareStatementCache.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationSingle.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationBatch.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationMultiple.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/com/RowProtocol.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/BinRowProtocolCapi.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/TextRowProtocolCapi.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/ExceptionFactory.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/StringImp.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/CArray.cpp
${mariadb-connector-cpp_SOURCE_DIR}/src/SimpleParameterMetaData.cpp
)
# NOTE: Keep this around if we ever want to rebuild the mariadb-connector-cpp library
if(WIN32)
set(MACPP_SOURCES
${MACPP_SOURCES}
${mariadb-connector-cpp_SOURCE_DIR}/src/Dll.c
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBConnCpp.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDriver.h
${mariadb-connector-cpp_SOURCE_DIR}/src/UrlParser.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDatabaseMetaData.h
${mariadb-connector-cpp_SOURCE_DIR}/src/HostAddress.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Version.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Consts.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbConnection.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbStatement.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBWarning.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Protocol.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Identifier.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbSavepoint.h
${mariadb-connector-cpp_SOURCE_DIR}/src/SqlStates.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Results.h
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnDefinition.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbServerCapabilities.h
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/MasterProtocol.h
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/QueryProtocol.h
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/ConnectProtocol.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/ColumnDefinitionCapi.h
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCache.h
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCacheKey.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Value.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ClassField.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Utils.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/StateChange.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/String.h
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/NoLogger.h
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/LoggerFactory.h
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/Logger.h
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/ProtocolLoggingProxy.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ParameterHolder.h
${mariadb-connector-cpp_SOURCE_DIR}/src/options/Options.h
${mariadb-connector-cpp_SOURCE_DIR}/src/options/DefaultOptions.h
${mariadb-connector-cpp_SOURCE_DIR}/src/options/DriverPropertyInfo.h
${mariadb-connector-cpp_SOURCE_DIR}/src/io/PacketOutputStream.h
${mariadb-connector-cpp_SOURCE_DIR}/src/io/PacketInputStream.h
${mariadb-connector-cpp_SOURCE_DIR}/src/io/StandardPacketInputStream.h
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/CredentialPlugin.h
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/CredentialPluginLoader.h
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/GlobalStateInfo.h
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/Pools.h
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/Pool.h
${mariadb-connector-cpp_SOURCE_DIR}/src/failover/FailoverProxy.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Listener.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformation.h
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Connection.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Statement.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/ResultSet.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/PreparedStatement.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/ParameterMetaData.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/ResultSetMetaData.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/DatabaseMetaData.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/CallableStatement.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/SQLString.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Warning.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Exception.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/jdbccompat.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Driver.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/DriverManager.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Types.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/buildconf.hpp
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/CArray.hpp
${mariadb-connector-cpp_SOURCE_DIR}/src/SelectResultSet.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/SelectResultSetCapi.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/SelectResultSetPacket.h
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnType.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/ColumnDefinitionPacket.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/ColumnNameMap.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Charset.h
${mariadb-connector-cpp_SOURCE_DIR}/src/ClientSidePreparedStatement.h
${mariadb-connector-cpp_SOURCE_DIR}/src/BasePrepareStatement.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbFunctionStatement.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbProcedureStatement.h
${mariadb-connector-cpp_SOURCE_DIR}/src/ServerSidePreparedStatement.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BigDecimalParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BooleanParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteArrayParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DateParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DefaultParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DoubleParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/FloatParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/IntParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/LongParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ULongParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/NullParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ReaderParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ShortParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StreamParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimeParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimestampParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StringParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/Parameters.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbPooledConnection.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbParameterMetaData.h
${mariadb-connector-cpp_SOURCE_DIR}/src/CallParameter.h
${mariadb-connector-cpp_SOURCE_DIR}/src/CallableParameterMetaData.h
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbResultSetMetaData.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/Packet.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerStatus.h
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/Credential.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/LogQueryTool.h
${mariadb-connector-cpp_SOURCE_DIR}/src/PrepareResult.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ClientPrepareResult.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareResult.h
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareStatementCache.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationSingle.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationBatch.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationMultiple.h
${mariadb-connector-cpp_SOURCE_DIR}/src/com/RowProtocol.h
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/BinRowProtocolCapi.h
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/TextRowProtocolCapi.h
${mariadb-connector-cpp_SOURCE_DIR}/src/ExceptionFactory.h
${mariadb-connector-cpp_SOURCE_DIR}/src/StringImp.h
${mariadb-connector-cpp_SOURCE_DIR}/src/CArrayImp.h
${mariadb-connector-cpp_SOURCE_DIR}/src/SimpleParameterMetaData.h
${mariadb-connector-cpp_SOURCE_DIR}/src/maconncpp.def
)
endif()
add_library(mariadbclientcpp STATIC ${MACPP_SOURCES})
target_include_directories(mariadbclientcpp
PUBLIC
${mariadb-connector-cpp_SOURCE_DIR}/include
PRIVATE
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp
${mariadb-connector-cpp_SOURCE_DIR}/src/
)
target_link_libraries(mariadbclientcpp PRIVATE mariadbclient)
set(MARIADBCPP_FOUND TRUE)
set(MARIADBCPP_LIBRARY mariadbclientcpp)
set(MARIADBCPP_INCLUDE_DIR ${mariadb-connector-cpp_SOURCE_DIR}/include)
endif()
else() # WIN32
message(STATUS "Looking for prebuilt MariaDB Connector/C++")
find_library(MARIADBCPP_LIBRARY
NAMES
mariadbcpp
PATHS
${PROJECT_SOURCE_DIR}/ext/mariadbcpp/${lib_dir}/
)
set(MARIADBCPP_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/ext/mariadbcpp/include/) # Only look internally
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MariaDBCPP DEFAULT_MSG MARIADBCPP_LIBRARY MARIADBCPP_INCLUDE_DIR)
endif()
message(STATUS "MARIADBCPP_FOUND: ${MARIADBCPP_FOUND}")
message(STATUS "MARIADBCPP_LIBRARY: ${MARIADBCPP_LIBRARY}")
message(STATUS "MARIADBCPP_INCLUDE_DIR: ${MARIADBCPP_INCLUDE_DIR}")
add_library(mariadbcpp INTERFACE)
target_link_libraries(mariadbcpp INTERFACE ${MARIADBCPP_LIBRARY})
target_include_directories(mariadbcpp SYSTEM INTERFACE ${MARIADBCPP_INCLUDE_DIR})

View file

@ -1,18 +0,0 @@
find_library(ZSTD_LIBRARY
NAMES
libzstd zstd
PATHS
/usr/
/usr/bin/
/usr/include/
/usr/lib/
/usr/local/
/usr/local/bin/
/opt/)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Zstd DEFAULT_MSG ZSTD_LIBRARY)
#link_libraries(zstd)
message(STATUS "Zstd_FOUND: ${ZSTD_FOUND}")
message(STATUS "Zstd_LIBRARY: ${ZSTD_LIBRARY}")

View file

@ -1,12 +1,12 @@
message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
if(${CMAKE_SOURCE_DIR} MATCHES " +")
set(STRIPPED_PATH "")
STRING(REGEX REPLACE " +" "_" STRIPPED_PATH "${CMAKE_SOURCE_DIR}")
set(STRIPPED_PATH "")
STRING(REGEX REPLACE " +" "_" STRIPPED_PATH "${CMAKE_SOURCE_DIR}")
message(STATUS
"Current path: ${CMAKE_SOURCE_DIR}\n"
"Suggested path: ${STRIPPED_PATH}\n"
"Your path contains spaces, this is not recommended.")
message(STATUS
"Current path: ${CMAKE_SOURCE_DIR}\n"
"Suggested path: ${STRIPPED_PATH}\n"
"Your path contains spaces, this is not recommended.")
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
@ -33,15 +33,3 @@ set(libpath "lib${platform_suffix}")
if(WIN32)
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
endif()
if(APPLE)
# The modern Apple linker (ld_prime, Xcode 15+) warns when the same library
# appears more than once on the link line. CMake's dependency propagation
# legitimately repeats static libs (historically required by classic ld64),
# so the warning is pure noise: silence it where the linker supports the flag.
include(CheckLinkerFlag)
check_linker_flag(CXX "-Wl,-no_warn_duplicate_libraries" LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
if(LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
add_link_options("-Wl,-no_warn_duplicate_libraries")
endif()
endif()

View file

@ -49,13 +49,13 @@ set(CMAKE_CXX_FLAGS_MSAN
CACHE STRING "Flags used by the C++ compiler during MemorySanitizer builds."
FORCE)
# UndefinedBehaviorSanitizer
# UndefinedBehaviorSanitizer is a run-time undefined behavior detector.
# Undefinedbehavior
# LeakSanitizer is a run-time undefined behavior detector.
set(CMAKE_C_FLAGS_UBSAN
"-fsanitize=undefined -fno-omit-frame-pointer -g -O2 -DNDEBUG"
"-fsanitize=undefined"
CACHE STRING "Flags used by the C compiler during UndefinedBehaviorSanitizer builds."
FORCE)
set(CMAKE_CXX_FLAGS_UBSAN
"-fsanitize=undefined -fno-omit-frame-pointer -g -O2 -DNDEBUG"
"-fsanitize=undefined"
CACHE STRING "Flags used by the C++ compiler during UndefinedBehaviorSanitizer builds."
FORCE)

View file

@ -1,14 +1,5 @@
# Set a default build type if none was specified
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
set(CMAKE_CONFIGURATION_TYPES
"RelWithDebInfo;Debug;Release;MinSizeRel"
CACHE STRING "Available build configurations" FORCE)
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
set(CMAKE_DEFAULT_BUILD_TYPE "RelWithDebInfo")
endif()
elseif(NOT CMAKE_BUILD_TYPE)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE
"RelWithDebInfo"
@ -17,16 +8,15 @@ elseif(NOT CMAKE_BUILD_TYPE)
set_property(
CACHE CMAKE_BUILD_TYPE
PROPERTY STRINGS
"RelWithDebInfo"
"Debug"
"Release"
"MinSizeRel"
)
"Debug"
"Release"
"MinSizeRel"
"RelWithDebInfo")
endif()
option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
if(ENABLE_IPO AND NOT CMAKE_BUILD_TYPE STREQUAL Debug AND NOT CMAKE_BUILD_TYPE STREQUAL ASAN AND NOT CMAKE_BUILD_TYPE STREQUAL UBSAN AND NOT CMAKE_BUILD_TYPE STREQUAL TSAN AND NOT CMAKE_BUILD_TYPE STREQUAL MSAN AND NOT CMAKE_BUILD_TYPE STREQUAL LSAN)
if(ENABLE_IPO AND NOT CMAKE_BUILD_TYPE STREQUAL Debug)
include(CheckIPOSupported)
check_ipo_supported(
RESULT
@ -41,16 +31,30 @@ if(ENABLE_IPO AND NOT CMAKE_BUILD_TYPE STREQUAL Debug AND NOT CMAKE_BUILD_TYPE S
endif()
message(STATUS "CMAKE_INTERPROCEDURAL_OPTIMIZATION: ${CMAKE_INTERPROCEDURAL_OPTIMIZATION} (this implies /GL or -flto)")
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
add_compile_options(-fno-fast-math)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/fp:precise)
# Snippet from GLM: https://github.com/g-truc/glm (MIT)
# NOTE: fast-math was on by default before the CMake build refactoring!
option(ENABLE_FAST_MATH "Enable fast math optimizations" ON)
if(ENABLE_FAST_MATH)
message(STATUS "ENABLE_FAST_MATH: ON")
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
add_compile_options(-ffast-math)
add_compile_options(-fno-finite-math-only) # only GCC needs this, /fp:fast on VC++ doesnt force finite math only
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/fp:fast)
endif()
else()
message(STATUS "ENABLE_FAST_MATH: OFF")
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/fp:precise)
endif()
endif()
if(MSVC)
list(APPEND FLAGS_AND_DEFINES
-D_CONSOLE
-D_MBCS
-DNOMINMAX
-D_CRT_SECURE_NO_WARNINGS
-D_CRT_NONSTDC_NO_DEPRECATE
# TODO: This is being overwritten by /Ob0
# /Ob2 # Inline Function Expansion
@ -76,7 +80,7 @@ if(MSVC)
)
endif()
link_libraries(ws2_32 dbghelp shlwapi winmm shell32 user32)
link_libraries(WS2_32 dbghelp Shlwapi)
endif()
if(UNIX)
@ -95,48 +99,28 @@ string(REPLACE ";" " " FLAGS_AND_DEFINES_STR "${FLAGS_AND_DEFINES}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS_AND_DEFINES_STR}")
function(set_target_output_directory target)
# Run from the repo root: data, scripts, settings and the runtime DLLs all live there.
# DEBUGGER_WORKING_DIRECTORY (CMake 4.0+): Ninja and other non-VS generators.
# VS_DEBUGGER_WORKING_DIRECTORY: Visual Studio generator (takes precedence there).
message(STATUS "Setting output directory for ${target} to ${CMAKE_SOURCE_DIR}")
set_target_properties(${target} PROPERTIES
DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
message(STATUS "${target}: staging build artifact to ${CMAKE_SOURCE_DIR} after build")
add_custom_command(TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$<TARGET_FILE:${target}>"
"${CMAKE_SOURCE_DIR}/$<TARGET_FILE_NAME:${target}>"
VERBATIM)
if(MSVC)
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "$<$<CONFIG:Debug,RelWithDebInfo>:${CMAKE_COMMAND};-E;copy_if_different;$<TARGET_PDB_FILE:${target}>;${CMAKE_SOURCE_DIR}/$<TARGET_PDB_FILE_NAME:${target}>>"
COMMAND_EXPAND_LISTS
VERBATIM)
endif()
if(APPLE)
# Under LTO the linker merges codegen objects into temp files and deletes after linking.
# We need to preserve those for the next step!
# -object_path_lto persists those codegen objects to a real, per-target directory so
# dsymutil can gather their DWARF into the .dSYM.
if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
set(lto_object_dir "${CMAKE_BINARY_DIR}/lto-objects/${target}")
file(MAKE_DIRECTORY "${lto_object_dir}")
target_link_options(${target} PRIVATE "-Wl,-object_path_lto,${lto_object_dir}")
endif()
# dsymutil consolidates the DWARF into a self-contained .dSYM that travels with the
# binary, and atos picks it up automatically.
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "$<$<CONFIG:Debug,RelWithDebInfo>:dsymutil;$<TARGET_FILE:${target}>;-o;${CMAKE_SOURCE_DIR}/$<TARGET_FILE_NAME:${target}>.dSYM>"
COMMAND_EXPAND_LISTS
VERBATIM)
endif()
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_SOURCE_DIR}"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_SOURCE_DIR}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_SOURCE_DIR}"
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_SOURCE_DIR}"
)
endfunction()
function(disable_lto target)
target_compile_options(${target} PRIVATE -fno-lto)
target_link_options(${target} PRIVATE -fno-lto)
endfunction()
# If we're on Unix and the system is 32-bit (void* is 4-bytes wide),
# then there's a good chance we're compiling for Raspberry Pi.
# Currently, CMake doesn't detect this properly and needs some help
# to link libatomic.
# Source: https://gitlab.kitware.com/cmake/cmake/-/issues/21174
#
# TODO: Use include(CheckCXXSourceCompiles) to make this check better.
if(UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -latomic")
endif()

View file

@ -1,16 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.allegiance
values:
mob: 0
player: 1
san_doria: 2
bastok: 3
windurst: 4
wyverns: 5
griffons: 6

View file

@ -1,53 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.animation
values:
none: 0
attack: 1
despawn: 2
death: 3
event: 4
chocobo: 5
fishing: 6
open_door: 8
close_door: 9
elevator_up: 10
elevator_down: 11
fishing_npc: 32
healing: 33
fishing_fish: 38
fishing_caught: 39
fishing_rod_break: 40
fishing_line_break: 41
fishing_monster: 42
fishing_stop: 43
synth: 44
sit: 47
ranged: 48
fishing_start: 50
new_fishing_start: 56
new_fishing_fish: 57
new_fishing_caught: 58
new_fishing_rod_break: 59
new_fishing_line_break: 60
new_fishing_monster: 61
new_fishing_stop: 62
# 63 through 73 are used with /sitchair
sitchair_0: 63
sitchair_1: 64
sitchair_2: 65
sitchair_3: 66
sitchair_4: 67
sitchair_5: 68
sitchair_6: 69
sitchair_7: 70
sitchair_8: 71
sitchair_9: 72
sitchair_10: 73
mount: 85
trust: 90 # trust NPC spawn-in animation

View file

@ -1,15 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.attackType
values:
none: 0
physical: 1
magical: 2
ranged: 3
breath: 4
special: 5

View file

@ -1,17 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint16_t
lua:
table: xi.behavior
values:
none: 0x000
no_despawn: 0x001 # mob does not despawn on death
standback: 0x002 # mob will standback forever
raisable: 0x004 # mob can be raised via Raise spells
no_assist: 0x008 # mob can not be targeted by helpful magic from players (cure, protect, etc)
aggro_ambush: 0x200 # mob aggroes by ambush
no_turn: 0x400 # mob does not turn to face target

View file

@ -1,12 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.claimType
values:
exclusive: 0 # Regular exclusive claim behavior. Only one entity and related group can attack.
non_exclusive: 1 # Regular claim behavior but multiple unrelated entities can attack and compete for claim. Rewards distributed to last claiming entity.
unclaimable: 2 # Mob cannot be claimed. Multiple unrelated entities can attack. Rewards will not be distributed.

View file

@ -1,23 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint16_t
lua:
table: xi.damageType
values:
none: 0
piercing: 1
slashing: 2
blunt: 3
hand_to_hand: 4
elemental: 5
fire: 6
ice: 7
wind: 8
earth: 9
thunder: 10
water: 11
light: 12
dark: 13

View file

@ -1,21 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint16_t
lua:
table: xi.detects
values:
none: 0x000
sight: 0x001
hearing: 0x002
sight_and_hearing: 0x003
lowhp: 0x004
none1: 0x008
none2: 0x010
magic: 0x020
weaponskill: 0x040
jobability: 0x080
scent: 0x100

View file

@ -1,32 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.ecosystem
values:
unclassified: 0
amorph: 1
aquan: 2
arcana: 3
archaic_machine: 4
beast: 5
beastmen: 6
bird: 7
demon: 8
dragon: 9
elemental: 10
empty: 11
humanoid: 12
lizard: 13
luminian: 14
luminion: 15
plantoid: 16
supreme_beings: 17
undead: 18
vermin: 19
voragean: 20
structures: 21
weapons: 22

View file

@ -1,15 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.effectOverwrite
values:
equal_higher: 0 # only overwrite if equal or higher (tier, power)
higher: 1 # only overwrite if higher (tier, power)
never: 2 # never overwrite
always: 3 # always overwrite no matter
ignore_duplicate: 4 # ignore dupes
tier_higher: 5 # only overwrite if tier is higher (regardless of power)

View file

@ -1,18 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.element
values:
none: 0
fire: 1
ice: 2
wind: 3
earth: 4
thunder: 5
water: 6
light: 7
dark: 8

View file

@ -1,21 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint32_t
lua:
table: xi.entityFlags
values:
none: 0x000
info_icon: 0x001 # (I) Icon next to name
# TODO: Flags 0x002, 0x004 and 0x008 do different things for different entities.
# : It isn't one-size-fits-all, and different combinations may do different things.
# : It'll need to be researched more.
# alt_appearance: 0x002
hide_name: 0x008
call_for_help: 0x020
hide_model: 0x080
hide_hp: 0x100
untargetable: 0x800

View file

@ -1,29 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint32_t
lua:
table: xi.immunity
values:
none: 0x00000000
addle: 0x00000001
gravity: 0x00000002
bind: 0x00000004
stun: 0x00000008
silence: 0x00000010
paralyze: 0x00000020
blind: 0x00000040
slow: 0x00000080
poison: 0x00000100
elegy: 0x00000200
requiem: 0x00000400
light_sleep: 0x00000800
dark_sleep: 0x00001000
aspir: 0x00002000
terror: 0x00004000
dispel: 0x00008000
petrify: 0x00010000
plague: 0x00020000

View file

@ -1,34 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
case: screaming
lua:
table: xi.job
values:
none: 0
war: 1
mnk: 2
whm: 3
blm: 4
rdm: 5
thf: 6
pld: 7
drk: 8
bst: 9
brd: 10
rng: 11
sam: 12
nin: 13
drg: 14
smn: 15
blu: 16
cor: 17
pup: 18
dnc: 19
sch: 20
geo: 21
run: 22
mon: 23 # NOTE: MON is not a full job

View file

@ -1,75 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint16_t
lua:
table: xi.latent
values:
hp_under_percent: 0 # hp less than or equal to % - PARAM: HP PERCENT
hp_over_percent: 1 # hp more than % - PARAM: HP PERCENT
hp_under_tp_under_100: 2 # hp less than or equal to %, tp under 100 - PARAM: HP PERCENT
hp_over_tp_under_100: 3 # hp more than %, tp over 100 - PARAM: HP PERCENT
mp_under_percent: 4 # mp less than or equal to % - PARAM: MP PERCENT
mp_under: 5 # mp less than # - PARAM: MP #
tp_under: 6 # tp under # and during WS - PARAM: TP VALUE
tp_over: 7 # tp over # - PARAM: TP VALUE
subjob: 8 # subjob - PARAM: JOBTYPE
pet_id: 9 # pettype - PARAM: PETID
weapon_drawn: 10 # weapon drawn
weapon_sheathed: 11 # weapon sheathed
signet_bonus: 12 # While in conquest region and engaged to an even match or less target
status_effect_active: 13 # status effect on player - PARAM: EFFECTID
no_food_active: 14 # no food effects active on player
party_members: 15 # party size # - PARAM: # OF MEMBERS
party_members_in_zone: 16 # party size # and members in zone - PARAM: # OF MEMBERS
sanction_regen_bonus: 17 # While in besieged region and HP is less than PARAM%
sanction_refresh_bonus: 18 # While in besieged region and MP is less than PARAM%
sigil_regen_bonus: 19 # While in campaign region and HP is less than PARAM%
sigil_refresh_bonus: 20 # While in campaign region and MP is less than PARAM%
avatar_in_party: 21 # party has a specific avatar - PARAM: same as globals/pets.lua (21 for any avatar)
job_in_party: 22 # party has job - PARAM: JOBTYPE
zone: 23 # in zone - PARAM: zoneid
synth_trainee: 24 # synth skill under 40 + no support: PARAM: 48: FISH, 49: WOOD, 50: SMITH, 51: GOLDSMITH, 52: CLOTH, 53: LEATHER, 54: BONE, 55: ALCHEMY, 56: COOKING
song_roll_active: 25 # any song or roll active
time_of_day: 26 # PARAM: 0: DAYTIME 1: NIGHTTIME 2: DUSK-DAWN
hour_of_day: 27 # PARAM: 1: NEW DAY, 2: DAWN, 3: DAY, 4: DUSK, 5: EVENING, 6: DEAD OF NIGHT
firesday: 28
earthsday: 29
watersday: 30
windsday: 31
darksday: 32
iceday: 34
lightningsday: 35
lightsday: 36
moon_phase: 37 # PARAM: 0: New Moon, 1: Waxing Crescent, 2: First Quarter, 3: Waxing Gibbous, 4: Full Moon, 5: Waning Gibbous, 6: Last Quarter, 7: Waning Crescent
job_multiple: 38 # PARAM: 0: ODD, 2: EVEN, 3-X: DIVISOR
job_multiple_at_night: 39 # PARAM: 0: ODD, 2: EVEN, 3-X: DIVISOR
equipped_in_slot: 40 # When item is equipped in the specified slot (e.g. Dweomer Knife, Erlking's Sword, etc.) PARAM: slotID
during_ws: 41 # During WS
weather_condition: 42 # See Weather.h for WEATHER enum
weapon_drawn_hp_under: 43 # PARAM: HP PERCENT
nation_citizen: 44 # Triggered by player being citizen of nation matching param: 0 San d'Oria, 1 Bastok, 2 Windurst
mp_under_visible_gear: 45 # mp less than or equal to %, calculated using MP bonuses from visible gear only
hp_over_visible_gear: 46 # hp more than or equal to %, calculated using HP bonuses from visible gear only
weapon_broken: 47
in_dynamis: 48
food_active: 49 # food effect (foodId) active - PARAM: FOOD ITEMID
job_level_below: 50 # PARAM: level
job_level_above: 51 # PARAM: level
weather_element: 52 # PARAM: 0: NONE, 1: FIRE, 2: ICE, 3: WIND 4: EARTH, 5: THUNDER, 6: WATER, 7: LIGHT, 8: DARK
nation_control: 53 # checks if player region is under nation's control - PARAM: 0: Under own nation's control, 1: Outside own nation's control
zone_home_nation: 54 # in zone and citizen of nation (aketons)
mp_over: 55 # mp greater than # - PARAM: MP #
weapon_drawn_mp_over: 56 # while weapon is drawn and mp greater than # - PARAM: MP #
eleven_roll_active: 57 # corsair roll of 11 active
in_assault: 58 # is in an Instance battle in a TOAU zone
vs_ecosystem: 59 # Vs. Specific Ecosystem ID (e.g. Vs. Plantoid: Accuracy+3)
vs_species: 60 # Vs. Specific Species ID (e.g. Vs. Korrigan: Accuracy+3)
vs_family: 61 # Vs. Specific Family ID (e.g. Vs. Mandragora: Accuracy+3)
mainjob: 62 # mainjob - PARAM: JOBTYPE
in_adoulin: 63
in_garrison: 64 # while in an active Garrison
sanction_food_bonus: 65 # While in besieged region
sigil_food_bonus: 66 # While in campaign region

View file

@ -1,107 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint16_t
lua:
table: xi.mobMod
values:
none: 0
gil_min: 1 # minimum gil drop -- spawn mod only
gil_max: 2 # maximum gil drop -- spawn mod only
mp_base: 3 # Give mob mp. Used for mobs that are not mages, wyverns, avatars
sight_range: 4 # sight range
sound_range: 5 # sound range
buff_chance: 6 # % chance to buff (combat only)
ga_chance: 7 # % chance to use -ga spell
heal_chance: 8 # % chance to use heal
hp_heal_chance: 9 # can cast cures below this HP %
sublink: 10 # Sub link group. Enables mobs from different families to link if they share a SUBLINK value.
link_radius: 11 # link radius
sees_through_illusion: 12 # Mob can see through the Illusion effect that grants effects similar to Sneak & Invisible without this mod and allows aggro (see Viscious Liquid in mamook)
severe_spell_chance: 13 # % chance to use a severe spell like death or impact
skill_list: 14 # uses given mob skill list
mug_gil: 15 # amount gil carried for mugging
detection: 16 # Overrides mob family's detection method. In order to set to override to none an unused bit must be set such as xi::Detects::None1.
no_despawn: 17 # do not despawn when too far from spawn. Gob Diggers have this.
var: 18 # temp var for whatever. Gets cleared on spawn
can_shield_block: 19 # toggle shield use for mobs without physical shields (trusts)
no_h2h_penalty: 20 # Disables H2H penalty in base damage calculation when set to non-zero
pet_spell_list: 21 # set pet spell list
na_chance: 22 # % chance to cast -na
immunity: 23 # immune to set status effects. This only works from the db, not scripts
gradual_rage: 24 # (!) TODO: NOT YET IMPLEMENTED -- gradually rages
build_resist: 25 # (!) TODO: NOT YET IMPLEMENTED -- builds resistance to given effects
superlink: 26 # super link group. Only use this in scripts! Must be defined in onMobInitialize if relevant mobs are different families
spell_list: 27 # set spell list
exp_bonus: 28 # bonus exp (bonus / 100) negative values reduce exp.
assist: 29 # mobs will assist me
special_skill: 30 # give special skill
roam_distance: 31 # distance allowed to roam from spawn
dont_roam_home: 32 # Allow mobs to roam any distance from spawn. Useful for mobs with scripted roaming behavior.
special_cool: 33 # cool down for special
magic_cool: 34 # cool down for magic
standback_cool: 35 # cool down time for standing back (casting spell while not in attack range)
roam_cool: 36 # cool down time in seconds after roaming
always_aggro: 37 # aggro regardless of level. Spheroids
no_drops: 38 # If set monster cannot drop any items, not even seals.
share_pos: 39 # share a pos with another mob (eald'narche exoplates)
teleport_cd: 40 # cooldown for teleport abilities (tarutaru AA, angra mainyu, eald'narche)
teleport_start: 41 # mobskill ID to begin teleport
teleport_end: 42 # mobskill ID to end teleport
teleport_type: 43 # teleport type - 1: on cooldown, 2 - to close distance
dual_wield: 44 # enables a mob to use their offhand in attacks
add_effect: 45 # enables additional effect script to process on mobs attacks
auto_spikes: 46 # enables additional effect script to process when mob is attacked
spawn_leash: 47 # forces a mob to not move farther from its spawn than its leash distance
share_target: 48 # mob always targets same target as ID in this var
check_as_nm: 49 # If set , mob will check as a NM
roam_reset_facing: 50 # Resume facing the default spawn rotation after roaming home.
roam_turns: 51 # Maximum amount of turns during a roam
roam_rate: 52 # Roaming frequency. roam_cool - rand(roam_cool / (roam_rate / 10))
behavior: 53 # Add behaviors to mob
gil_bonus: 54 # Allow mob to drop gil. Multiplier to gil dropped by mob (bonus / 100) * total
idle_despawn: 55 # Time (in seconds) to despawn after being idle
hp_standback: 56 # mob will always standback with hp % higher to value
magic_delay: 57 # Amount of seconds mob waits before casting first spell
special_delay: 58 # Amount of seconds mob waits before using first special
base_damage_modifier: 59 # Add a flat modifer mob a mob's base damage. This is subject to multiplication by MOBMOD_BASE_DAMAGE_MULTIPLIER.
spawn_animationsub: 60 # reset animationsub to this on spawn
hp_scale: 61 # Scale the mobs max HP. ( hp_scale / 100 ) * maxhp
no_standback: 62 # Mob will never standback
attack_skill_list: 63 # skill list to use in place of regular attacks
charmable: 64 # mob is charmable
no_move: 65 # Mob will not be able to move
multi_hit: 66 # Mob will have as many swings as defined.
no_aggro: 67 # If set, mob cannot aggro until unset.
alli_hate: 68 # Range around target to add alliance member to enmity list.
no_link: 69 # If set, mob cannot link until unset.
no_rest: 70 # Mob cannot regain hp (e.g. re-burrowing antlions during ENM).
leader: 71 # Used for mob following. Positive number is how many followers a leader has. A negative number is the distance from this mob ID to the leader ID.
magic_range: 72 # magic aggro range
target_distance_offset: 73 # Adjusts how close a mob will move to it's target. 12 = 1.2 yalm. Positive values to go closer, negative farther.
one_way_linking: 74 # Will link with other mobs in its party (typically the same mob family) while roaming, but will not let others link with it once engaged
can_parry: 75 # Check if a mob is allowed to have parry rank (Rank Value 1-5)
no_widescan: 76 # Disables widescan for a specific mob
trust_distance: 77 # TRUSTS ONLY: Set movement type/distance. See trust.lua for details.
standback_range: 78 # Applies a specific standback range for the mob
cannot_guard: 79 # Check if the mob does not guard(despite being a MNK or PUP mob)
skip_allegiance_check: 80 # Skip the allegiance check for valid target (allows for example a mob to cast a TARGET_ENEMY spell on itself)
ability_response: 81 # Mob can respond to player ability use with onPlayerAbilityUse()
run_speed_mult: 82 # Multiplier for the speed of a mob while running (generally when the target is out of range) 100 = 1.00x
claim_type: 83 # Changes the claim behavior of the mob. See xi::ClaimType enum.
no_spell_cost: 84 # Mob does not use MP when casting spells
astral_pet_offset: 85 # If non-zero, defines the offset from main mob's ID for astral flow (if zero, will assume offset of 2)
base_damage_multiplier: 86 # Multiplies the mob's base damage. Example: 150 = x1.5. MOBMOD_DAMAGE_OFFSET/MOBMOD_RANGED_DAMAGE_OFFSET are not subject to multiplication.
damage_offset: 87 # Adds or subtracts the mob's base damage offset.
ranged_damage_offset: 88 # Adds or subtracts the mob's ranged base damage offset.
avatar_petid: 89 # A value from xi.petId to select model/ability from when owner uses astral flow
avatar_astral_delay: 90 # Number of milliseconds to delay AF after avatar spawn
h2h_single_swing: 91 # Mob will have only one swing per attack even as MNK with H2H skill
aoe_hit_all: 92 # Mob AoE can hit any player regardless of enmity
ranged_attack_range: 93 # Max range for ranged auto attacks. Mob will move closer if target is beyond this range.
follow_leash_range: 94 # Distance the leader can walk before their followers start moving. Applied to followers.
follow_stop_range: 95 # Distance the followers attempt to stop at once their leader stops moving. Applied to followers.
trust_shield_size: 96 # TRUSTS ONLY: Set the size of the mob's shield. 3 = Default size, only used for trusts that use shields.
bodyguard: 97 # Charmed mob defends its master similar to an avatar. (Maiden's Virelai)

View file

@ -1,17 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint8_t
lua:
table: xi.mobType
values:
normal: 0x00
unused: 0x01 # available for use
notorious: 0x02
fished: 0x04
called: 0x08
battlefield: 0x10
event: 0x20

File diff suppressed because it is too large Load diff

View file

@ -1,14 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint8_t
lua:
table: xi.nameVis
values:
none: 0x00
icon: 0x01 # (I) Icon next to name
hide_name: 0x08
ghost_phase: 0x80

View file

@ -1,23 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint16_t
lua:
table: xi.roamFlag
values:
none: 0x000
none0: 0x001
none1: 0x002
none2: 0x004
none3: 0x008
none4: 0x010
none5: 0x020
worm: 0x040 # pop up and down when moving
ambush: 0x080 # stays hidden until someone comes close (antlion)
scripted: 0x100 # calls lua method for roaming logic
ignore: 0x200 # ignore all hate, except linking hate
stealth: 0x400 # stays name hidden and untargetable until someone comes close (chigoe)
follow: 0x800 # follows a player when sighted for a little while

View file

@ -1,65 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.skill
values:
# Combat Skills
none: 0
hand_to_hand: 1
dagger: 2
sword: 3
great_sword: 4
axe: 5
great_axe: 6
scythe: 7
polearm: 8
katana: 9
great_katana: 10
club: 11
staff: 12
# 13-21 unused
automaton_melee: 22
automaton_ranged: 23
automaton_magic: 24
archery: 25
marksmanship: 26
throwing: 27
# Defensive Skills
guard: 28
evasion: 29
shield: 30
parry: 31
# Magic Skills
divine_magic: 32
healing_magic: 33
enhancing_magic: 34
enfeebling_magic: 35
elemental_magic: 36
dark_magic: 37
summoning_magic: 38
ninjutsu: 39
singing: 40
string_instrument: 41
wind_instrument: 42
blue_magic: 43
geomancy: 44
handbell: 45
# 46-47 unused
# Crafting Skills
fishing: 48
woodworking: 49
smithing: 50
goldsmithing: 51
clothcraft: 52
leathercraft: 53
bonecraft: 54
alchemy: 55
cooking: 56
synergy: 57
# Other Skills
rid: 58
dig: 59

View file

@ -1,11 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.spawnAnimation
values:
normal: 0
special: 1

View file

@ -1,19 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint8_t
lua:
table: xi.spawnType
values:
normal: 0x00 # 00:00-24:00
at_night: 0x01 # 20:00-04:00
at_evening: 0x02 # 18:00-06:00
weather: 0x04
fog: 0x08 # 02:00-07:00
moonphase: 0x10
lottery: 0x20
windowed: 0x40
scripted: 0x80 # scripted spawn

View file

@ -1,17 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint8_t
lua:
table: xi.status
values:
normal: 0
update: 1
disappear: 2
invisible: 3
status_4: 4
cutscene_only: 6
status_18: 18
shutdown: 20

View file

@ -1,42 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint32_t
lua:
table: xi.effectFlag
values:
none: 0x00000000
dispelable: 0x00000001
erasable: 0x00000002
attack: 0x00000004
empathy: 0x00000008
damage: 0x00000010
death: 0x00000020
magic_begin: 0x00000040
magic_end: 0x00000080
on_zone: 0x00000100
no_loss_message: 0x00000200
invisible: 0x00000400
detectable: 0x00000800
no_rest: 0x00001000
prevent_action: 0x00002000
waltzable: 0x00004000
food: 0x00008000
song: 0x00010000
roll: 0x00020000
synth_support: 0x00040000
confrontation: 0x00080000
logout: 0x00100000
bloodpact: 0x00200000
on_jobchange: 0x00400000
no_cancel: 0x00800000
influence: 0x01000000
offline_tick: 0x02000000
aura: 0x04000000
hide_timer: 0x08000000
on_zone_pathos: 0x10000000
always_expiring: 0x20000000
on_attack: 0x40000000

View file

@ -1,29 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
cpp:
underlying: uint16_t
lua:
table: xi.weather
values:
none: 0
sunshine: 1
clouds: 2
fog: 3
hot_spell: 4
heat_wave: 5
rain: 6
squall: 7
dust_storm: 8
sand_storm: 9
wind: 10
gales: 11
snow: 12
blizzards: 13
thunder: 14
thunderstorms: 15
auroras: 16
stellar_glare: 17
gloom: 18
darkness: 19

View file

@ -1,26 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint16_t
lua:
table: xi.zoneMisc
values:
none: 0x0000 # Able to be used in any area
escape: 0x0001 # Ability to use Escape Spell
fellow: 0x0002 # Ability to summon Fellow NPC
mount: 0x0004 # Ability to use Chocobos and mounts
mazurka: 0x0008 # Ability to use Mazurka Spell
tractor: 0x0010 # Ability to use Tractor Spell
mogmenu: 0x0020 # Ability to communicate with Nomad Moogle (menu access mog house)
costume: 0x0040 # Ability to use a Costumes
pet: 0x0080 # Ability to summon Pets
treasure: 0x0100 # Presence in the global zone TreasurePool
auction_house: 0x0200 # Ability to use the auction house
yell: 0x0400 # Send and receive /yell commands
trust: 0x0800 # Ability to summon Trust NPC
los_player_block: 0x1000 # Players can't use magic/JAs through walls if this is set
los_off: 0x2000 # Zone should not have LoS checks
assist: 0x4000 # Send and receive /assiste, /assistj commands

View file

@ -1,20 +0,0 @@
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
meta:
flags: true
cpp:
underlying: uint16_t
lua:
table: xi.zoneType
values:
unknown: 0x0000
city: 0x0001
outdoors: 0x0002
dungeon: 0x0004
signet: 0x0008
sanction: 0x0010
sigil: 0x0020
ionis: 0x0040
dynamis: 0x0080
instanced: 0x0100

View file

@ -1,43 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "_meta.schema.json",
"title": "Data-file codegen metadata",
"description": "Optional top-level `meta:` block in data yamls. Carries directives that drive codegen.",
"type": "object",
"unevaluatedProperties": false,
"properties": {
"enum": {
"type": "object",
"unevaluatedProperties": false,
"required": ["cpp"],
"description": "Emit a typed enum derived from a top-level section of the data file.",
"properties": {
"cpp": {
"type": "object",
"unevaluatedProperties": false,
"required": ["underlying", "class"],
"properties": {
"underlying": { "type": "string" },
"class": { "type": "string", "pattern": "^[A-Z][A-Za-z0-9]*$" },
"case": { "type": "string", "enum": ["pascal", "screaming"], "default": "pascal" }
}
},
"lua": {
"type": "object",
"unevaluatedProperties": false,
"properties": {
"table": { "type": "string", "pattern": "^xi\\.[A-Za-z][A-Za-z0-9_]*$" }
}
},
"section": {
"type": "string",
"description": "Which top-level YAML section to walk. Defaults to the filename."
},
"name_from": {
"type": "string",
"description": "Dot-path inside each entry to a string that gets slugged into the enum value name (e.g., `name.en`). When set, the YAML key is treated as the integer id."
}
}
}
}
}

View file

@ -1,65 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "_enum.schema.json",
"title": "Enum source",
"description": "Meta-schema for data/enums/*.yaml. Each file declares a typed enum: a `meta` block describing the C++/Lua surface, and a `values` map of name -> integer.",
"type": "object",
"unevaluatedProperties": false,
"required": ["meta", "values"],
"properties": {
"meta": {
"type": "object",
"unevaluatedProperties": false,
"required": ["cpp"],
"properties": {
"flags": {
"description": "True if values are bitmask flags.",
"type": "boolean",
"default": false
},
"cpp": {
"type": "object",
"unevaluatedProperties": false,
"required": ["underlying"],
"properties": {
"underlying": {
"description": "C++ underlying integer type for the enum class.",
"type": "string",
"enum": ["int8_t", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t", "int64_t", "uint64_t"]
},
"class": {
"description": "Generated C++ enum class name (PascalCase).",
"type": "string",
"pattern": "^[A-Z][A-Za-z0-9]*$"
},
"case": {
"description": "Case style for generated enum value names. `pascal` (default): `War`, `MysteryBox`. `screaming`: `WAR`, `MYSTERY_BOX`.",
"type": "string",
"enum": ["pascal", "screaming"],
"default": "pascal"
}
}
},
"lua": {
"type": "object",
"unevaluatedProperties": false,
"properties": {
"table": {
"description": "Lua table path the values are exported under. Example: `xi.itemFlag`.",
"type": "string",
"pattern": "^xi\\.[A-Za-z][A-Za-z0-9_]*$"
}
}
}
}
},
"values": {
"description": "Map of value name -> integer. Names must be snake_case and unique. Integers may be decimal or hex (0xNN).",
"type": "object",
"minProperties": 1,
"propertyNames": { "pattern": "^[a-z][a-z0-9_]*$" },
"additionalProperties": { "type": "integer" }
}
}
}

View file

@ -1,52 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "status_effects.schema.json",
"title": "StatusEffects",
"description": "Schema for data/status_effects.yaml.",
"type": "object",
"unevaluatedProperties": false,
"required": ["status_effects"],
"properties": {
"meta": { "$ref": "_meta.schema.json" },
"status_effects": {
"type": "object",
"description": "Status effects.",
"propertyNames": { "pattern": "^[a-z][a-z0-9_]*$" },
"additionalProperties": { "$ref": "#/$defs/status_effect" }
}
},
"$defs": {
"status_effect": {
"type": "object",
"unevaluatedProperties": false,
"required": ["id"],
"properties": {
"id": { "type": "integer", "minimum": 0, "maximum": 65535 },
"name": {
"type": "string",
"description": "Override for the Lua script lookup name. Defaults to the YAML key."
},
"flags": {
"type": "array",
"items": { "$ref": "enums/status_effect_flag.codegen.json" },
"uniqueItems": true,
"default": []
},
"exclusion_group": {
"$ref": "enums/status_effect.codegen.json",
"description": "Applying this effect removes all other effects sharing the same group (the group's representative effect). e.g. all spikes share blaze_spikes."
},
"negative": { "$ref": "enums/status_effect.codegen.json" },
"overwrite": { "$ref": "enums/effect_overwrite.codegen.json" },
"block": { "$ref": "enums/status_effect.codegen.json" },
"remove": { "$ref": "enums/status_effect.codegen.json" },
"element": { "$ref": "enums/element.codegen.json" },
"min_duration": { "type": "integer", "minimum": 0, "maximum": 65535 },
"sort_key": { "type": "integer", "minimum": 0, "maximum": 65535 },
"wear_off_message_id": { "type": "integer", "minimum": 0, "maximum": 65535 }
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -102,6 +102,7 @@ services:
XI_NETWORK_SQL_HOST: database
XI_NETWORK_SQL_PORT: 3306
volumes:
- losmeshes:/server/losmeshes
- navmeshes:/server/navmeshes
- ${LOCAL_WORKSPACE_FOLDER:-./}/log:/server/log
depends_on:
@ -116,6 +117,7 @@ services:
XI_NETWORK_SQL_HOST: database
XI_NETWORK_SQL_PORT: 3306
volumes:
- losmeshes:/server/losmeshes
- navmeshes:/server/navmeshes
- ${LOCAL_WORKSPACE_FOLDER:-./}/log:/server/log
depends_on:
@ -190,6 +192,7 @@ services:
ports:
- "54230:54230/udp"
volumes:
- losmeshes:/server/losmeshes
- navmeshes:/server/navmeshes
- ${LOCAL_WORKSPACE_FOLDER:-./}/log:/server/log
depends_on:
@ -204,5 +207,7 @@ services:
condition: service_started
volumes:
losmeshes:
external: true
navmeshes:
external: true

View file

@ -2,10 +2,10 @@
## Meshes
`navmeshes` are included in a separate image. You can load these into a volume with the following command:
`losmeshes` and `navmeshes` are included in a separate image. You can load these into a volume with the following command:
```sh
docker run --rm -v navmeshes:/navmeshes ghcr.io/landsandboat/ximeshes:latest
docker run --rm -v losmeshes:/losmeshes -v navmeshes:/navmeshes ghcr.io/landsandboat/ximeshes:latest
```
Once the volumes are created, you can delete the image.
@ -47,6 +47,7 @@ docker run --name some-lsb-server \
-p 54002:54002 \
-p 54230:54230 \
-p 54231:54231 \
-v losmeshes:/server/losmeshes \
-v navmeshes:/server/navmeshes \
-it ghcr.io/landsandboat/server:latest
```
@ -113,6 +114,7 @@ x-common: &common
XI_NETWORK_SQL_HOST: database
# XI_{file}_{setting}: value
volumes:
- losmeshes:/server/losmeshes
- navmeshes:/server/navmeshes
# - ./config.yaml:/server/tools/config.yaml
# - ./map.lua:/server/settings/map.lua
@ -199,6 +201,8 @@ services:
volumes:
database:
losmeshes:
external: true
navmeshes:
external: true
```

View file

@ -3,7 +3,7 @@
########
# Base #
########
ARG BASE_TAG=3.24
ARG BASE_TAG=3.22
FROM --platform=$BUILDPLATFORM alpine:$BASE_TAG AS base
# Install runtime dependencies.
@ -12,7 +12,6 @@ apk --update-cache add \
bash \
binutils \
git \
libdwarf \
lua5.1-dev \
luajit \
mariadb-client \
@ -57,7 +56,7 @@ SHELL ["/bin/bash", "-c"]
###########
FROM base AS staging
ARG LLVM_VERSION=22
ARG LLVM_VERSION=20
# Install build dependencies.
RUN --mount=type=cache,target=/var/cache/apk,id=cache-apk,sharing=locked <<EOF
@ -66,18 +65,15 @@ apk --update-cache add \
ccache \
cmake \
g++ \
libdwarf-dev \
linux-headers \
luajit-dev \
make \
mariadb-dev \
ninja-build \
ninja-is-really-ninja \
openssl-dev \
python3-dev \
samurai \
zeromq-dev \
zlib-dev \
zstd-dev
zlib-dev
EOF
# Install secondary dependencies as user.
@ -140,8 +136,9 @@ USER $UNAME
# https://docs.docker.com/reference/dockerfile/#copy---exclude (docker/dockerfile:1.7-labs)
COPY --chown=$UNAME:$UGROUP \
--exclude=.git \
--exclude=losmeshes/** \
--exclude=navmeshes/** \
--exclude=ximeshes/** \
--exclude=scripts \
--exclude=sql \
. /server
@ -154,6 +151,7 @@ ENV CCACHE_DIR=/xiadmin/.ccache
RUN --mount=type=cache,target=/xiadmin/build,uid=$UID,gid=$GID,id=build-alpine-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
--mount=type=cache,target=/xiadmin/.ccache,uid=$UID,gid=$GID,id=ccache-alpine-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
--mount=type=bind,source=.git,target=/server/.git \
--mount=type=bind,source=scripts,target=/server/scripts \
--mount=type=bind,source=sql,target=/server/sql <<EOF
set -eo pipefail
cp -p /xiadmin/build/version.cpp /server/src/common/ 2> /dev/null || true
@ -189,14 +187,13 @@ USER $UNAME
COPY --chown=$UNAME:$UGROUP LICENSE /server/LICENSE
COPY --chown=$UNAME:$UGROUP res/compress.dat res/decompress.dat /server/res/
COPY --chown=$UNAME:$UGROUP scripts /server/scripts
COPY --chown=$UNAME:$UGROUP sql /server/sql
COPY --chown=$UNAME:$UGROUP tools /server/tools
COPY --chown=$UNAME:$UGROUP modules /server/modules
COPY --chown=$UNAME:$UGROUP settings /server/settings
COPY --chown=$UNAME:$UGROUP --from=staging $VIRTUAL_ENV $VIRTUAL_ENV
COPY --chown=$UNAME:$UGROUP --from=build /server/data /server/data
COPY --chown=$UNAME:$UGROUP --from=build /server/scripts /server/scripts
COPY --chown=$UNAME:$UGROUP --from=build /server/xi_* /server/
COPY --chown=$UNAME:$UGROUP --from=build /server/build.log /server/build.log

View file

@ -1,6 +1,6 @@
FROM --platform=$BUILDPLATFORM busybox:latest
COPY ./losmeshes/*.obj /losmeshes/
COPY ./navmeshes/*.nav /navmeshes/
COPY ./ximeshes/*.ximesh /ximeshes/
VOLUME /navmeshes /ximeshes
VOLUME /navmeshes /losmeshes

View file

@ -3,7 +3,7 @@
########
# Base #
########
ARG BASE_TAG=26.04
ARG BASE_TAG=24.04
FROM --platform=$BUILDPLATFORM ubuntu:$BASE_TAG AS base
ARG DEBIAN_FRONTEND=noninteractive
@ -19,7 +19,6 @@ apt-get update && apt-get install --assume-yes --no-install-recommends --quiet \
binutils \
ca-certificates \
git \
libdwarf1 \
libzmq5 \
lua5.1 \
luajit \
@ -64,8 +63,8 @@ SHELL ["/bin/bash", "-c"]
###########
FROM base AS staging
ARG GCC_VERSION=15
ARG LLVM_VERSION=22
ARG GCC_VERSION=14
ARG LLVM_VERSION=20
# Install build dependencies.
RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt,sharing=locked \
@ -75,18 +74,15 @@ apt-get update && apt-get install --assume-yes --no-install-recommends --quiet \
ccache \
cmake \
g++-$GCC_VERSION \
libdwarf-dev \
libluajit-5.1-dev \
libmariadb-dev-compat \
libssl-dev \
libzmq3-dev \
make \
ninja-build \
pkg-config \
python3-dev \
python3-venv \
zlib1g-dev \
libzstd-dev
zlib1g-dev
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$GCC_VERSION 100
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-$GCC_VERSION 100
EOF
@ -152,8 +148,9 @@ USER $UNAME
# https://docs.docker.com/reference/dockerfile/#copy---exclude (docker/dockerfile:1.7-labs)
COPY --chown=$UNAME:$UGROUP \
--exclude=.git \
--exclude=losmeshes/** \
--exclude=navmeshes/** \
--exclude=ximeshes/** \
--exclude=scripts \
--exclude=sql \
. /server
@ -166,6 +163,7 @@ ENV CCACHE_DIR=/xiadmin/.ccache
RUN --mount=type=cache,target=/xiadmin/build,uid=$UID,gid=$GID,id=build-ubuntu-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
--mount=type=cache,target=/xiadmin/.ccache,uid=$UID,gid=$GID,id=ccache-ubuntu-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
--mount=type=bind,source=.git,target=/server/.git \
--mount=type=bind,source=scripts,target=/server/scripts \
--mount=type=bind,source=sql,target=/server/sql <<EOF
set -eo pipefail
cp -p /xiadmin/build/version.cpp /server/src/common/ 2> /dev/null || true
@ -201,14 +199,13 @@ USER $UNAME
COPY --chown=$UNAME:$UGROUP LICENSE /server/LICENSE
COPY --chown=$UNAME:$UGROUP res/compress.dat res/decompress.dat /server/res/
COPY --chown=$UNAME:$UGROUP scripts /server/scripts
COPY --chown=$UNAME:$UGROUP sql /server/sql
COPY --chown=$UNAME:$UGROUP tools /server/tools
COPY --chown=$UNAME:$UGROUP modules /server/modules
COPY --chown=$UNAME:$UGROUP settings /server/settings
COPY --chown=$UNAME:$UGROUP --from=staging $VIRTUAL_ENV $VIRTUAL_ENV
COPY --chown=$UNAME:$UGROUP --from=build /server/data /server/data
COPY --chown=$UNAME:$UGROUP --from=build /server/scripts /server/scripts
COPY --chown=$UNAME:$UGROUP --from=build /server/xi_* /server/
COPY --chown=$UNAME:$UGROUP --from=build /server/build.log /server/build.log

View file

@ -43,18 +43,18 @@ ATTACKED - Defender, attacker, action
RANGE_START - Entity, action
RANGE_STATE_EXIT - Entity, Target, action
ABILITY_START - userEntity, skillObject
ABILITY_USE - userEntity, targetEntity, skillObject, action
ABILITY_TAKE - userEntity, targetEntity, skillObject, action
ABILITY_STATE_EXIT - userEntity, skillObject
ABILITY_START - Entity, Ability
ABILITY_USE - Entity, Target, Ability, action
ABILITY_TAKE - Target, Entity, Ability, action
ABILITY_STATE_EXIT - Entity, Ability
WEAPONSKILL_STATE_ENTER - userEntity, skillId
WEAPONSKILL_BEFORE_USE - userEntity, skillId
WEAPONSKILL_USE - userEntity, targetEntity, skill, tp, action, damage
WEAPONSKILL_TAKE - userEntity, targetEntity, skill, tp, action
WEAPONSKILL_STATE_EXIT - userEntity, skillId, wasExecuted
WEAPONSKILL_STATE_ENTER - Entity, Skillid
WEAPONSKILL_BEFORE_USE - Entity, Skillid
WEAPONSKILL_USE - Entity, Target, Skillid, TP, action
WEAPONSKILL_TAKE - Target, Entity, Skillid, TP, action
WEAPONSKILL_STATE_EXIT - Entity, Skillid
MAGIC_START - Entity, Target, Spell, action
MAGIC_START - Entity, Spell, action
MAGIC_USE - Entity, Target, Spell, action
MAGIC_INTERRUPTED - Entity, Target, Spell, action
MAGIC_TAKE - Target, Entity, Spell, action

View file

@ -1,59 +0,0 @@
# AI Agents
```txt
* This post was written by hand, zhuzhed up by AI, and then manually proofread, fact-checked, and
polished by hand, exactly how it should be.
Even with careful oversight, I still had to alter the tone, correct statements, remove ligatures,
remove outright lies and hallucinations, replace the telltale "em dashes"'s that AI is so fond
of (—), etc.
It's unknown if it would have been faster for me to write the document entirely by hand, or if using
AI forced me to spend much more time in editing and verification than I otherwise would have...
Worth thinking about.
```
### Use of AI, LLMs, and Code Generation Tools in LandSandBoat
AI-assisted coding tools like ChatGPT, Claude, Copilot, and Cursor are now a part of most developers' workflows. Their use is inevitable in an open-source project like LandSandBoat.
However, these tools are **not a substitute for understanding what you're doing**, and they cannot be trusted to write, test, or reason about code on your behalf. If you submit code written or heavily influenced by AI, you are still responsible for the result. That means understanding it, testing it, and verifying that it's correct and appropriate for the project. The code you submit is still going to be read many times over by reviewers and future contributors, and it should be of sufficient quality that it can stand up to this scrutiny.
Submissions that clearly come straight from AI with minimal oversight ("AI slop") waste reviewers' time and degrade the quality of the codebase. If you're using AI, please do so carefully and responsibly.
#### When is AI suitable?
* **Enhanced Auto-Complete / IntelliSense:** Inline suggestions can be effective for filling in small patterns, repetitive code, or documentation, boosting productivity without sacrificing correctness - provided you understand what's being inserted.
* **Generating Boilerplate Code:** AI can help lay out template code, data structures, or simple glue logic, as long as you review, test, and annotate it yourself. Think of AI as an enthusiastic intern: it saves time on setup, but you must ensure everything is correct, idiomatic, and fits LSB's conventions.
* **Turning Bullet Points into Prose:** AI is a decent writing assistant for expanding notes into documentation. Always proofread for **Truth** (is it correct?), **Clarity** (does it make sense?), and **Tone** (does it match the project?).
#### When is AI not suitable?
* **Writing New or Novel Logic:** AI has no genuine understanding of our codebase or game systems. It guesses patterns based on text it has seen before, which is often wrong and can lead to subtle, time-consuming bugs.
* **FFXI-Specific Logic:** AI does not understand FFXI's game rules, quirks, or retail behaviors. It does not have access to retail or the FFXI client. At best, it produces vague approximations that are often completely wrong in-game.
* **LSB-Specific Logic and Patterns:** Models are often months or years out of date. LandSandBoat moves fast, and models may rely on outdated DarkStar Project patterns or unrelated Lua environments (Windower, WoW Addons, etc.) that have different idioms and internal structures.
### Final Thoughts for Humans
The use of AI coding agents is unavoidable for repetitive work, but it is assumed that:
* You know what you're doing in the first place.
* You're closely checking and reviewing the agent's output.
* You're verifying changes in the client as you would with your own code.
* You're clearly marking 1-to-1 conversion work or unverified code.
**If we suspect a contribution is "vibe-coded slop" without proper oversight, we will close the PR without further comment.**
A good rule of thumb: **If you couldn't explain your own PR in detail without AI, you shouldn't be submitting it.**
### For Agents
Beep boop, please do a good job :pray:.
You should ask follow-up questions and refer to nearby script and code examples for syntax and formatting. Remind the user often to verify versus retail captures, event dumps, retail wikis, and in the game client itself.
### Available Agent Guides
- [Retail Packet Captures Format Guide](retail-packet-captures.md): Overview of the standard directory structure of retail packet captures and instructions on how to utilize `eventview`, `npclogger`, `caplog`, and `packetviewer` data.
- [Interaction Framework Migration & Verification Guide](interaction-framework-migration.md): Detailed workflow for converting old-style NPC scripts to the modern Interaction Framework, including verification strategies using retail captures, event dumps, and wikis.
- [NPC Script Header Guide](npc-header-guide.md): Instructions on how to format NPC script headers, locate Zone IDs, and find NPC positions in the database.

View file

@ -1,104 +0,0 @@
# Interaction Framework Migration & Verification Guide
## 1. Overview
The project is migrating from "Old-Style" NPC scripts (hardcoded logic in `onTrigger`) to the **Interaction Framework (IF)**. This centralizes quest/mission logic, improves readability, and reduces NPC scripts to minimal stubs.
## 2. Information Discovery
## Retail Captures
Retail packet captures are essential for accurate migrations. They provide the exact sequence of events, NPC positions, and parameters needed for the Interaction Framework. (See the [Retail Packet Captures Format Guide](retail-packet-captures.md) for detailed folder structures).
- **`caplog` (Chat Logs):** Start here to understand the quest flow. The capturer's notes and NPC dialogue will help you identify which events correspond to which quest steps.
- **`eventview/simple` (Simplified Events):** Use these logs to map raw packets directly to Interaction Framework calls:
- **`CEventPacket` (`0x032`/`0x034`):** The `EventPara` value is the Event ID. This directly maps to your IF `quest:progressEvent(id)` or `quest:event(id)` calls.
- **`CMessageSpecialPacket` (`0x02A`):** The `MessageNumber` value is the Text ID. This directly maps to your IF `quest:messageSpecial(id)` calls (often used for non-standard dialogues or system messages like checking doors/sarcophagi).
- **`CMessageNamePacket` (`0x027`):** The `MesNum` value (sometimes requiring a bitwise `& 0xFFFF` depending on the logger output) is the standard chat dialogue ID. This maps to IF `quest:messageName(id)` or standard text lookups.
- **`npclogger/database` (NPC Data):** Use the `.lua` files here to populate or verify NPC coordinates and properties in `sql/npc_list.sql` or to format your NPC script headers correctly.
- **`packetviewer` (Raw Packets):** For complex interactions that `eventview` doesn't fully capture, you can dive into the raw packets here to understand what the client is sending and receiving.
### Database (SQL)
- **NPC IDs & Positions:** Check `sql/npc_list.sql`. Use this to find the 8-digit NPC ID and their `!pos` coordinates.
- **Item IDs:** Check `sql/item_basic.sql`. If an item constant is missing from Lua, find the ID here and use it directly or add it to the enum.
### Global Registries (Lua Enums)
- **Quest IDs:** `scripts/globals/quests.lua`.
- **Mission IDs:** `scripts/globals/missions.lua`.
- **Item Constants:** `scripts/enum/item.lua`.
- **Key Item Constants:** `scripts/enum/key_item.lua`.
- **Zone Constants:** `scripts/enum/zone.lua`.
### Retail Event Dumps
The `sruon/FFXI-EventsDump` repository is the source of truth for retail event IDs and dialogue.
- **Nearby Repo:** If the repo is cloned next to this one, access it via `../FFXI-EventsDump/dumps/<Zone_Name>`.
- **Remote Access:** Use `web_fetch` or `google_web_search` to find raw markdown files on GitHub if the local path is unavailable.
- **Strings:** Each zone folder has a `strings.txt` file. Map the decimal/hex IDs in the `.md` files to these strings to verify dialogue.
## 3. The Migration Workflow
### Step 1: Research (The "Wiki Triangulation")
1. Check **BOTH** [BG-Wiki](https://www.bg-wiki.com) and [FFXI Wikia](https://ffxiclopedia.fandom.com).
2. Compare steps, item requirements, and NPC dialogue descriptions.
3. Note any "Wait until Japanese Midnight" or "Zone out/in" requirements.
### Step 2: Implementation (The IF File)
Create the appropriate file in `scripts/quests/`, `scripts/missions/`, or `scripts/quests/hiddenQuests/`.
- **Choosing the Container Class:**
- **Quests:** `local quest = Quest:new(xi.questLog.LOG_NAME, xi.quest.id.area.QUEST_NAME)`
- **Missions:** `local mission = Mission:new(xi.mission.log_id.LOG_NAME, xi.mission.id.area.MISSION_NAME)`
- **Hidden Quests:** `local quest = HiddenQuest:new('UniqueStringName')` (Used for non-logged content like Trust acquisitions or Mog House expansions).
- **Why they are different:**
- **Variable Scoping:** Each class automatically prefixes variables (e.g., `Quest[1][2]Prog`, `Mission[4][10]Prog`, or `UniqueStringNameProg`). This prevents collisions across different types of content.
- **Check Arguments:** `Quest` and `Mission` objects automatically check their respective logs/statuses when determining if a section's `check` function should run. `HiddenQuest` relies entirely on custom variables.
- **Basic Structure:**
```lua
local quest = Quest:new(xi.questLog.LOG_NAME, xi.quest.id.area.QUEST_NAME)
quest.reward = { fame = 30, gil = 1000 }
quest.sections = {
{
check = function(player, status, vars) return status == xi.questStatus.QUEST_AVAILABLE end,
[xi.zone.ZONE_ID] = {
['NPC_Name'] = quest:progressEvent(100),
},
},
}
```
- **Trading:** Use `onTrade` within the NPC block. Always use `npcUtil.tradeHasExactly` or `npcUtil.tradeHas`.
- **Zoning:** Use `quest:setMustZone(player)` and `quest:getMustZone(player)`.
- **Trigger Areas:** Handle approach-based cutscenes via `onTriggerAreaEnter`.
### Step 3: NPC Script Cleanup
1. **Header:** Ensure the header includes the `!pos` from `npc_list.sql`.
2. **Logic Removal:** Strip all `if/else` quest blocks.
3. **Minimal Stub:** If no non-quest logic remains, convert to:
```lua
---@type TNpcEntity
local entity = {}
entity.onTrigger = function(player, npc) end
entity.onTrade = function(player, npc, trade) end
return entity
```
4. **Preservation:** Keep patrol logic (`onSpawn`), Trust logic, or complex non-migrated quests in the script.
### Step 4: Default Actions
If an NPC has a single default interaction (e.g., `player:startEvent(200)`), move it to `scripts/zones/<Zone>/DefaultActions.lua`:
```lua
['NPC_Name'] = { event = 200 },
```
### Step 5: Global Marking
Mark the quest in `scripts/globals/quests.lua` with the specific partial conversion tag:
```lua
QUEST_NAME = 123, -- + Partial conversion. TODO: This needs completing with retail caps
```
## 4. Advanced Interaction Techniques
- **Container Action Helpers (`event` vs `progressEvent`):** Under the hood (`scripts/globals/interaction/container.lua`), actions like `quest:progressEvent(id)` are simply syntactic sugar for creating a base Event and applying a priority modifier (e.g. `Event:new(id):progress()`). The same applies to `quest:cutscene(id)` or `quest:replaceEvent(id)`. Use `progressEvent` for critical quest progression to ensure it overrides default NPC behaviors.
- **Event Updates:** Handle multi-choice menus via `onEventUpdate`.
- **Bitmasks:** Use `quest:setVarBit(player, 'Prog', bit)` and `quest:isVarBitsSet(player, 'Prog', bit)`.
- **Variables:** Prefer `quest:getVar` over `player:getCharVar` for framework-managed persistence.
- **Timers:** Use `quest:setTimedVar(player, 'Timer', JstMidnight())` for daily repeats.
## 5. Verification Golden Rule
**Never assume existing logic is correct.** Existing scripts often skip "Reminder" dialogue or "Post-Quest" flavor text. Always cross-reference the `sruon/FFXI-EventsDump` for every NPC involved in the quest to ensure 100% dialogue coverage.

View file

@ -1,75 +0,0 @@
# NPC Script Header Guide
This guide explains how to format the header for NPC script files in LandSandBoat, and how to locate the required information.
## Header Format
Every NPC script should begin with a standardized header. This header provides the zone name, zone ID, NPC name, and the NPC's spawn position (as a `!pos` command).
```lua
-----------------------------------
-- Area: Windurst Walls (239)
-- NPC: Ambrosius
-- !pos 65.175 -2.499 -63.231 239
-----------------------------------
```
### Components
1. **Area**: The name of the zone followed by its Zone ID in parentheses.
2. **NPC**: The name of the NPC.
3. **!pos**: The X, Y, Z coordinates, followed by the Zone ID. This matches the format used by the in-game `!pos` command.
## Finding the Information
### 1. Zone Name and ID
* **Zone Name**: Usually matches the name of the folder containing the script (e.g., `scripts/zones/Windurst_Walls/`).
* **Zone ID**: Can be found in `scripts/enum/zone.lua`. Search for the zone's constant name (e.g., `WINDURST_WALLS`) to find its numeric ID.
### 2. NPC Name
* **NPC Name**: Use the **display name** (the second name) as it appears in the `sql/npc_list.sql` file. This is usually the name players see in-game.
Example SQL:
```sql
INSERT INTO `npc_list` VALUES (17752605,'AMAN_Liaison','A.M.A.N. Liaison', ...);
```
In this case, you would use `A.M.A.N. Liaison` in the header.
### 3. Finding Position (X, Y, Z) in `sql/npc_list.sql`
If you don't have the coordinates from an in-game capture or a retail dump, you can find them in the database:
1. Open `sql/npc_list.sql`.
2. Search for the NPC's name within the section for the specific zone. Note that names in SQL might be in `varbinary` or `char` formats.
3. The coordinates are stored in the `pos_x`, `pos_y`, and `pos_z` columns.
Example SQL entry:
```sql
INSERT INTO `npc_list` VALUES (16781427,'Ambrosius','Ambrosius',0,65.175,-2.499,-63.231,0,40,40,0,0,0,0,0,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',0,NULL,1);
```
In this example:
* `pos_x` = `65.175`
* `pos_y` = `-2.499`
* `pos_z` = `-63.231`
* Zone ID = `239` (derived from the NPC ID or the zone header in the SQL file).
## Maintaining the Notes Section
If a script requires additional context or documentation, a "Notes" section can be included within the header block.
### Existing Notes
If a script already has a notes section, **do not remove it**. Maintain the notes and update them if your changes alter the NPC's behavior or purpose.
### Formatting Notes
Notes should be placed within the header block, usually before the `!pos` command.
```lua
-----------------------------------
-- Area: Windurst Walls (239)
-- NPC: Ambrosius
-- Notes: This NPC is part of the "Crying Over Onions" quest.
-- !pos 65.175 -2.499 -63.231 239
-----------------------------------
```

View file

@ -1,46 +0,0 @@
# Retail Packet Captures Format Guide
When processing unzipped retail packet captures, you will typically encounter a standard directory structure. These captures are usually provided as a `.zip` file, which unpacks into a parent folder representing the content's title, followed by a character folder containing the extracted capture data.
## Folder Structure
A typical unpack hierarchy looks like this:
`[Title Folder] / [Character Name] / [Addon Folders]`
### Important Addon Folders and Their Uses
Inside the character folder, you will find data generated by various capture addons. Folder names may vary slightly in capitalization or structure depending on the logger version. Here are the most important folders and how they should be utilized:
#### 1. `eventview` / `EventView`
Contains data regarding cutscenes and events.
- **`eventview/simple`** (or `.log` files directly under the character name directory): This is the primary directory you will use. It contains logs (usually one `.log` file per zone) outlining simplified event data. Use these files to fill out mission and quest event information when migrating or writing scripts for the Interaction Framework (IF).
- **`eventview/raw`**: Contains more verbose, raw event data if deeper debugging is needed.
#### 2. `npclogger` / `NPCLogger`
Contains data regarding NPC locations, behaviors, and properties.
- **`database` folder or `.db` files**: Depending on the capture, this may be a `database` folder with `.lua` files per zone, or `.db` SQLite files directly in the `NPCLogger` folder. You will use this data to populate or update NPC details, positions, and parameters in `sql/npc_list.sql`.
- *Other folders (like `logs`, `tables`, `widescan`) contain additional raw or parsed NPC data which can be used as supplementary references.*
#### 3. `caplog` / `CapLog`
Contains chat logs from the game client during the capture session.
- **`*.txt` or `*.log` files**: These files represent the capturer's chat window. They are extremely useful for reading notes left by the capturer or seeing the text spoken by NPCs as they are interacted with. This can provide crucial context to help you understand which event is currently playing out.
#### 4. `packetviewer` / `PacketLogger`
Contains raw network packet information.
- Contains `incoming` and `outgoing` folders with packets separated by their hex IDs (e.g., `0x034.log` or `0x0D3.log`), as well as consolidated `full.log`, `incoming.log`, and `outgoing.log` files. This is used when deep-diving into specific raw packet data to understand complex or unmapped game client behaviors.
#### 5. Additional Addon Folders
You may also encounter other specialized folders:
- **`ActionView`**: Logs actions and events (sometimes contains its own `simple` folder with logs, similar to `EventView`).
- **`PathLog`**: Contains `.csv` files tracking PC and NPC movement paths. Useful for recreating NPC patrols.
- **`ShopStock` / `GuildStock`**: Contains `.db` files (`BuyList.db`, `SellList.db`) logging shop and guild inventory data.
- **`KITrack`**: Tracks Key Item acquisitions.
- **`HPTrack`**: Tracks Home Point unlocks/interactions.
- **`AttackDelay`**: Logs related to attack speeds and delays.
## General Workflow
1. Use **`caplog`** to read the flow of the capture and gather context from player notes or NPC dialogues.
2. Use **`eventview`** (specifically the simple logs) to map out the steps, parameters, and event IDs for your Interaction Framework (IF) implementation.
3. If new NPCs are encountered or existing ones are missing data, use **`npclogger`** to prepare their `npc_list.sql` entries.
4. Fall back to **`packetviewer`** / **`PacketLogger`** or `eventview/raw` only when you need to understand low-level network interactions that aren't obvious from the simplified logs.

View file

@ -964,8 +964,8 @@
963 Sleet Blast alt
964 Sleet Blast
965 Geotic Breath
966 Ocher Blast alt
967 Ocher Blast
966 Ochre Blast alt
967 Ochre Blast
968 Sable Breath
969 Snowball
970 Snow Cloud

View file

@ -1,245 +0,0 @@
-----------------------------------
-- Area: Apollyon
-----------------------------------
zones = zones or {}
zones[xi.zone.APOLLYON] =
{
text =
{
ITEM_CANNOT_BE_OBTAINED = 6385, -- You cannot obtain the <item>. Come back after sorting your inventory.
ITEM_OBTAINED = 6391, -- Obtained: <item>.
GIL_OBTAINED = 6392, -- Obtained <number> gil.
KEYITEM_OBTAINED = 6394, -- Obtained key item: <keyitem>.
CARRIED_OVER_POINTS = 7002, -- You have carried over <number> login point[/s].
LOGIN_CAMPAIGN_UNDERWAY = 7003, -- The [/January/February/March/April/May/June/July/August/September/October/November/December] <number> Login Campaign is currently underway!
LOGIN_NUMBER = 7004, -- In celebration of your most recent login (login no. <number>), we have provided you with <number> points! You currently have a total of <number> points.
MEMBERS_LEVELS_ARE_RESTRICTED = 7024, -- Your party is unable to participate because certain members' levels are restricted.
CONQUEST_BASE = 7069, -- Tallying conquest results...
},
mob =
{
-- CS_CARNAGECHIEF_JACKBODOKK = GetFirstID('Carnagechief_Jackbodokk'),
-- CS_DEE_WAPA_THE_DESOLATOR = GetFirstID('Dee_Wapa_the_Desolator'),
-- CS_NAQBA_CHIRURGEON = GetFirstID('NaQba_Chirurgeon'),
-- NE_APOLLYON_SWEEPER_OFFSET = GetFirstID('Apollyon_Sweeper'),
-- NE_GOOBBUE_HARVESTER = GetFirstID('Goobbue_Harvester'),
-- NE_TROGLODYTE_DHALMEL_OFFSET = GetFirstID('Troglodyte_Dhalmel'),
-- NW_APOLLYON_SCAVENGER_OFFSET = GetFirstID('Apollyon_Scavenger'),
-- NW_BARDHA_OFFSET = GetFirstID('Bardha'),
-- NW_CYNOPROSOPI = GetFirstID('Cynoprosopi'),
-- NW_GORYNICH_OFFSET = GetFirstID('Gorynich'),
-- NW_KAISER_BEHEMOTH = GetFirstID('Kaiser_Behemoth'),
-- NW_MILLENARY_MOSSBACK = GetFirstID('Millenary_Mossback'),
-- NW_MOUNTAIN_BUFFALO_OFFSET = GetFirstID('Mountain_Buffalo'),
-- NW_PLUTO = GetFirstID('Pluto'),
-- NW_ZLATOROG = GetFirstID('Zlatorog'),
-- SE_ADAMANTSHELL_OFFSET = GetFirstID('Adamantshell'),
-- SE_FLYING_SPEAR_OFFSET = GetFirstID('Flying_Spear'),
-- SE_TIEHOLTSODI = GetFirstID('Tieholtsodi'),
-- SW_BOSS_JIDRA = GetFirstID('Jidra_Boss'),
-- SW_AIR_ELEMENTAL_OFFSET = GetFirstID('Air_Elemental'),
-- SW_DARK_ELEMENTAL_OFFSET = GetFirstID('Dark_Elemental'),
-- SW_EARTH_ELEMENTAL_OFFSET = GetFirstID('Earth_Elemental'),
-- SW_FIRE_ELEMENTAL_OFFSET = GetFirstID('Fire_Elemental'),
-- SW_ICE_ELEMENTAL_OFFSET = GetFirstID('Ice_Elemental'),
-- SW_LIGHT_ELEMENTAL_OFFSET = GetFirstID('Light_Elemental'),
-- SW_THUNDER_ELEMENTAL_OFFSET = GetFirstID('Thunder_Elemental'),
-- SW_WATER_ELEMENTAL_OFFSET = GetFirstID('Water_Elemental'),
},
npc =
{
-- CENTRAL_LOOT_CRATE = GetFirstID('Central_Loot_Crate'),
-- CS_LOOT_CRATE = GetFirstID('CS_Loot_Crate'),
-- NE_LOOT_CRATE = GetFirstID('NE_Loot_Crate'),
-- NW_LOOT_CRATE = GetFirstID('NW_Loot_Crate'),
-- SE_LOOT_CRATE = GetFirstID('SE_Loot_Crate'),
-- SW_LOOT_CRATE = GetFirstID('SW_Loot_Crate'),
},
-- SW_APOLLYON =
-- {
-- npc =
-- {
-- PORTAL =
-- {
-- 16933231,
-- 16933232,
-- 16933233,
-- },
-- ITEM_CRATES =
-- {
-- 16932865,
-- 16932878,
-- 16932896,
-- },
-- RECOVER_CRATES =
-- {
-- 16932867,
-- 16932880,
-- 16932898,
-- },
-- TIME_CRATES =
-- {
-- 16932866,
-- 16932879,
-- 16932897,
-- },
-- },
-- LINKED_CRATES =
-- {
-- [16932865] = { 16932866, 16932867 },
-- [16932866] = { 16932865, 16932867 },
-- [16932867] = { 16932865, 16932866 },
-- [16932878] = { 16932879, 16932880 },
-- [16932879] = { 16932878, 16932880 },
-- [16932880] = { 16932878, 16932879 },
-- },
-- },
-- SE_APOLLYON =
-- {
-- npc =
-- {
-- PORTAL =
-- {
-- 16933240,
-- 16933239,
-- 16933242,
-- },
-- ITEM_CRATES =
-- {
-- 16932991,
-- 16933005,
-- 16933019,
-- },
-- RECOVER_CRATES =
-- {
-- 16932990,
-- 16933004,
-- 16933018,
-- },
-- TIME_CRATES =
-- {
-- 16932989,
-- 16933003,
-- 16933017,
-- },
-- },
-- },
-- NW_APOLLYON =
-- {
-- npc =
-- {
-- PORTAL =
-- {
-- 16933227,
-- 16933228,
-- 16933229,
-- 16933225,
-- },
-- ITEM_CRATES =
-- {
-- 16932934,
-- 16932947,
-- 16932960,
-- 16932973,
-- },
-- RECOVER_CRATES =
-- {
-- 16932936,
-- 16932949,
-- 16932962,
-- 16932983,
-- },
-- TIME_CRATES =
-- {
-- 16932935,
-- 16932945,
-- 16932946,
-- 16932948,
-- 16932958,
-- 16932959,
-- 16932961,
-- 16932971,
-- 16932972,
-- 16932974,
-- 16932975,
-- 16932982,
-- },
-- },
-- },
-- NE_APOLLYON =
-- {
-- npc =
-- {
-- PORTAL =
-- {
-- 16933236,
-- 16933235,
-- 16933234,
-- 16933238,
-- },
-- ITEM_CRATES =
-- {
-- 16933041,
-- 16933059,
-- 16933076,
-- 16933096,
-- },
-- RECOVER_CRATES =
-- {
-- 16933053,
-- 16933061,
-- 16933078,
-- 16933098,
-- },
-- TIME_CRATES =
-- {
-- 16933042,
-- 16933043,
-- 16933054,
-- 16933060,
-- 16933074,
-- 16933075,
-- 16933077,
-- 16933079,
-- 16933080,
-- 16933097,
-- 16933110,
-- 16933111,
-- },
-- },
-- },
-- CENTRAL_APOLLYON =
-- {
-- },
-- CS_APOLLYON =
-- {
-- npc =
-- {
-- TIME_CRATES =
-- {
-- 16933127,
-- 16933128,
-- },
-- },
-- },
}
return zones[xi.zone.APOLLYON]

View file

@ -1,176 +0,0 @@
-----------------------------------
-- Zone: Apollyon
-----------------------------------
-- local ID = zones[xi.zone.APOLLYON]
-----------------------------------
---@type TZone
local zoneObject = {}
zoneObject.onInitialize = function(zone)
SetServerVariable('[CENTRAL_APOLLYON]Time', 0)
SetServerVariable('[CS_Apollyon]Time', 0)
SetServerVariable('[NE_Apollyon]Time', 0)
SetServerVariable('[NW_Apollyon]Time', 0)
SetServerVariable('[SE_APOLLYON]Time', 0)
SetServerVariable('[SW_APOLLYON]Time', 0)
zone:registerCuboidTriggerArea(1, 637, -4, -642, 642, 4, -637) -- SE Apollyon NE exit
zone:registerCuboidTriggerArea(2, -642, -4, -642, -637, 4, -637) -- APOLLYON_NW_SW exit
zone:registerCuboidTriggerArea(20, 396, -4, -522, 403, 4, -516) -- Apollyon SE telporter floor 1 to floor 2
zone:registerCuboidTriggerArea(21, 116, -4, -443, 123, 4, -436) -- Apollyon SE telporter floor 2 to floor 3
zone:registerCuboidTriggerArea(22, 276, -4, -283, 283, 4, -276) -- Apollyon SE telporter floor 3 to floor 4
zone:registerCuboidTriggerArea(24, 396, -4, 76, 403, 4, 83) -- Apollyon NE telporter floor 1 to floor 2
zone:registerCuboidTriggerArea(25, 276, -4, 356, 283, 4, 363) -- Apollyon NE telporter floor 2 to floor 3
zone:registerCuboidTriggerArea(26, 236, -4, 517, 243, 4, 523) -- Apollyon NE telporter floor 3 to floor 4
zone:registerCuboidTriggerArea(27, 517, -4, 637, 523, 4, 643) -- Apollyon NE telporter floor 4 to floor 5
zone:registerCuboidTriggerArea(29, -403, -4, -523, -396, 4, -516) -- Apollyon SW telporter floor 1 to floor 2
zone:registerCuboidTriggerArea(30, -123, -4, -443, -116, 4, -436) -- Apollyon SW telporter floor 2 to floor 3
zone:registerCuboidTriggerArea(31, -283, -4, -283, -276, 4, -276) -- Apollyon SW telporter floor 3 to floor 4
zone:registerCuboidTriggerArea(33, -403, -4, 76, -396, 4, 83) -- Apollyon NW telporter floor 1 to floor 2
zone:registerCuboidTriggerArea(34, -283, -4, 356, -276, 4, 363) -- Apollyon NW telporter floor 2 to floor 3
zone:registerCuboidTriggerArea(35, -243, -4, 516, -236, 4, 523) -- Apollyon NW telporter floor 3 to floor 4
zone:registerCuboidTriggerArea(36, -523, -4, 636, -516, 4, 643) -- Apollyon NW telporter floor 4 to floor 5
end
zoneObject.onConquestUpdate = function(zone, updatetype, influence, owner, ranking, isConquestAlliance)
xi.conquest.onConquestUpdate(zone, updatetype, influence, owner, ranking, isConquestAlliance)
end
zoneObject.onZoneIn = function(player, prevZone)
local cs = -1
if
player:getXPos() == 0 and
player:getYPos() == 0 and
player:getZPos() == 0
then
player:setPos(643, 0.1, -600)
end
return cs
end
zoneObject.onTriggerAreaEnter = function(player, triggerArea)
-- local triggerAreaID = triggerArea:getTriggerAreaID()
-- switch (triggerAreaID): caseof
-- {
-- -- Apollyon: SE_NE exit
-- [1] = function()
-- player:startEvent(100)
-- end,
-- -- Apollyon: NW_SW exit
-- [2] = function()
-- player:startEvent(101)
-- end,
-- -- Apollyon: SE Teleporters
-- [20] = function()
-- if GetNPCByID(ID.SE_APOLLYON.npc.PORTAL[1]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(219)
-- end
-- end,
-- [21] = function()
-- if GetNPCByID(ID.SE_APOLLYON.npc.PORTAL[2]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(218)
-- end
-- end,
-- [22] = function()
-- if GetNPCByID(ID.SE_APOLLYON.npc.PORTAL[3]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(216)
-- end
-- end,
-- -- Apollyon: NE Teleporters
-- [24] = function()
-- if GetNPCByID(ID.NE_APOLLYON.npc.PORTAL[1]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(214)
-- end
-- end,
-- [25] = function()
-- if GetNPCByID(ID.NE_APOLLYON.npc.PORTAL[2]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(212)
-- end
-- end,
-- [26] = function()
-- if GetNPCByID(ID.NE_APOLLYON.npc.PORTAL[3]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(210)
-- end
-- end,
-- [27] = function()
-- if GetNPCByID(ID.NE_APOLLYON.npc.PORTAL[4]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(215)
-- end
-- end,
-- -- Apollyon: SW Teleporters
-- [29] = function()
-- if GetNPCByID(ID.SW_APOLLYON.npc.PORTAL[1]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(208)
-- end
-- end,
-- [30] = function()
-- if GetNPCByID(ID.SW_APOLLYON.npc.PORTAL[2]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(209)
-- end
-- end,
-- [31] = function()
-- if GetNPCByID(ID.SW_APOLLYON.npc.PORTAL[3]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(207)
-- end
-- end,
-- -- Apollyon: NW Teleporters
-- [33] = function()
-- if GetNPCByID(ID.NW_APOLLYON.npc.PORTAL[1]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(205)
-- end
-- end,
-- [34] = function()
-- if GetNPCByID(ID.NW_APOLLYON.npc.PORTAL[2]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(203)
-- end
-- end,
-- [35] = function()
-- if GetNPCByID(ID.NW_APOLLYON.npc.PORTAL[3]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(201)
-- end
-- end,
-- [36] = function()
-- if GetNPCByID(ID.NW_APOLLYON.npc.PORTAL[4]):getAnimation() == xi.animation.OPEN_DOOR then
-- player:startOptionalCutscene(200)
-- end
-- end,
-- }
end
zoneObject.onTriggerAreaLeave = function(player, triggerArea)
end
zoneObject.onEventUpdate = function(player, csid, option, npc)
end
zoneObject.onEventFinish = function(player, csid, option, npc)
if csid == 100 and option == 1 then
player:setPos(557, -1, 441, 128, 33) -- Apollyon: SE_NE exit
elseif csid == 101 and option == 1 then
player:setPos(-561, 0, 443, 242, 33) -- Apollyon: NW_SW exit
end
end
return zoneObject

View file

@ -1,23 +0,0 @@
# Legacy Limbus Documentation
This repository preserves documentation for **legacy Limbus** because the original version of the system has effectively been removed from the game by Square Enix.
## Why this is documented
Old Limbus cannot be restored through simple script or naming changes alone. The original implementation depended on client data that no longer exists in a usable form. Events, NPCs, mobs, and related assets were removed, renamed, or otherwise changed to the point that the system is no longer works off the base FFXI client.
To get legacy Limbus working again, you would need to restore older DAT files and perform significant client-side and server-side reconstruction.
## Support status
Legacy Limbus is included here for **historical reference and preservation only**.
It should be considered:
- **Unsupported**
- Dependent on **external legacy DATs not provided by this project**
- A feature that requires substantial manual restoration work
## Purpose of this folder
The goal of this documentation is to preserve information about what legacy Limbus was, what was removed, and what would be required to restore it in a custom environment.

View file

@ -1,206 +0,0 @@
-----------------------------------
-- Area: Temenos
-----------------------------------
zones = zones or {}
zones[xi.zone.TEMENOS] =
{
text =
{
ITEM_CANNOT_BE_OBTAINED = 6385, -- You cannot obtain the <item>. Come back after sorting your inventory.
ITEM_OBTAINED = 6391, -- Obtained: <item>.
GIL_OBTAINED = 6392, -- Obtained <number> gil.
KEYITEM_OBTAINED = 6394, -- Obtained key item: <keyitem>.
CARRIED_OVER_POINTS = 7002, -- You have carried over <number> login point[/s].
LOGIN_CAMPAIGN_UNDERWAY = 7003, -- The [/January/February/March/April/May/June/July/August/September/October/November/December] <number> Login Campaign is currently underway!
LOGIN_NUMBER = 7004, -- In celebration of your most recent login (login no. <number>), we have provided you with <number> points! You currently have a total of <number> points.
MEMBERS_LEVELS_ARE_RESTRICTED = 7024, -- Your party is unable to participate because certain members' levels are restricted.
CHIP_TRADE_T = 7031, -- What do you wish to do? Show me the cutscene again. Skip the cutscene and continue.
CONQUEST_BASE = 7069, -- Tallying conquest results...
},
mob =
{
},
npc =
{
-- C1_LOOT_CRATE = GetFirstID('C1_Loot_Crate'),
-- C2_LOOT_CRATE = GetFirstID('C2_Loot_Crate'),
-- C3_LOOT_CRATE = GetFirstID('C3_Loot_Crate'),
-- C4_LOOT_CRATE = GetFirstID('C4_Loot_Crate'),
-- CB_LOOT_CRATE = GetFirstID('CB_Loot_Crate'),
-- N_LOOT_CRATE = GetFirstID('N_Loot_Crate'),
-- W_LOOT_CRATE = GetFirstID('W_Loot_Crate'),
},
-- TEMENOS_NORTHERN_TOWER =
-- {
-- mob =
-- {
-- MOBLIN_DUSTMAN = 16928774,
-- KARI = 16928784,
-- TELCHINES_DRAGOON = 16928790,
-- TELCHINES_MONK = 16928792,
-- KINDRED_BLACK_MAGE = 16928802,
-- CRYPTONBERRY_ABDUCTOR = 16928818,
-- CRYPTONBERRY_DESIGNATOR = 16928819,
-- },
-- npc =
-- {
-- PORTAL =
-- {
-- 16929198,
-- 16929199,
-- 16929200,
-- 16929201,
-- 16929202,
-- 16929203,
-- 16929204,
-- },
-- ITEM_CRATES =
-- {
-- 16928770,
-- 16928779,
-- 16928786,
-- 16928795,
-- 16928807,
-- 16928814,
-- },
-- TIME_CRATES =
-- {
-- 16928771,
-- 16928780,
-- 16928787,
-- 16928796,
-- 16928808,
-- 16928815,
-- },
-- RECOVER_CRATES =
-- {
-- 16928769,
-- 16928778,
-- 16928785,
-- 16928794,
-- 16928806,
-- 16928813,
-- },
-- },
-- LINKED_CRATES =
-- {
-- [16932865] = { 16932866, 16932867 },
-- [16928769] = { 16928770, 16928771 },
-- [16928770] = { 16928769, 16928771 },
-- [16928771] = { 16928769, 16928770 },
-- [16928778] = { 16928779, 16928780 },
-- [16928779] = { 16928778, 16928780 },
-- [16928780] = { 16928778, 16928779 },
-- [16928785] = { 16928786, 16928787 },
-- [16928786] = { 16928785, 16928787 },
-- [16928787] = { 16928785, 16928786 },
-- [16928794] = { 16928795, 16928796 },
-- [16928795] = { 16928794, 16928796 },
-- [16928796] = { 16928794, 16928795 },
-- [16928806] = { 16928807, 16928808 },
-- [16928807] = { 16928806, 16928808 },
-- [16928808] = { 16928806, 16928807 },
-- [16928813] = { 16928814, 16928815 },
-- [16928814] = { 16928813, 16928815 },
-- [16928815] = { 16928813, 16928814 },
-- },
-- },
-- TEMENOS_WESTERN_TOWER =
-- {
-- mob =
-- {
-- ENHANCED_TIGER = 16928898,
-- ENHANCED_MANDRAGORA = 16928910,
-- ENHANCED_BEETLE = 16928922,
-- ENHANCED_LIZARD = 16928931,
-- ENHANCED_SLIME = 16928943,
-- },
-- npc =
-- {
-- PORTAL =
-- {
-- 16929212,
-- 16929213,
-- 16929214,
-- 16929215,
-- 16929216,
-- 16929217,
-- 16929218,
-- },
-- CRATE_OFFSETS =
-- {
-- 16928895,
-- 16928907,
-- 16928919,
-- 16928928,
-- 16928940,
-- 16928949,
-- },
-- },
-- },
-- TEMENOS_EASTERN_TOWER =
-- {
-- mob =
-- {
-- ICE_ELEMENTAL = 16928849,
-- AIR_ELEMENTAL = 16928858,
-- THUNDER_ELEMENTAL = 16928876,
-- },
-- npc =
-- {
-- PORTAL =
-- {
-- 16929205,
-- 16929206,
-- 16929207,
-- 16929208,
-- 16929209,
-- 16929210,
-- 16929211,
-- },
-- CRATE_OFFSETS =
-- {
-- 16928836,
-- 16928845,
-- 16928854,
-- 16928863,
-- 16928872,
-- 16928881,
-- 16928890,
-- },
-- },
-- },
-- CENTRAL_TEMENOS_4TH_FLOOR =
-- {
-- npc =
-- {
-- GROUPS =
-- {
-- { offset = 16928967, count = 4 },
-- { offset = 16928971, count = 7 },
-- { offset = 16928978, count = 8 },
-- },
-- },
-- mob =
-- {
-- GROUPS =
-- {
-- { offset = 16928986, count = 3 },
-- { offset = 16928991, count = 6 },
-- { offset = 16928997, count = 7 },
-- },
-- },
-- },
}
return zones[xi.zone.TEMENOS]

View file

@ -1,99 +0,0 @@
-----------------------------------
-- Zone: Temenos (37)
-----------------------------------
local ID = zones[xi.zone.TEMENOS]
-----------------------------------
---@type TZone
local zoneObject = {}
zoneObject.onInitialize = function(zone)
SetServerVariable('[TEMENOS_NORTHERN_TOWER]Time', 0)
SetServerVariable('[TEMENOS_EASTERN_TOWER]Time', 0)
SetServerVariable('[TEMENOS_WESTERN_TOWER]Time', 0)
SetServerVariable('[CENTRAL_TEMENOS_4TH_FLOOR]Time', 0)
SetServerVariable('[CENTRAL_TEMENOS_3RD_FLOOR]Time', 0)
SetServerVariable('[CENTRAL_TEMENOS_2ND_FLOOR]Time', 0)
SetServerVariable('[CENTRAL_TEMENOS_1ST_FLOOR]Time', 0)
SetServerVariable('[CENTRAL_TEMENOS_BASEMENT]Time', 0)
-- Temenos North Elevators
zone:registerCylindricalTriggerArea(1, 340.000, 376.000, 5) -- F1 -> F2
zone:registerCylindricalTriggerArea(2, 220.000, 376.000, 5) -- F2 -> F3
zone:registerCylindricalTriggerArea(3, 20.000, 376.000, 5) -- F3 -> F4
zone:registerCylindricalTriggerArea(4, -100.000, 376.000, 5) -- F4 -> F5
zone:registerCylindricalTriggerArea(5, -300.000, 376.000, 5) -- F5 -> F6
zone:registerCylindricalTriggerArea(6, -420.000, 376.000, 5) -- F6 -> F7
zone:registerCylindricalTriggerArea(7, -620.000, 376.000, 5) -- F7 -> Entrance
-- Temenos East Elevators
zone:registerCylindricalTriggerArea(8, 340.000, 96.000, 5) -- F1 -> F2
zone:registerCylindricalTriggerArea(9, 220.000, 96.000, 5) -- F2 -> F3
zone:registerCylindricalTriggerArea(10, 20.000, 96.000, 5) -- F3 -> F4
zone:registerCylindricalTriggerArea(11, -100.000, 96.000, 5) -- F4 -> F5
zone:registerCylindricalTriggerArea(12, -300.000, 96.000, 5) -- F5 -> F6
zone:registerCylindricalTriggerArea(13, -420.000, 96.000, 5) -- F6 -> F7
zone:registerCylindricalTriggerArea(14, -620.000, 96.000, 5) -- F7 -> Entrance
-- Temenos West Elevators
zone:registerCylindricalTriggerArea(15, 340.000, -184.000, 5) -- F1 -> F2
zone:registerCylindricalTriggerArea(16, 220.000, -184.000, 5) -- F2 -> F3
zone:registerCylindricalTriggerArea(17, 20.000, -184.000, 5) -- F3 -> F4
zone:registerCylindricalTriggerArea(18, -100.000, -184.000, 5) -- F4 -> F5
zone:registerCylindricalTriggerArea(19, -300.000, -184.000, 5) -- F5 -> F6
zone:registerCylindricalTriggerArea(20, -420.000, -184.000, 5) -- F6 -> F7
zone:registerCylindricalTriggerArea(21, -620.000, -184.000, 5) -- F7 -> Entrance
-- Temenos Central Elevators
zone:registerCylindricalTriggerArea(22, 540.000, -544.000, 5) -- Basement -> Entrance
zone:registerCylindricalTriggerArea(23, 300.000, -504.000, 5) -- F1 -> Entrance
zone:registerCylindricalTriggerArea(24, -20.000, -544.000, 5) -- F2 -> Entrance
zone:registerCylindricalTriggerArea(25, -264.000, -500.000, 5) -- F3 -> Entrance
zone:registerCylindricalTriggerArea(26, -580.000, -584.000, 5) -- F4 -> Entrance
end
zoneObject.onConquestUpdate = function(zone, updatetype, influence, owner, ranking, isConquestAlliance)
xi.conquest.onConquestUpdate(zone, updatetype, influence, owner, ranking, isConquestAlliance)
end
zoneObject.onZoneIn = function(player, prevZone)
local cs = -1
if
player:getXPos() == 0 and
player:getYPos() == 0 and
player:getZPos() == 0
then
player:setPos(580, -1.5, 4.452, 192)
end
return cs
end
zoneObject.onTriggerAreaEnter = function(player, triggerArea)
-- local triggerAreaID = triggerArea:getTriggerAreaID()
-- local cs
-- if GetNPCByID(ID.TEMENOS_NORTHERN_TOWER.npc.PORTAL[1] + (triggerAreaID - 1)):getAnimation() == xi.animation.OPEN_DOOR then
-- if triggerAreaID > 20 then
-- cs = 120
-- else
-- cs = triggerAreaID + 99
-- end
-- player:startOptionalCutscene(cs)
-- end
end
zoneObject.onTriggerAreaLeave = function(player, triggerArea)
end
zoneObject.onEventUpdate = function(player, csid, option, npc)
if csid == 32001 or csid == 32002 then
player:messageSpecial(ID.text.HUM + 1)
end
end
zoneObject.onEventFinish = function(player, csid, option, npc)
end
return zoneObject

View file

@ -554,7 +554,7 @@
ALL_WSDMG_FIRST_HIT = 841, // Generic (all Weaponskills) damage, first hit only.
AUTO_DECISION_DELAY = 842, // Reduces the Automaton's global decision delay
AUTO_SHIELD_BASH_DELAY = 843, // Reduces the Automaton's global shield bash delay
AUTO_MAGIC_COOLDOWN = 844, // Adjusts the Automaton's global magic cooldown. (negative value reduces cooldown, positive value increases cooldown)
AUTO_MAGIC_DELAY = 844, // Reduces the Automaton's global magic delay
AUTO_HEALING_DELAY = 845, // Reduces the Automaton's global healing delay
AUTO_HEALING_THRESHOLD = 846, // Increases the healing trigger threshold
BURDEN_DECAY = 847, // Increases amount of burden removed per tick
@ -653,8 +653,8 @@
// SPARE ID 936
FOOD_DURATION = 937, // Percentage to increase food duration
// SPARE ID 938
AUTO_STEAM_JACKET_REDUCTION = 939, // Percent damage reduction from Steam Jacket
AUTO_STEAM_JACKET = 938, // Causes the Automaton to mitigate damage from successive attacks of the same type
AUTO_STEAM_JACKET_REDUCTION = 939, // Amount of damage reduced with Steam Jacket
AUTO_SCHURZEN = 940, // Prevents fatal damage leaving the automaton at 1HP and consumes an Earth manuever
AUTO_EQUALIZER = 941, // Reduces damage received according to damage taken
AUTO_PERFORMANCE_BOOST = 942, // Increases the performance of other attachments by a percentage
@ -770,3 +770,4 @@
// For example, +10% damage to Chant du Cygne would be ID 570 + 225 (795)
// SPARE = 1077,

View file

@ -1,15 +1,15 @@
# add_subdirectory(lua) # Handled globally
# add_subdirectory(mariadb) # Handled globally
# add_subdirectory(mariadbcpp) # Handled globally
# add_subdirectory(zmq) # Handled globally
# add_subdirectory(openssl) # Handled globally
add_subdirectory(concurrentqueue)
add_subdirectory(SPSCQueue)
add_subdirectory(sol)
# CPM Modules
if(TRACY_ENABLE)
# Tracy version tag, without the leading 'v'
set(TRACY_VERSION 0.13.1)
set(TRACY_VERSION 0.12.2)
# Download client library
CPMAddPackage(
@ -42,55 +42,31 @@ if(TRACY_ENABLE)
tar xvf "${CMAKE_SOURCE_DIR}/tracy.tar.gz"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/
)
else() # UNIX (Linux / macOS)
include(ExternalProject)
else() # UNIX
# TODO: Auto-build Tracy and capture executables on Linux
# sudo apt-get -y install libglfw3-dev libdbus-1-dev libcapstone-dev libtbb-dev libdebuginfod-dev libfreetype-dev
# target name:source subdirectory
set(TRACY_TOOLS
"tracy-capture:capture"
"tracy-csvexport:csvexport"
)
# execute_process(COMMAND "make"
# WORKING_DIRECTORY ${tracy_SOURCE_DIR}/profiler/build/unix
# )
foreach(_tracy_tool ${TRACY_TOOLS})
string(REPLACE ":" ";" _tracy_tool "${_tracy_tool}")
list(GET _tracy_tool 0 _tracy_tool_name)
list(GET _tracy_tool 1 _tracy_tool_dir)
message(STATUS "Configuring Tracy tool: ${_tracy_tool_name}")
set(_tracy_tool_bindir ${CMAKE_BINARY_DIR}/tracy-tools/${_tracy_tool_name})
ExternalProject_Add(${_tracy_tool_name}
SOURCE_DIR ${TracyClient_SOURCE_DIR}/${_tracy_tool_dir}
BINARY_DIR ${_tracy_tool_bindir}
CMAKE_ARGS
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}
-DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${_tracy_tool_bindir}
BUILD_ALWAYS TRUE
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different
${_tracy_tool_bindir}/${_tracy_tool_name}
${CMAKE_SOURCE_DIR}/${_tracy_tool_name}
)
endforeach()
# execute_process(COMMAND "make"
# WORKING_DIRECTORY ${tracy_SOURCE_DIR}/capture/build/unix
# )
endif()
endif(TRACY_ENABLE)
CPMAddPackage(
NAME fmt
GITHUB_REPOSITORY fmtlib/fmt
GIT_TAG 12.2.0
GIT_TAG 11.2.0
SYSTEM ON
) # defines: fmt::fmt
CPMAddPackage(
NAME spdlog
GITHUB_REPOSITORY gabime/spdlog
GIT_TAG v1.17.0
GIT_TAG v1.15.3
SYSTEM ON
OPTIONS
"SPDLOG_ENABLE_PCH ON"
@ -100,9 +76,11 @@ CPMAddPackage(
CPMAddPackage(
NAME recastnavigation
GITHUB_REPOSITORY recastnavigation/recastnavigation
GIT_TAG 1078bfe346d9bb560faa748c8fde2e7aae73a3ab
GIT_TAG bd98d84c274ee06842bf51a4088ca82ac71f8c2d
SYSTEM ON
OPTIONS
# TODO: Remove this once recast is updated to use CMake 3.5+, it's currently set to what we use in the root CMakeLists.txt
"CMAKE_POLICY_VERSION_MINIMUM 3.20"
"RECASTNAVIGATION_DEMO OFF"
"RECASTNAVIGATION_TESTS OFF"
"RECASTNAVIGATION_EXAMPLES OFF"
@ -118,28 +96,6 @@ CPMAddPackage(
SYSTEM ON
) # defines: fast_obj
CPMAddPackage(
NAME earcut_hpp
GITHUB_REPOSITORY mapbox/earcut.hpp
GIT_TAG v2.2.4
DOWNLOAD_ONLY ON
) # defines: earcut_hpp
if(earcut_hpp_ADDED) # header-only
add_library(earcut_hpp INTERFACE)
target_include_directories(earcut_hpp SYSTEM INTERFACE ${earcut_hpp_SOURCE_DIR}/include/)
endif()
CPMAddPackage(
NAME rapidyaml
GITHUB_REPOSITORY biojppm/rapidyaml
GIT_TAG v0.15.2
SYSTEM ON
OPTIONS
"RYML_BUILD_TOOLS OFF"
"RYML_BUILD_API OFF"
"RYML_INSTALL OFF"
) # defines: ryml
CPMAddPackage(
NAME argparse
GITHUB_REPOSITORY p-ranav/argparse
@ -149,8 +105,8 @@ CPMAddPackage(
CPMAddPackage(
NAME efsw
GITHUB_REPOSITORY SpartanJ/efsw
GIT_TAG 22f17a0bcdf3a4edf61f8b14328391463389e548 # master
GITHUB_REPOSITORY zach2good/efsw
GIT_TAG c37c7e0fc6bbd63659edeba458273c35a51513da # master
SYSTEM ON
OPTIONS
"VERBOSE OFF"
@ -171,7 +127,7 @@ CPMAddPackage(
CPMAddPackage(
NAME cpp-httplib
GITHUB_REPOSITORY yhirose/cpp-httplib
GIT_TAG v0.49.0
GIT_TAG v0.18.3
SYSTEM ON
OPTIONS
"HTTPLIB_REQUIRE_ZLIB OFF"
@ -181,7 +137,7 @@ CPMAddPackage(
CPMAddPackage(
NAME json
GITHUB_REPOSITORY nlohmann/json
GIT_TAG v3.12.0
GIT_TAG 9f60e855576bb1e95f39ab23b3821982cccb0bab
SYSTEM ON
) # defines: nlohmann_json::nlohmann_json
@ -197,9 +153,9 @@ endif()
CPMAddPackage(
NAME asio
VERSION 1.38.0
VERSION 1.32.0
GITHUB_REPOSITORY chriskohlhoff/asio
GIT_TAG asio-1-38-0 # asio uses non-standard version tag, we must specify GIT_TAG
GIT_TAG asio-1-32-0 # asio uses non-standard version tag, we must specify GIT_TAG
) #defines asio
# ASIO doesn't use CMake, we have to configure it manually. Extra notes for using on Windows:
@ -209,7 +165,7 @@ CPMAddPackage(
if(asio_ADDED)
add_library(asio INTERFACE)
target_include_directories(asio SYSTEM INTERFACE ${asio_SOURCE_DIR}/include)
target_include_directories(asio SYSTEM INTERFACE ${asio_SOURCE_DIR}/asio/include)
target_compile_definitions(asio INTERFACE ASIO_STANDALONE ASIO_NO_DEPRECATED)
@ -281,7 +237,7 @@ CPMAddPackage(
CPMAddPackage(
NAME magic_enum
GITHUB_REPOSITORY Neargye/magic_enum
GIT_TAG v0.9.8
GIT_TAG 1a1824df7ac798177a521eed952720681b0bf482
SYSTEM ON
) # defines: magic_enum
@ -292,56 +248,12 @@ CPMAddPackage(
SYSTEM ON
) # defines: termcolor::termcolor
CPMAddPackage(
NAME unordered_dense
GITHUB_REPOSITORY martinus/unordered_dense
GIT_TAG v4.8.1
SYSTEM ON
) # defines: unordered_dense::unordered_dense (aliased to FlatHashMap, see src/common/flat_hash_map.h)
# TODO: std::move_only_function lands in C++23, but libc++ (macOS) has not implemented
# : it yet. Remove this once all compilers for all platforms implement.
CPMAddPackage(
NAME function2
GITHUB_REPOSITORY Naios/function2
GIT_TAG 4.2.4
SYSTEM ON
) # defines: function2 (aliased to Fn, see src/common/types/fn.h)
# How cpptrace turns a crash address into function + file:line, per platform:
set(CPPTRACE_SYMBOL_OPTIONS "")
if(APPLE)
# macOS binaries carry a "debug map" pointing at the .o files rather than embedded DWARF;
# atos resolves against the staged .dSYM (see set_target_output_directory) and is fast.
list(APPEND CPPTRACE_SYMBOL_OPTIONS
"CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF OFF"
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE ON"
)
elseif(UNIX)
# Linux: resolve in-process with libdwarf.
list(APPEND CPPTRACE_SYMBOL_OPTIONS
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE OFF"
"CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF ON"
"CPPTRACE_USE_EXTERNAL_LIBDWARF ON"
"CPPTRACE_FIND_LIBDWARF_WITH_PKGCONFIG ON"
)
endif()
CPMAddPackage(
NAME cpptrace
GITHUB_REPOSITORY jeremy-rifkin/cpptrace
GIT_TAG v1.0.4
SYSTEM ON
OPTIONS
${CPPTRACE_SYMBOL_OPTIONS}
) # defines: cpptrace::cpptrace
set(SHARED_EXTERNAL_LIBS
fmt::fmt
spdlog
concurrentqueue
spscqueue
mariadbclient
mariadbcpp
sol2_single
argparse
efsw
@ -350,21 +262,27 @@ set(SHARED_EXTERNAL_LIBS
asio
alpaca
magic_enum
utf8cpp
unordered_dense::unordered_dense
function2
cpptrace::cpptrace
)
if(APPLE)
if(WIN32)
# add wepoll for epoll support on windows
add_subdirectory(wepoll)
list(APPEND SHARED_EXTERNAL_LIBS
wepoll
)
# backwards needs these to add to linker
elseif(APPLE)
# MacOS has bfd built in clang
list(APPEND SHARED_EXTERNAL_LIBS
dl
)
elseif(UNIX)
# Linux needs bfd as it's not native like MacOS
list(APPEND SHARED_EXTERNAL_LIBS
bfd
dl
zstd
)
endif()
@ -377,9 +295,6 @@ set(MAP_ONLY_EXTERNAL_LIBS
RecastNavigation::Recast
RecastNavigation::Detour
fast_obj
earcut_hpp
ryml
zlibstatic
)
set(SEARCH_ONLY_EXTERNAL_LIBS

View file

@ -1,3 +0,0 @@
add_library(spscqueue INTERFACE)
target_sources(spscqueue INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/rigtorp/SPSCQueue.h)
target_include_directories(spscqueue SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/)

View file

@ -1,237 +0,0 @@
/*
Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <atomic>
#include <cassert>
#include <cstddef>
#include <memory> // std::allocator
#include <new> // std::hardware_destructive_interference_size
#include <stdexcept>
#include <type_traits> // std::enable_if, std::is_*_constructible
#ifdef __has_cpp_attribute
#if __has_cpp_attribute(nodiscard)
#define RIGTORP_NODISCARD [[nodiscard]]
#endif
#endif
#ifndef RIGTORP_NODISCARD
#define RIGTORP_NODISCARD
#endif
namespace rigtorp {
template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {
#if defined(__cpp_if_constexpr) && defined(__cpp_lib_void_t)
template <typename Alloc2, typename = void>
struct has_allocate_at_least : std::false_type {};
template <typename Alloc2>
struct has_allocate_at_least<
Alloc2, std::void_t<typename Alloc2::value_type,
decltype(std::declval<Alloc2 &>().allocate_at_least(
size_t{}))>> : std::true_type {};
#endif
public:
explicit SPSCQueue(const size_t capacity,
const Allocator &allocator = Allocator())
: capacity_(capacity), allocator_(allocator) {
// The queue needs at least one element
if (capacity_ < 1) {
capacity_ = 1;
}
capacity_++; // Needs one slack element
// Prevent overflowing size_t
if (capacity_ > SIZE_MAX - 2 * kPadding) {
capacity_ = SIZE_MAX - 2 * kPadding;
}
#if defined(__cpp_if_constexpr) && defined(__cpp_lib_void_t)
if constexpr (has_allocate_at_least<Allocator>::value) {
auto res = allocator_.allocate_at_least(capacity_ + 2 * kPadding);
slots_ = res.ptr;
capacity_ = res.count - 2 * kPadding;
} else {
slots_ = std::allocator_traits<Allocator>::allocate(
allocator_, capacity_ + 2 * kPadding);
}
#else
slots_ = std::allocator_traits<Allocator>::allocate(
allocator_, capacity_ + 2 * kPadding);
#endif
static_assert(alignof(SPSCQueue<T>) == kCacheLineSize, "");
static_assert(sizeof(SPSCQueue<T>) >= 3 * kCacheLineSize, "");
assert(reinterpret_cast<char *>(&readIdx_) -
reinterpret_cast<char *>(&writeIdx_) >=
static_cast<std::ptrdiff_t>(kCacheLineSize));
}
~SPSCQueue() {
while (front()) {
pop();
}
std::allocator_traits<Allocator>::deallocate(allocator_, slots_,
capacity_ + 2 * kPadding);
}
// non-copyable and non-movable
SPSCQueue(const SPSCQueue &) = delete;
SPSCQueue &operator=(const SPSCQueue &) = delete;
template <typename... Args>
void emplace(Args &&...args) noexcept(
std::is_nothrow_constructible<T, Args &&...>::value) {
static_assert(std::is_constructible<T, Args &&...>::value,
"T must be constructible with Args&&...");
auto const writeIdx = writeIdx_.load(std::memory_order_relaxed);
auto nextWriteIdx = writeIdx + 1;
if (nextWriteIdx == capacity_) {
nextWriteIdx = 0;
}
while (nextWriteIdx == readIdxCache_) {
readIdxCache_ = readIdx_.load(std::memory_order_acquire);
}
new (&slots_[writeIdx + kPadding]) T(std::forward<Args>(args)...);
writeIdx_.store(nextWriteIdx, std::memory_order_release);
}
template <typename... Args>
RIGTORP_NODISCARD bool try_emplace(Args &&...args) noexcept(
std::is_nothrow_constructible<T, Args &&...>::value) {
static_assert(std::is_constructible<T, Args &&...>::value,
"T must be constructible with Args&&...");
auto const writeIdx = writeIdx_.load(std::memory_order_relaxed);
auto nextWriteIdx = writeIdx + 1;
if (nextWriteIdx == capacity_) {
nextWriteIdx = 0;
}
if (nextWriteIdx == readIdxCache_) {
readIdxCache_ = readIdx_.load(std::memory_order_acquire);
if (nextWriteIdx == readIdxCache_) {
return false;
}
}
new (&slots_[writeIdx + kPadding]) T(std::forward<Args>(args)...);
writeIdx_.store(nextWriteIdx, std::memory_order_release);
return true;
}
void push(const T &v) noexcept(std::is_nothrow_copy_constructible<T>::value) {
static_assert(std::is_copy_constructible<T>::value,
"T must be copy constructible");
emplace(v);
}
template <typename P, typename = typename std::enable_if<
std::is_constructible<T, P &&>::value>::type>
void push(P &&v) noexcept(std::is_nothrow_constructible<T, P &&>::value) {
emplace(std::forward<P>(v));
}
RIGTORP_NODISCARD bool
try_push(const T &v) noexcept(std::is_nothrow_copy_constructible<T>::value) {
static_assert(std::is_copy_constructible<T>::value,
"T must be copy constructible");
return try_emplace(v);
}
template <typename P, typename = typename std::enable_if<
std::is_constructible<T, P &&>::value>::type>
RIGTORP_NODISCARD bool
try_push(P &&v) noexcept(std::is_nothrow_constructible<T, P &&>::value) {
return try_emplace(std::forward<P>(v));
}
RIGTORP_NODISCARD T *front() noexcept {
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
if (readIdx == writeIdxCache_) {
writeIdxCache_ = writeIdx_.load(std::memory_order_acquire);
if (writeIdxCache_ == readIdx) {
return nullptr;
}
}
return &slots_[readIdx + kPadding];
}
void pop() noexcept {
static_assert(std::is_nothrow_destructible<T>::value,
"T must be nothrow destructible");
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
assert(writeIdx_.load(std::memory_order_acquire) != readIdx &&
"Can only call pop() after front() has returned a non-nullptr");
slots_[readIdx + kPadding].~T();
auto nextReadIdx = readIdx + 1;
if (nextReadIdx == capacity_) {
nextReadIdx = 0;
}
readIdx_.store(nextReadIdx, std::memory_order_release);
}
RIGTORP_NODISCARD size_t size() const noexcept {
std::ptrdiff_t diff = writeIdx_.load(std::memory_order_acquire) -
readIdx_.load(std::memory_order_acquire);
if (diff < 0) {
diff += capacity_;
}
return static_cast<size_t>(diff);
}
RIGTORP_NODISCARD bool empty() const noexcept {
return writeIdx_.load(std::memory_order_acquire) ==
readIdx_.load(std::memory_order_acquire);
}
RIGTORP_NODISCARD size_t capacity() const noexcept { return capacity_ - 1; }
private:
#ifdef __cpp_lib_hardware_interference_size
static constexpr size_t kCacheLineSize =
std::hardware_destructive_interference_size;
#else
static constexpr size_t kCacheLineSize = 64;
#endif
// Padding to avoid false sharing between slots_ and adjacent allocations
static constexpr size_t kPadding = (kCacheLineSize - 1) / sizeof(T) + 1;
private:
size_t capacity_;
T *slots_;
#if defined(__has_cpp_attribute) && __has_cpp_attribute(no_unique_address)
Allocator allocator_ [[no_unique_address]];
#else
Allocator allocator_;
#endif
// Align to cache line size in order to avoid false sharing
// readIdxCache_ and writeIdxCache_ is used to reduce the amount of cache
// coherency traffic
alignas(kCacheLineSize) std::atomic<size_t> writeIdx_ = {0};
alignas(kCacheLineSize) size_t readIdxCache_ = 0;
alignas(kCacheLineSize) std::atomic<size_t> readIdx_ = {0};
alignas(kCacheLineSize) size_t writeIdxCache_ = 0;
};
} // namespace rigtorp

21
ext/backward/LICENSE.txt Normal file
View file

@ -0,0 +1,21 @@
Copyright 2013 Google Inc. All Rights Reserved.
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

42
ext/backward/backward.cpp Normal file
View file

@ -0,0 +1,42 @@
// Pick your poison.
//
// On GNU/Linux, you have few choices to get the most out of your stack trace.
//
// By default you get:
// - object filename
// - function name
//
// In order to add:
// - source filename
// - line and column numbers
// - source code snippet (assuming the file is accessible)
// Install one of the following libraries then uncomment one of the macro (or
// better, add the detection of the lib and the macro definition in your build
// system)
// - apt-get install libdw-dev ...
// - g++/clang++ -ldw ...
// #define BACKWARD_HAS_DW 1
// - apt-get install binutils-dev ...
// - g++/clang++ -lbfd ...
// #define BACKWARD_HAS_BFD 1
// - apt-get install libdwarf-dev ...
// - g++/clang++ -ldwarf ...
// #define BACKWARD_HAS_DWARF 1
// Regardless of the library you choose to read the debug information,
// for potentially more detailed stack traces you can use libunwind
// - apt-get install libunwind-dev
// - g++/clang++ -lunwind
// #define BACKWARD_HAS_LIBUNWIND 1
#include "backward.hpp"
namespace backward {
backward::SignalHandling sh;
} // namespace backward

4514
ext/backward/backward.hpp Normal file

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more