Compare commits

..

1 Commits

Author SHA1 Message Date
David Markowitz
79bc6e73ff crash and log fix 2024-01-02 18:21:33 -08:00
388 changed files with 4859 additions and 5219 deletions

View File

@@ -3,8 +3,8 @@ Dockerfile
*.md *.md
logo.png logo.png
versions.txt versions.txt
build.sh
docker-compose.yml docker-compose.yml
.env .env
docker/__pycache__ docker/__pycache__
.env.example .env.example
build

View File

@@ -1,7 +1,9 @@
# Full path to the LEGO Universe client # Full path to the LEGO Universe client
CLIENT_PATH=./client CLIENT_PATH=/Users/someuser/LEGO Universe
# Can improve build time
BUILD_THREADS=1
# Updates NET_VERSION in CMakeVariables.txt # Updates NET_VERSION in CMakeVariables.txt
NET_VERSION=171022 BUILD_VERSION=171022
# make sure this is a long random string # make sure this is a long random string
# grab a "SHA 256-bit Key" from here: https://keygen.io/ # grab a "SHA 256-bit Key" from here: https://keygen.io/
ACCOUNT_MANAGER_SECRET= ACCOUNT_MANAGER_SECRET=
@@ -10,5 +12,6 @@ EXTERNAL_IP=localhost
# Database values # Database values
# Be careful with special characters here. It is more safe to use normal characters and/or numbers. # Be careful with special characters here. It is more safe to use normal characters and/or numbers.
MARIADB_USER=darkflame MARIADB_USER=darkflame
MARIADB_PASSWORD= MARIADB_PASSWORD=SECRET_VALUE_CHANGE_ME
MARIADB_ROOT_PASSWORD=SECRET_VALUE_CHANGE_ME
MARIADB_DATABASE=darkflame MARIADB_DATABASE=darkflame

View File

@@ -1,56 +0,0 @@
name: CI
on:
push:
branches:
- "main"
tags:
- "v*.*.*"
pull_request:
branches:
- "main"
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=pr
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -13,7 +13,7 @@ jobs:
continue-on-error: true continue-on-error: true
strategy: strategy:
matrix: matrix:
os: [ windows-2022, ubuntu-22.04, macos-13 ] os: [ windows-2022, ubuntu-20.04, macos-11 ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -25,11 +25,9 @@ jobs:
with: with:
vs-version: '[17,18)' vs-version: '[17,18)'
msbuild-architecture: x64 msbuild-architecture: x64
- name: Install libssl and switch to XCode 15.2 (Mac Only) - name: Install libssl (Mac Only)
if: ${{ matrix.os == 'macos-13' }} if: ${{ matrix.os == 'macos-11' }}
run: | run: brew install openssl@3
brew install openssl@3
sudo xcode-select -s /Applications/Xcode_15.2.app/Contents/Developer
- name: cmake - name: cmake
uses: lukka/run-cmake@v10 uses: lukka/run-cmake@v10
with: with:

3
.gitmodules vendored
View File

@@ -14,6 +14,9 @@
path = thirdparty/mariadb-connector-cpp path = thirdparty/mariadb-connector-cpp
url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git
ignore = dirty ignore = dirty
[submodule "thirdparty/AccountManager"]
path = thirdparty/AccountManager
url = https://github.com/DarkflameUniverse/AccountManager
[submodule "thirdparty/magic_enum"] [submodule "thirdparty/magic_enum"]
path = thirdparty/magic_enum path = thirdparty/magic_enum
url = https://github.com/Neargye/magic_enum.git url = https://github.com/Neargye/magic_enum.git

View File

@@ -3,7 +3,6 @@ project(Darkflame)
include(CTest) include(CTest)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CXX_STANDARD_REQUIRED ON)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# Read variables from file # Read variables from file
@@ -52,7 +51,7 @@ set(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "" FORCE)
# Disabled no-register # Disabled no-register
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas. # Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
if(UNIX) if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wuninitialized -fPIC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -fPIC")
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0 _GLIBCXX_USE_CXX17_ABI=0) add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0 _GLIBCXX_USE_CXX17_ABI=0)
if(NOT APPLE) if(NOT APPLE)
@@ -101,9 +100,6 @@ set(RESOURCE_FILES "sharedconfig.ini" "authconfig.ini" "chatconfig.ini" "worldco
message(STATUS "Checking resource file integrity") message(STATUS "Checking resource file integrity")
include(Utils) include(Utils)
UpdateConfigOption(${PROJECT_BINARY_DIR}/authconfig.ini "port" "auth_server_port")
UpdateConfigOption(${PROJECT_BINARY_DIR}/chatconfig.ini "port" "chat_server_port")
UpdateConfigOption(${PROJECT_BINARY_DIR}/masterconfig.ini "port" "master_server_port")
foreach(resource_file ${RESOURCE_FILES}) foreach(resource_file ${RESOURCE_FILES})
set(file_size 0) set(file_size 0)
@@ -238,13 +234,84 @@ set(INCLUDED_DIRECTORIES
"dNet" "dNet"
"dScripts"
"dScripts/02_server"
"dScripts/ai"
"dScripts/client"
"dScripts/EquipmentScripts"
"dScripts/EquipmentTriggers"
"dScripts/zone"
"dScripts/02_server/DLU"
"dScripts/02_server/Enemy"
"dScripts/02_server/Equipment"
"dScripts/02_server/Map"
"dScripts/02_server/Minigame"
"dScripts/02_server/Objects"
"dScripts/02_server/Pets"
"dScripts/02_server/Enemy/AG"
"dScripts/02_server/Enemy/AM"
"dScripts/02_server/Enemy/FV"
"dScripts/02_server/Enemy/General"
"dScripts/02_server/Enemy/Survival"
"dScripts/02_server/Enemy/VE"
"dScripts/02_server/Enemy/Waves"
"dScripts/02_server/Map/AG"
"dScripts/02_server/Map/AG_Spider_Queen"
"dScripts/02_server/Map/AM"
"dScripts/02_server/Map/FV"
"dScripts/02_server/Map/General"
"dScripts/02_server/Map/GF"
"dScripts/02_server/Map/njhub"
"dScripts/02_server/Map/NS"
"dScripts/02_server/Map/NT"
"dScripts/02_server/Map/PR"
"dScripts/02_server/Map/Property"
"dScripts/02_server/Map/SS"
"dScripts/02_server/Map/VE"
"dScripts/02_server/Map/FV/Racing"
"dScripts/02_server/Map/General/Ninjago"
"dScripts/02_server/Map/njhub/boss_instance"
"dScripts/02_server/Map/NS/Waves"
"dScripts/02_server/Map/Property/AG_Med"
"dScripts/02_server/Map/Property/AG_Small"
"dScripts/02_server/Map/Property/NS_Med"
"dScripts/02_server/Minigame/General"
"dScripts/ai/ACT"
"dScripts/ai/AG"
"dScripts/ai/FV"
"dScripts/ai/GENERAL"
"dScripts/ai/GF"
"dScripts/ai/MINIGAME"
"dScripts/ai/MINIGAME/Objects"
"dScripts/ai/NP"
"dScripts/ai/NS"
"dScripts/ai/PETS"
"dScripts/ai/PROPERTY"
"dScripts/ai/RACING"
"dScripts/ai/SPEC"
"dScripts/ai/WILD"
"dScripts/ai/ACT/FootRace"
"dScripts/ai/MINIGAME/SG_GF"
"dScripts/ai/MINIGAME/SG_GF/SERVER"
"dScripts/ai/NS/NS_PP_01"
"dScripts/ai/NS/WH"
"dScripts/ai/PROPERTY/AG"
"dScripts/ai/RACING/OBJECTS"
"dScripts/client/ai"
"dScripts/client/ai/PR"
"dScripts/zone/AG"
"dScripts/zone/LUPs"
"dScripts/zone/PROPERTY"
"dScripts/zone/PROPERTY/FV"
"dScripts/zone/PROPERTY/GF"
"dScripts/zone/PROPERTY/NS"
"thirdparty/magic_enum/include/magic_enum" "thirdparty/magic_enum/include/magic_enum"
"thirdparty/raknet/Source" "thirdparty/raknet/Source"
"thirdparty/tinyxml2" "thirdparty/tinyxml2"
"thirdparty/recastnavigation" "thirdparty/recastnavigation"
"thirdparty/SQLite" "thirdparty/SQLite"
"thirdparty/cpplinq" "thirdparty/cpplinq"
"thirdparty/cpp-httplib"
"tests" "tests"
"tests/dCommonTests" "tests/dCommonTests"
@@ -273,9 +340,7 @@ link_directories(${PROJECT_BINARY_DIR})
# Load all of our third party directories # Load all of our third party directories
add_subdirectory(thirdparty) add_subdirectory(thirdparty)
if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
# Glob together all headers that need to be precompiled # Glob together all headers that need to be precompiled
file( file(
GLOB HEADERS_DDATABASE GLOB HEADERS_DDATABASE
@@ -317,7 +382,6 @@ add_subdirectory(dGame)
add_subdirectory(dZoneManager) add_subdirectory(dZoneManager)
add_subdirectory(dNavigation) add_subdirectory(dNavigation)
add_subdirectory(dPhysics) add_subdirectory(dPhysics)
add_subdirectory(dServer)
# Create a list of common libraries shared between all binaries # Create a list of common libraries shared between all binaries
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum") set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum")
@@ -337,6 +401,12 @@ add_subdirectory(dAuthServer)
add_subdirectory(dChatServer) add_subdirectory(dChatServer)
add_subdirectory(dMasterServer) # Add MasterServer last so it can rely on the other binaries add_subdirectory(dMasterServer) # Add MasterServer last so it can rely on the other binaries
# Add our precompiled headers
target_precompile_headers(
dGame PRIVATE
${HEADERS_DGAME}
)
target_precompile_headers( target_precompile_headers(
dZoneManager PRIVATE dZoneManager PRIVATE
${HEADERS_DZONEMANAGER} ${HEADERS_DZONEMANAGER}

View File

@@ -14,13 +14,13 @@
"generator": "Unix Makefiles" "generator": "Unix Makefiles"
}, },
{ {
"name": "ci-ubuntu-22.04", "name": "ci-ubuntu-20.04",
"displayName": "CI configure step for Ubuntu", "displayName": "CI configure step for Ubuntu",
"description": "Same as default, Used in GitHub actions workflow", "description": "Same as default, Used in GitHub actions workflow",
"inherits": "default" "inherits": "default"
}, },
{ {
"name": "ci-macos-13", "name": "ci-macos-11",
"displayName": "CI configure step for MacOS", "displayName": "CI configure step for MacOS",
"description": "Same as default, Used in GitHub actions workflow", "description": "Same as default, Used in GitHub actions workflow",
"inherits": "default" "inherits": "default"
@@ -67,15 +67,15 @@
"jobs": 2 "jobs": 2
}, },
{ {
"name": "ci-ubuntu-22.04", "name": "ci-ubuntu-20.04",
"configurePreset": "ci-ubuntu-22.04", "configurePreset": "ci-ubuntu-20.04",
"displayName": "Linux CI Build", "displayName": "Linux CI Build",
"description": "This preset is used by the CI build on linux", "description": "This preset is used by the CI build on linux",
"jobs": 2 "jobs": 2
}, },
{ {
"name": "ci-macos-13", "name": "ci-macos-11",
"configurePreset": "ci-macos-13", "configurePreset": "ci-macos-11",
"displayName": "MacOS CI Build", "displayName": "MacOS CI Build",
"description": "This preset is used by the CI build on MacOS", "description": "This preset is used by the CI build on MacOS",
"jobs": 2 "jobs": 2
@@ -83,8 +83,8 @@
], ],
"testPresets": [ "testPresets": [
{ {
"name": "ci-ubuntu-22.04", "name": "ci-ubuntu-20.04",
"configurePreset": "ci-ubuntu-22.04", "configurePreset": "ci-ubuntu-20.04",
"displayName": "CI Tests on Linux", "displayName": "CI Tests on Linux",
"description": "Runs all tests on a linux configuration", "description": "Runs all tests on a linux configuration",
"execution": { "execution": {
@@ -95,8 +95,8 @@
} }
}, },
{ {
"name": "ci-macos-13", "name": "ci-macos-11",
"configurePreset": "ci-macos-13", "configurePreset": "ci-macos-11",
"displayName": "CI Tests on MacOS", "displayName": "CI Tests on MacOS",
"description": "Runs all tests on a Mac configuration", "description": "Runs all tests on a Mac configuration",
"execution": { "execution": {

46
Docker.md Normal file
View File

@@ -0,0 +1,46 @@
# Run the Darkflame Server inside Docker
## What you need
- [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker)
- [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop)
- LEGO® Universe Client. Check the main [README](./README.md) for details on this.
## Run server inside Docker
1. Copy `.env.example` and save it as `.env` inside the root directory of this repository
2. Edit the `.env` file and add your path to the root directory of your LEGO® Universe Client after `CLIENT_PATH=`
3. Update other values in the `.env` file as needed (be sure to update passwords!)
4. Run `docker compose up -d --build`
5. Run `docker compose exec darkflame /app/MasterServer -a` and setup your admin account
6. Follow the directions [here](https://github.com/DarkflameUniverse/AccountManager) to setup regular user accounts. The server will be accessible at: `http://<EXTERNAL_IP>:5000`
7. Now you can see the output of the server with `docker compose logs -f --tail 100` or `docker compose logs -f --tail 100`. This can help you understand issues and there you can also see when the server finishes it's startup.
8. You're ready to connect your client!
**NOTE #1**: If you're running an older version of Docker, you may need to use the command `docker-compose` instead of `docker compose`.
**NOTE #2**: To stop the server simply run `docker compose down` and to restart it just run `docker compose up -d` again. No need to run all the steps above every time.
**NOTE #3**: Docker buildkit needs to be enabled. https://docs.docker.com/develop/develop-images/build_enhancements/#to-enable-buildkit-builds
**NOTE #4**: Make sure to run the following in the repo root directory after cloning so submodules are also downloaded.
```
git submodule update --init --recursive
```
**NOTE #5**: If DarkflameSetup fails due to not having cdclient.fdb, rename CDClient.fdb (in the same folder) to cdclient.fdb
## Disable brickbuildfix
If you don't need the http server running on port 80 do this:
1. Create a file with the name `docker-compose.override.yml` in the root of the repository
2. Paste this content:
```yml
services:
brickbuildfix:
profiles:
- donotstart
```
3. Now run `docker compose up -d`

58
Docker_Windows.md Normal file
View File

@@ -0,0 +1,58 @@
# Installation under Windows
## First Run
1. Navigate to the [Docker download page](https://www.docker.com/products/docker-desktop) and download docker.
![Docker Download Page](docker/images/Docker_Download_Page.png)
2. Once the file has finished downloading, run it and proceed through the installation. Make sure, "Install required Windows components for WSL 2" is checked.
![Docker Desktop Installer Configuration](docker/images/Docker_Desktop_Installer_Configuration.png)
3. If necessary, restart your computer.
4. After the restart, Docker Desktop will automatically open. If it does not, simply start it like any other program.
5. If a window "WSL 2 Installation is incomplete." pops up, follow the link and click "WSL2 Linux kernel update package for x64 machines". Run the downloaded file and once that finishes, click "Restart" in the Docker Desktop window.
![WSL 2 download](docker/images/WSL_2_download.png)
6. Wait until Docker Desktop has started. You may skip the tutorial.
7. You may want to disable "Open Docker Dashboard at startup" in _Settings_ -> _General_
![Disable Dashboard Autostart](docker/images/DD_General_Settings.png)
8. Install [Git for Windows](https://git-scm.com/download/win). During the installation, simply confirming the defaults is sufficient.
9. In the folder you wish to save the Server, right click and select "Git Bash Here".
10. Type `git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer`
11. Once the command has completed (you can see you path again and can enter commands), close the window.
12. Inside the downloaded folder, copy `.env.example` and name the copy `.env`
13. Open `.env` with Notepad by right-clicking it and selecting _Open With_ -> _More apps_ -> _Notepad_.
14. Change the text after `CLIENT_PATH=` to the location of your client. This folder must contain either a folder `client` or `legouniverse.exe`.
> If you need the extra performance, place the client files in `\\wsl$\<your linux OS>\...` to avoid working across file systems, see [Docker Best Practices](https://docs.docker.com/desktop/windows/wsl/#best-practices) and [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/filesystems#file-storage-and-performance-across-file-systems).
15. Optionally, you can change the number after `BUILD_THREADS=` to the number of cores / threads your processor has. If your computer crashes while building, you can try to reduce this value.
16. After `ACCOUNT_MANAGER_SECRET=` paste a "SHA 256-bit Key" from https://keygen.io/
17. If you are not only hosting a local server, change the value after `EXTERNAL_IP=` to the external IP address of your computer.
18. Change the two values `SECRET_VALUE_CHANGE_ME` to passwords only you know. Save and close the file.
19. In the extracted folder hit Shift+Right Click and select "Open PowerShell window here".
![Open PowerShell](docker/images/Open_Powershell.png)
17. In the new window, paste (with right click) or type `docker compose up -d --build` and confirm with enter.
18. Once you see the blinking cursor and the path again, setup has finished and the server is already running.
![setup done](docker/images/setup_finished.png)
19. Create an admin account by pasting `docker compose exec darkflame /app/MasterServer -a` and following the prompts.
![admin account creation](docker/images/Account_Creation.png)
20. You can now login with these credentials at `http://your_ip:5000` (replace your_ip with your external IP). There you can create your account for playing as well as generate keys for other people to join; use these at `http://your_ip:5000/activate`
## Normal Use
1. In Docker Desktop you should now see an entry `darkflameserver-main` and when you click on it all containers but `DarkflameSetup` should eventually be green. That means the server is running.
![server running](docker/images/Docker_Compose_Finished.png)
2. For troubleshooting, you can check the logs of the various parts by clicking their entry.
3. You can start and stop the server with the corresponding buttons. Once all containers are grey, the server has shut down, and when all containers but `DarkflameSetup` are green, the server is running. Note that starting and stopping takes some time, please be patient.
![start stop buttons](docker/images/DD_Server_Startstop.png)

View File

@@ -1,51 +0,0 @@
FROM gcc:12 as build
WORKDIR /app
RUN set -ex; \
apt-get update; \
apt-get install -y cmake
COPY . /app/
COPY --chmod=0500 ./build.sh /app/
RUN sed -i 's/MARIADB_CONNECTOR_COMPILE_JOBS__=.*/MARIADB_CONNECTOR_COMPILE_JOBS__=2/' /app/CMakeVariables.txt
RUN ./build.sh
FROM debian:12 as runtime
WORKDIR /app
RUN --mount=type=cache,id=build-apt-cache,target=/var/cache/apt \
apt update && \
apt install -y libssl3 libcurl4 && \
rm -rf /var/lib/apt/lists/*
# Grab libraries and load them
COPY --from=build /app/build/mariadbcpp/src/mariadb_connector_cpp-build/libmariadbcpp.so /usr/local/lib/
COPY --from=build /app/build/mariadbcpp/src/mariadb_connector_cpp-build/libmariadb/libmariadb/libmariadb.so.3 /usr/local/lib
RUN ldconfig
# Server bins
COPY --from=build /app/build/*Server /app/
# Necessary suplimentary files
COPY --from=build /app/build/*.ini /app/configs/
COPY --from=build /app/build/vanity/*.* /app/vanity/*
COPY --from=build /app/build/navmeshes /app/navmeshes
COPY --from=build /app/build/migrations /app/migrations
COPY --from=build /app/build/*.dcf /app/
# backup of config and vanity files to copy to the host incase
# of a mount clobbering the copy from above
COPY --from=build /app/build/*.ini /app/default-configs/
COPY --from=build /app/build/vanity/*.* /app/default-vanity/*
# needed as the container runs with the root user
# and therefore sudo doesn't exist
ENV USE_SUDO_AUTH=0
ENV DLU_CONFIG_DIR=/app/configs/
COPY --chmod=0500 ./entrypoint.sh /app/
ENTRYPOINT [ "/app/entrypoint.sh" ]

View File

@@ -37,7 +37,6 @@ If you would like a setup for a single player server only on a Windows machine,
* [Verify your setup](#verify-your-setup) * [Verify your setup](#verify-your-setup)
* [Running the server](#running-the-server) * [Running the server](#running-the-server)
* [User Guide](#user-guide) * [User Guide](#user-guide)
* [Docker](#docker)
## Clone the repository ## Clone the repository
If you are on Windows, you will need to download and install git from [here](https://git-scm.com/download/win) If you are on Windows, you will need to download and install git from [here](https://git-scm.com/download/win)
@@ -348,66 +347,6 @@ certutil -hashfile <file> SHA1
Known good *SHA1* checksum of the Darkflame Universe client: Known good *SHA1* checksum of the Darkflame Universe client:
- `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed) - `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed)
# Docker
The Darkflame Server is automatically built and published as a Docker Container / [OCI](https://opencontainers.org/) Image to the GitHub Container Registry at:
[`ghcr.io/darkflameuniverse/darkflameserver`](https://github.com/DarkflameUniverse/DarkflameServer/pkgs/container/darkflameserver).
## Compose
> [!WARNING]
> It seems that Docker Desktop on Windows with the WSL 2 backend has some issues with MariaDB (c.f. [mariadb-docker#331](https://github.com/MariaDB/mariadb-docker/issues/331)) triggered by NexusDashboard
> migrations, so this setup may not work for you. If that is the case, please tell us about your setup in [NexusDashboard#92](https://github.com/DarkflameUniverse/NexusDashboard/issues/92).
You can use the `docker-compose` tool to [setup a MariaDB database](#database-setup), run the Darkflame Server and manage it with [Nexus Dashboard](https://github.com/DarkflameUniverse/NexusDashboard) all
at once. For that:
- [Install Docker Desktop](https://docs.docker.com/get-docker/)
- Open the directory that contains your LU Client
- If the `legouniverse.exe` is in a subfolder called `client`, you're good to go. There may also be a folder `versions`.
- Otherwise, create a new `client` folder and move the exe and everything else (e.g. `res` and `locale`) in there. This is necessary to work around a bug in the client that will prevent that you to log back in after getting disconnected.
- Download the [docker-compose.yml](docker-compose.yml) file and place it next to `client`.
- Download the [.env.example](.env.example) file and place it next to `client` with the file name `.env`
- You may get warnings that this name starts with a dot, acknowledge those, this is intentional. Depending on your operating system, you may need to activate showing hidden files (e.g. Ctrl-H in Gnome on Linux) and/or file extensions ("File name extensions" in the "View" tab on Windows).
- Update the `ACCOUNT_MANAGER_SECRET` and `MARIADB_PASSWORD` with strong random passwords.
- Use a password generator like <https://keygen.io>
- Avoid `:` and `@` characters
- Once the database user is created, changing the password will not update it, so the server will just fail to connect.
- Set `EXTERNAL_IP` to your LAN IP or public IP if you want to host the game for friends & family
- Open a terminal in the folder with the `docker-compose.yml` and `client`
- Run `docker compose up -d`
- This might require `sudo` on Linux, and a recent version of [docker compose](https://docs.docker.com/compose/install/)
- Run `docker exec -it dlu-darkflameserver-1 /app/MasterServer -a` and follow the instructions to create the initial admin account
- Open <http://localhost:8000> to access Nexus Dashboard with the admin account to create normal users
- Set `AUTHSERVERIP=0:localhost` in `client/boot.cfg`
- Replace `localhost` with the value of `EXTERNAL_IP` if you changed that earlier.
- Also make sure `UGCUSE3DSERVICES=7:` is set to `0`
- Launch `legouniverse.exe`
## Standalone
This assumes that you have a database deployed to your host or in another docker container.
A basic deployment of this contianer would look like:
```sh
# example docker contianer deployment
docker run -it \
-v /path/to/configs/:/app/configs \
-v /path/to/logs/:/app/logs \
-v /path/to/dumps/:/app/dumps \
-v /path/to/res:/app/res:ro \
-v /path/to/resServer:/app/resServer \
-e DUMP_FOLDER=/app/dumps \
-p 1001:1001/udp \
-p 2005:2005/udp \
-p 3000-3300:3000-3300/udp \
ghcr.io/darkflameuniverse/darkflameserver:latest
```
You will need to replace the `/path/to/`'s to reflect the paths on your host.
Any config option in the `.ini`'s can be overridden with environmental variables: Ex: `log_to_console=1` from `shared_config.ini` would be overidden like `-e LOG_TO_CONSOLE=0`
# Development Documentation # Development Documentation
This is a Work in Progress, but below are some quick links to documentaion for systems and structs in the server This is a Work in Progress, but below are some quick links to documentaion for systems and structs in the server
[Networked message structs](https://lcdruniverse.org/lu_packets/lu_packets/index.html) [Networked message structs](https://lcdruniverse.org/lu_packets/lu_packets/index.html)

View File

@@ -7,10 +7,6 @@ function(UpdateConfigOption file_name old_option_name new_option_name)
string(APPEND old_option_name "=") string(APPEND old_option_name "=")
string(APPEND new_option_name "=") string(APPEND new_option_name "=")
message(STATUS "Checking " ${file_name} " for " ${old_option_name} " and adding " ${new_option_name} " if it does not exist") message(STATUS "Checking " ${file_name} " for " ${old_option_name} " and adding " ${new_option_name} " if it does not exist")
if(NOT EXISTS ${file_name})
message(STATUS ${file_name} " does not exist. Doing nothing")
return()
endif()
file(READ ${file_name} current_file_contents) file(READ ${file_name} current_file_contents)
string(REPLACE "\\\n" "" current_file_contents ${current_file_contents}) string(REPLACE "\\\n" "" current_file_contents ${current_file_contents})
string(REPLACE "\n" ";" current_file_contents ${current_file_contents}) string(REPLACE "\n" ";" current_file_contents ${current_file_contents})

View File

@@ -16,7 +16,7 @@
//RakNet includes: //RakNet includes:
#include "RakNetDefines.h" #include "RakNetDefines.h"
#include "MessageIdentifiers.h" #include <MessageIdentifiers.h>
//Auth includes: //Auth includes:
#include "AuthPackets.h" #include "AuthPackets.h"
@@ -25,9 +25,6 @@
#include "eAuthMessageType.h" #include "eAuthMessageType.h"
#include "Game.h" #include "Game.h"
#include "Server.h"
namespace Game { namespace Game {
Logger* logger = nullptr; Logger* logger = nullptr;
dServer* server = nullptr; dServer* server = nullptr;
@@ -36,6 +33,7 @@ namespace Game {
std::mt19937 randomEngine; std::mt19937 randomEngine;
} }
Logger* SetupLogger();
void HandlePacket(Packet* packet); void HandlePacket(Packet* packet);
int main(int argc, char** argv) { int main(int argc, char** argv) {
@@ -48,12 +46,15 @@ int main(int argc, char** argv) {
std::signal(SIGINT, Game::OnSignal); std::signal(SIGINT, Game::OnSignal);
std::signal(SIGTERM, Game::OnSignal); std::signal(SIGTERM, Game::OnSignal);
Game::config = new dConfig("authconfig.ini");
//Create all the objects we need to run our service: //Create all the objects we need to run our service:
Server::SetupLogger("AuthServer"); Game::logger = SetupLogger();
if (!Game::logger) return EXIT_FAILURE; if (!Game::logger) return EXIT_FAILURE;
//Read our config:
Game::config = new dConfig("authconfig.ini");
Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0");
Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1");
LOG("Starting Auth server..."); LOG("Starting Auth server...");
LOG("Version: %s", PROJECT_VERSION); LOG("Version: %s", PROJECT_VERSION);
LOG("Compiled on: %s", __TIMESTAMP__); LOG("Compiled on: %s", __TIMESTAMP__);
@@ -82,15 +83,12 @@ int main(int argc, char** argv) {
Game::randomEngine = std::mt19937(time(0)); Game::randomEngine = std::mt19937(time(0));
//It's safe to pass 'localhost' here, as the IP is only used as the external IP. //It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999; uint32_t maxClients = 50;
uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
std::string ourIP = "localhost"; if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients); if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
GeneralUtils::TryParse(Game::config->GetValue("auth_server_port"), ourPort);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal); Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal);
//Run it until server gets a kill message from Master: //Run it until server gets a kill message from Master:
auto t = std::chrono::high_resolution_clock::now(); auto t = std::chrono::high_resolution_clock::now();
@@ -161,6 +159,18 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Logger* SetupLogger() {
std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/AuthServer_" + std::to_string(time(nullptr)) + ".log")).string();
bool logToConsole = false;
bool logDebugStatements = false;
#ifdef _DEBUG
logToConsole = true;
logDebugStatements = true;
#endif
return new Logger(logPath, logToConsole, logDebugStatements);
}
void HandlePacket(Packet* packet) { void HandlePacket(Packet* packet) {
if (packet->length < 4) return; if (packet->length < 4) return;

View File

@@ -1,7 +1,3 @@
add_executable(AuthServer "AuthServer.cpp") add_executable(AuthServer "AuthServer.cpp")
target_link_libraries(AuthServer ${COMMON_LIBRARIES})
target_link_libraries(AuthServer ${COMMON_LIBRARIES} dServer)
target_include_directories(AuthServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer)
add_compile_definitions(AuthServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") add_compile_definitions(AuthServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"")

View File

@@ -6,9 +6,7 @@ set(DCHATSERVER_SOURCES
add_executable(ChatServer "ChatServer.cpp") add_executable(ChatServer "ChatServer.cpp")
add_library(dChatServer ${DCHATSERVER_SOURCES}) add_library(dChatServer ${DCHATSERVER_SOURCES})
target_include_directories(dChatServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer)
add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"")
target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter) target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter)
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer) target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer)

View File

@@ -2,6 +2,7 @@
#include "PlayerContainer.h" #include "PlayerContainer.h"
#include "eChatInternalMessageType.h" #include "eChatInternalMessageType.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#include "PacketUtils.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "Logger.h"
#include "eObjectBits.h" #include "eObjectBits.h"
@@ -25,15 +26,17 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
LWOOBJID playerId; LWOOBJID playerId;
inStream.Read(playerId); inStream.Read(playerId);
auto& receiver = Game::playerContainer.GetPlayerDataMutable(playerId); auto* receiver = Game::playerContainer.GetPlayerData(playerId);
if (!receiver) { if (!receiver) {
LOG("Tried to get ignore list, but player %llu not found in container", playerId); LOG("Tried to get ignore list, but player %llu not found in container", playerId);
return; return;
} }
if (!receiver.ignoredPlayers.empty()) { if (!receiver->ignoredPlayers.empty()) {
LOG_DEBUG("Player %llu already has an ignore list, but is requesting it again.", playerId); LOG_DEBUG("Player %llu already has an ignore list", playerId);
} else { return;
}
auto ignoreList = Database::Get()->GetIgnoreList(static_cast<uint32_t>(playerId)); auto ignoreList = Database::Get()->GetIgnoreList(static_cast<uint32_t>(playerId));
if (ignoreList.empty()) { if (ignoreList.empty()) {
LOG_DEBUG("Player %llu has no ignores", playerId); LOG_DEBUG("Player %llu has no ignores", playerId);
@@ -41,20 +44,19 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
} }
for (auto& ignoredPlayer : ignoreList) { for (auto& ignoredPlayer : ignoreList) {
receiver.ignoredPlayers.emplace_back(ignoredPlayer.name, ignoredPlayer.id); receiver->ignoredPlayers.push_back(IgnoreData{ ignoredPlayer.id, ignoredPlayer.name });
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::CHARACTER); GeneralUtils::SetBit(receiver->ignoredPlayers.back().playerId, eObjectBits::CHARACTER);
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::PERSISTENT); GeneralUtils::SetBit(receiver->ignoredPlayers.back().playerId, eObjectBits::PERSISTENT);
}
} }
CBITSTREAM; CBITSTREAM;
WriteOutgoingReplyHeader(bitStream, receiver.playerID, ChatIgnoreList::Response::GET_IGNORE); WriteOutgoingReplyHeader(bitStream, receiver->playerID, ChatIgnoreList::Response::GET_IGNORE);
bitStream.Write<uint8_t>(false); // Probably is Is Free Trial, but we don't care about that bitStream.Write<uint8_t>(false); // Probably is Is Free Trial, but we don't care about that
bitStream.Write<uint16_t>(0); // literally spacing due to struct alignment bitStream.Write<uint16_t>(0); // literally spacing due to struct alignment
bitStream.Write<uint16_t>(receiver.ignoredPlayers.size()); bitStream.Write<uint16_t>(receiver->ignoredPlayers.size());
for (const auto& ignoredPlayer : receiver.ignoredPlayers) { for (const auto& ignoredPlayer : receiver->ignoredPlayers) {
bitStream.Write(ignoredPlayer.playerId); bitStream.Write(ignoredPlayer.playerId);
bitStream.Write(LUWString(ignoredPlayer.playerName, 36)); bitStream.Write(LUWString(ignoredPlayer.playerName, 36));
} }
@@ -67,40 +69,40 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
LWOOBJID playerId; LWOOBJID playerId;
inStream.Read(playerId); inStream.Read(playerId);
auto& receiver = Game::playerContainer.GetPlayerDataMutable(playerId); auto* receiver = Game::playerContainer.GetPlayerData(playerId);
if (!receiver) { if (!receiver) {
LOG("Tried to get ignore list, but player %llu not found in container", playerId); LOG("Tried to get ignore list, but player %llu not found in container", playerId);
return; return;
} }
constexpr int32_t MAX_IGNORES = 32; constexpr int32_t MAX_IGNORES = 32;
if (receiver.ignoredPlayers.size() > MAX_IGNORES) { if (receiver->ignoredPlayers.size() > MAX_IGNORES) {
LOG_DEBUG("Player %llu has too many ignores", playerId); LOG_DEBUG("Player %llu has too many ignores", playerId);
return; return;
} }
inStream.IgnoreBytes(4); // ignore some garbage zeros idk inStream.IgnoreBytes(4); // ignore some garbage zeros idk
LUWString toIgnoreName; LUWString toIgnoreName(33);
inStream.Read(toIgnoreName); inStream.Read(toIgnoreName);
std::string toIgnoreStr = toIgnoreName.GetAsString(); std::string toIgnoreStr = toIgnoreName.GetAsString();
CBITSTREAM; CBITSTREAM;
WriteOutgoingReplyHeader(bitStream, receiver.playerID, ChatIgnoreList::Response::ADD_IGNORE); WriteOutgoingReplyHeader(bitStream, receiver->playerID, ChatIgnoreList::Response::ADD_IGNORE);
// Check if the player exists // Check if the player exists
LWOOBJID ignoredPlayerId = LWOOBJID_EMPTY; LWOOBJID ignoredPlayerId = LWOOBJID_EMPTY;
if (toIgnoreStr == receiver.playerName || toIgnoreStr.find("[GM]") == 0) { if (toIgnoreStr == receiver->playerName || toIgnoreStr.find("[GM]") == 0) {
LOG_DEBUG("Player %llu tried to ignore themselves", playerId); LOG_DEBUG("Player %llu tried to ignore themselves", playerId);
bitStream.Write(ChatIgnoreList::AddResponse::GENERAL_ERROR); bitStream.Write(ChatIgnoreList::AddResponse::GENERAL_ERROR);
} else if (std::count(receiver.ignoredPlayers.begin(), receiver.ignoredPlayers.end(), toIgnoreStr) > 0) { } else if (std::count(receiver->ignoredPlayers.begin(), receiver->ignoredPlayers.end(), toIgnoreStr) > 0) {
LOG_DEBUG("Player %llu is already ignoring %s", playerId, toIgnoreStr.c_str()); LOG_DEBUG("Player %llu is already ignoring %s", playerId, toIgnoreStr.c_str());
bitStream.Write(ChatIgnoreList::AddResponse::ALREADY_IGNORED); bitStream.Write(ChatIgnoreList::AddResponse::ALREADY_IGNORED);
} else { } else {
// Get the playerId falling back to query if not online // Get the playerId falling back to query if not online
const auto& playerData = Game::playerContainer.GetPlayerData(toIgnoreStr); auto* playerData = Game::playerContainer.GetPlayerData(toIgnoreStr);
if (!playerData) { if (!playerData) {
// Fall back to query // Fall back to query
auto player = Database::Get()->GetCharacterInfo(toIgnoreStr); auto player = Database::Get()->GetCharacterInfo(toIgnoreStr);
@@ -110,7 +112,7 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
ignoredPlayerId = player->id; ignoredPlayerId = player->id;
} }
} else { } else {
ignoredPlayerId = playerData.playerID; ignoredPlayerId = playerData->playerID;
} }
if (ignoredPlayerId != LWOOBJID_EMPTY) { if (ignoredPlayerId != LWOOBJID_EMPTY) {
@@ -118,7 +120,7 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::CHARACTER); GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::CHARACTER);
GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::PERSISTENT); GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::PERSISTENT);
receiver.ignoredPlayers.emplace_back(toIgnoreStr, ignoredPlayerId); receiver->ignoredPlayers.push_back(IgnoreData{ ignoredPlayerId, toIgnoreStr });
LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str()); LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str());
bitStream.Write(ChatIgnoreList::AddResponse::SUCCESS); bitStream.Write(ChatIgnoreList::AddResponse::SUCCESS);
@@ -139,7 +141,7 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
LWOOBJID playerId; LWOOBJID playerId;
inStream.Read(playerId); inStream.Read(playerId);
auto& receiver = Game::playerContainer.GetPlayerDataMutable(playerId); auto* receiver = Game::playerContainer.GetPlayerData(playerId);
if (!receiver) { if (!receiver) {
LOG("Tried to get ignore list, but player %llu not found in container", playerId); LOG("Tried to get ignore list, but player %llu not found in container", playerId);
return; return;
@@ -147,21 +149,21 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
inStream.IgnoreBytes(4); // ignore some garbage zeros idk inStream.IgnoreBytes(4); // ignore some garbage zeros idk
LUWString removedIgnoreName; LUWString removedIgnoreName(33);
inStream.Read(removedIgnoreName); inStream.Read(removedIgnoreName);
std::string removedIgnoreStr = removedIgnoreName.GetAsString(); std::string removedIgnoreStr = removedIgnoreName.GetAsString();
auto toRemove = std::remove(receiver.ignoredPlayers.begin(), receiver.ignoredPlayers.end(), removedIgnoreStr); auto toRemove = std::remove(receiver->ignoredPlayers.begin(), receiver->ignoredPlayers.end(), removedIgnoreStr);
if (toRemove == receiver.ignoredPlayers.end()) { if (toRemove == receiver->ignoredPlayers.end()) {
LOG_DEBUG("Player %llu is not ignoring %s", playerId, removedIgnoreStr.c_str()); LOG_DEBUG("Player %llu is not ignoring %s", playerId, removedIgnoreStr.c_str());
return; return;
} }
Database::Get()->RemoveIgnore(static_cast<uint32_t>(playerId), static_cast<uint32_t>(toRemove->playerId)); Database::Get()->RemoveIgnore(static_cast<uint32_t>(playerId), static_cast<uint32_t>(toRemove->playerId));
receiver.ignoredPlayers.erase(toRemove, receiver.ignoredPlayers.end()); receiver->ignoredPlayers.erase(toRemove, receiver->ignoredPlayers.end());
CBITSTREAM; CBITSTREAM;
WriteOutgoingReplyHeader(bitStream, receiver.playerID, ChatIgnoreList::Response::REMOVE_IGNORE); WriteOutgoingReplyHeader(bitStream, receiver->playerID, ChatIgnoreList::Response::REMOVE_IGNORE);
bitStream.Write<int8_t>(0); bitStream.Write<int8_t>(0);
LUWString playerNameSend(removedIgnoreStr, 33); LUWString playerNameSend(removedIgnoreStr, 33);

File diff suppressed because it is too large Load Diff

View File

@@ -4,56 +4,16 @@
#include "BitStream.h" #include "BitStream.h"
struct PlayerData; struct PlayerData;
enum class eAddFriendResponseType : uint8_t; enum class eAddFriendResponseType : uint8_t;
enum class eChatChannel : uint8_t {
SYSTEMNOTIFY = 0,
SYSTEMWARNING,
SYSTEMERROR,
BROADCAST,
LOCAL,
LOCALNOANIM,
EMOTE,
PRIVATE_CHAT,
TEAM,
TEAMLOCAL,
GUILD,
GUILDNOTIFY,
PROPERTY,
ADMIN,
COMBATDAMAGE,
COMBATHEALING,
COMBATLOOT,
COMBATEXP,
COMBATDEATH,
GENERAL,
TRADE,
LFG,
USER
};
enum class eChatMessageResponseCode : uint8_t {
SENT = 0,
NOTONLINE,
GENERALERROR,
RECEIVEDNEWWHISPER,
NOTFRIENDS,
SENDERFREETRIAL,
RECEIVERFREETRIAL,
};
namespace ChatPacketHandler { namespace ChatPacketHandler {
void HandleFriendlistRequest(Packet* packet); void HandleFriendlistRequest(Packet* packet);
void HandleFriendRequest(Packet* packet); void HandleFriendRequest(Packet* packet);
void HandleFriendResponse(Packet* packet); void HandleFriendResponse(Packet* packet);
void HandleRemoveFriend(Packet* packet); void HandleRemoveFriend(Packet* packet);
void HandleGMLevelUpdate(Packet* packet);
void HandleChatMessage(Packet* packet); void HandleChatMessage(Packet* packet);
void HandlePrivateChatMessage(Packet* packet); void HandlePrivateChatMessage(Packet* packet);
void SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode);
void HandleTeamInvite(Packet* packet); void HandleTeamInvite(Packet* packet);
void HandleTeamInviteResponse(Packet* packet); void HandleTeamInviteResponse(Packet* packet);
@@ -63,18 +23,18 @@ namespace ChatPacketHandler {
void HandleTeamLootOption(Packet* packet); void HandleTeamLootOption(Packet* packet);
void HandleTeamStatusRequest(Packet* packet); void HandleTeamStatusRequest(Packet* packet);
void SendTeamInvite(const PlayerData& receiver, const PlayerData& sender); void SendTeamInvite(PlayerData* receiver, PlayerData* sender);
void SendTeamInviteConfirm(const PlayerData& receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName); void SendTeamInviteConfirm(PlayerData* receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName);
void SendTeamStatus(const PlayerData& receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName); void SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName);
void SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID); void SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64PlayerID);
void SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID); void SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID);
void SendTeamRemovePlayer(const PlayerData& receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName); void SendTeamRemovePlayer(PlayerData* receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName);
void SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID); void SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID);
//FriendData is the player we're SENDING this stuff to. Player is the friend that changed state. //FriendData is the player we're SENDING this stuff to. Player is the friend that changed state.
void SendFriendUpdate(const PlayerData& friendData, const PlayerData& playerData, uint8_t notifyType, uint8_t isBestFriend); void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend);
void SendFriendRequest(const PlayerData& receiver, const PlayerData& sender); void SendFriendRequest(PlayerData* receiver, PlayerData* sender);
void SendFriendResponse(const PlayerData& receiver, const PlayerData& sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U); void SendFriendResponse(PlayerData* receiver, PlayerData* sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U);
void SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful); void SendRemoveFriend(PlayerData* receiver, std::string& personToRemove, bool isSuccessful);
}; };

View File

@@ -20,14 +20,12 @@
#include "eChatInternalMessageType.h" #include "eChatInternalMessageType.h"
#include "eWorldMessageType.h" #include "eWorldMessageType.h"
#include "ChatIgnoreList.h" #include "ChatIgnoreList.h"
#include "StringifiedEnum.h"
#include "Game.h" #include "Game.h"
#include "Server.h"
//RakNet includes: //RakNet includes:
#include "RakNetDefines.h" #include "RakNetDefines.h"
#include "MessageIdentifiers.h" #include <MessageIdentifiers.h>
namespace Game { namespace Game {
Logger* logger = nullptr; Logger* logger = nullptr;
@@ -40,6 +38,7 @@ namespace Game {
PlayerContainer playerContainer; PlayerContainer playerContainer;
} }
Logger* SetupLogger();
void HandlePacket(Packet* packet); void HandlePacket(Packet* packet);
int main(int argc, char** argv) { int main(int argc, char** argv) {
@@ -52,13 +51,14 @@ int main(int argc, char** argv) {
std::signal(SIGINT, Game::OnSignal); std::signal(SIGINT, Game::OnSignal);
std::signal(SIGTERM, Game::OnSignal); std::signal(SIGTERM, Game::OnSignal);
Game::config = new dConfig("chatconfig.ini");
//Create all the objects we need to run our service: //Create all the objects we need to run our service:
Server::SetupLogger("ChatServer"); Game::logger = SetupLogger();
if (!Game::logger) return EXIT_FAILURE; if (!Game::logger) return EXIT_FAILURE;
//Read our config: //Read our config:
Game::config = new dConfig("chatconfig.ini");
Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0");
Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1");
LOG("Starting Chat server..."); LOG("Starting Chat server...");
LOG("Version: %s", PROJECT_VERSION); LOG("Version: %s", PROJECT_VERSION);
@@ -99,19 +99,14 @@ int main(int argc, char** argv) {
masterPort = masterInfo->port; masterPort = masterInfo->port;
} }
//It's safe to pass 'localhost' here, as the IP is only used as the external IP. //It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999; uint32_t maxClients = 50;
uint32_t ourPort = 1501; uint32_t ourPort = 1501;
std::string ourIP = "localhost"; if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients); if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
GeneralUtils::TryParse(Game::config->GetValue("chat_server_port"), ourPort);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal); Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal);
bool dontGenerateDCF = false; Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf"))));
GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf"), dontGenerateDCF);
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF);
Game::randomEngine = std::mt19937(time(0)); Game::randomEngine = std::mt19937(time(0));
@@ -182,6 +177,18 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Logger* SetupLogger() {
std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/ChatServer_" + std::to_string(time(nullptr)) + ".log")).string();
bool logToConsole = false;
bool logDebugStatements = false;
#ifdef _DEBUG
logToConsole = true;
logDebugStatements = true;
#endif
return new Logger(logPath, logToConsole, logDebugStatements);
}
void HandlePacket(Packet* packet) { void HandlePacket(Packet* packet) {
if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) {
LOG("A server has disconnected, erasing their connected players from the list."); LOG("A server has disconnected, erasing their connected players from the list.");
@@ -224,8 +231,7 @@ void HandlePacket(Packet* packet) {
} }
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::CHAT) { if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::CHAT) {
eChatMessageType chat_message_type = static_cast<eChatMessageType>(packet->data[3]); switch (static_cast<eChatMessageType>(packet->data[3])) {
switch (chat_message_type) {
case eChatMessageType::GET_FRIENDS_LIST: case eChatMessageType::GET_FRIENDS_LIST:
ChatPacketHandler::HandleFriendlistRequest(packet); ChatPacketHandler::HandleFriendlistRequest(packet);
break; break;
@@ -295,61 +301,9 @@ void HandlePacket(Packet* packet) {
case eChatMessageType::TEAM_SET_LOOT: case eChatMessageType::TEAM_SET_LOOT:
ChatPacketHandler::HandleTeamLootOption(packet); ChatPacketHandler::HandleTeamLootOption(packet);
break; break;
case eChatMessageType::GMLEVEL_UPDATE:
ChatPacketHandler::HandleGMLevelUpdate(packet);
break;
case eChatMessageType::LOGIN_SESSION_NOTIFY:
case eChatMessageType::USER_CHANNEL_CHAT_MESSAGE:
case eChatMessageType::WORLD_DISCONNECT_REQUEST:
case eChatMessageType::WORLD_PROXIMITY_RESPONSE:
case eChatMessageType::WORLD_PARCEL_RESPONSE:
case eChatMessageType::TEAM_MISSED_INVITE_CHECK:
case eChatMessageType::GUILD_CREATE:
case eChatMessageType::GUILD_INVITE:
case eChatMessageType::GUILD_INVITE_RESPONSE:
case eChatMessageType::GUILD_LEAVE:
case eChatMessageType::GUILD_KICK:
case eChatMessageType::GUILD_GET_STATUS:
case eChatMessageType::GUILD_GET_ALL:
case eChatMessageType::SHOW_ALL:
case eChatMessageType::BLUEPRINT_MODERATED:
case eChatMessageType::BLUEPRINT_MODEL_READY:
case eChatMessageType::PROPERTY_READY_FOR_APPROVAL:
case eChatMessageType::PROPERTY_MODERATION_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED_REPORT:
case eChatMessageType::MAIL:
case eChatMessageType::WORLD_INSTANCE_LOCATION_REQUEST:
case eChatMessageType::REPUTATION_UPDATE:
case eChatMessageType::SEND_CANNED_TEXT:
case eChatMessageType::CHARACTER_NAME_CHANGE_REQUEST:
case eChatMessageType::CSR_REQUEST:
case eChatMessageType::CSR_REPLY:
case eChatMessageType::GM_KICK:
case eChatMessageType::GM_ANNOUNCE:
case eChatMessageType::WORLD_ROUTE_PACKET:
case eChatMessageType::GET_ZONE_POPULATIONS:
case eChatMessageType::REQUEST_MINIMUM_CHAT_MODE:
case eChatMessageType::MATCH_REQUEST:
case eChatMessageType::UGCMANIFEST_REPORT_MISSING_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_BLUEPRINT:
case eChatMessageType::UGCC_REQUEST:
case eChatMessageType::WHO:
case eChatMessageType::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE:
case eChatMessageType::ACHIEVEMENT_NOTIFY:
case eChatMessageType::GM_CLOSE_PRIVATE_CHAT_WINDOW:
case eChatMessageType::UNEXPECTED_DISCONNECT:
case eChatMessageType::PLAYER_READY:
case eChatMessageType::GET_DONATION_TOTAL:
case eChatMessageType::UPDATE_DONATION:
case eChatMessageType::PRG_CSR_COMMAND:
case eChatMessageType::HEARTBEAT_REQUEST_FROM_WORLD:
case eChatMessageType::UPDATE_FREE_TRIAL_STATUS:
LOG("Unhandled CHAT Message id: %s (%i)", StringifiedEnum::ToString(chat_message_type).data(), chat_message_type);
break;
default: default:
LOG("Unknown CHAT Message id: %i", chat_message_type); LOG("Unknown CHAT id: %i", int(packet->data[3]));
} }
} }

View File

@@ -10,7 +10,6 @@
#include "Database.h" #include "Database.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eChatInternalMessageType.h" #include "eChatInternalMessageType.h"
#include "eGameMasterLevel.h"
#include "ChatPackets.h" #include "ChatPackets.h"
#include "dConfig.h" #include "dConfig.h"
@@ -23,43 +22,33 @@ PlayerContainer::~PlayerContainer() {
m_Players.clear(); m_Players.clear();
} }
PlayerData::PlayerData() {
gmLevel = eGameMasterLevel::CIVILIAN;
}
TeamData::TeamData() { TeamData::TeamData() {
lootFlag = Game::config->GetValue("default_team_loot") == "0" ? 0 : 1; lootFlag = Game::config->GetValue("default_team_loot") == "0" ? 0 : 1;
} }
void PlayerContainer::InsertPlayer(Packet* packet) { void PlayerContainer::InsertPlayer(Packet* packet) {
CINSTREAM_SKIP_HEADER; CINSTREAM_SKIP_HEADER;
LWOOBJID playerId; PlayerData* data = new PlayerData();
if (!inStream.Read(playerId)) { inStream.Read(data->playerID);
LOG("Failed to read player ID");
return;
}
auto& data = m_Players[playerId];
data.playerID = playerId;
uint32_t len; uint32_t len;
inStream.Read<uint32_t>(len); inStream.Read<uint32_t>(len);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
char character; inStream.Read<char>(character); char character; inStream.Read<char>(character);
data.playerName += character; data->playerName += character;
} }
inStream.Read(data.zoneID); inStream.Read(data->zoneID);
inStream.Read(data.muteExpire); inStream.Read(data->muteExpire);
inStream.Read(data.gmLevel); data->sysAddr = packet->systemAddress;
data.sysAddr = packet->systemAddress;
m_Names[data.playerID] = GeneralUtils::UTF8ToUTF16(data.playerName); m_Names[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName);
LOG("Added user: %s (%llu), zone: %i", data.playerName.c_str(), data.playerID, data.zoneID.GetMapID()); m_Players.insert(std::make_pair(data->playerID, data));
LOG("Added user: %s (%llu), zone: %i", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID());
Database::Get()->UpdateActivityLog(data.playerID, eActivityType::PlayerLoggedIn, data.zoneID.GetMapID()); Database::Get()->UpdateActivityLog(data->playerID, eActivityType::PlayerLoggedIn, data->zoneID.GetMapID());
} }
void PlayerContainer::RemovePlayer(Packet* packet) { void PlayerContainer::RemovePlayer(Packet* packet) {
@@ -68,27 +57,26 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
inStream.Read(playerID); inStream.Read(playerID);
//Before they get kicked, we need to also send a message to their friends saying that they disconnected. //Before they get kicked, we need to also send a message to their friends saying that they disconnected.
const auto& player = GetPlayerData(playerID); std::unique_ptr<PlayerData> player(this->GetPlayerData(playerID));
if (!player) { if (player == nullptr) {
LOG("Failed to find user: %llu", playerID);
return; return;
} }
for (const auto& fr : player.friends) { for (auto& fr : player->friends) {
const auto& fd = this->GetPlayerData(fr.friendID); auto fd = this->GetPlayerData(fr.friendID);
if (fd) ChatPacketHandler::SendFriendUpdate(fd, player, 0, fr.isBestFriend); if (fd) ChatPacketHandler::SendFriendUpdate(fd, player.get(), 0, fr.isBestFriend);
} }
auto* team = GetTeam(playerID); auto* team = GetTeam(playerID);
if (team != nullptr) { if (team != nullptr) {
const auto memberName = GeneralUtils::UTF8ToUTF16(player.playerName); const auto memberName = GeneralUtils::UTF8ToUTF16(std::string(player->playerName.c_str()));
for (const auto memberId : team->memberIDs) { for (const auto memberId : team->memberIDs) {
const auto& otherMember = GetPlayerData(memberId); auto* otherMember = GetPlayerData(memberId);
if (!otherMember) continue; if (otherMember == nullptr) continue;
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, { 0, 0, 0 }); ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, { 0, 0, 0 });
} }
@@ -97,7 +85,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
LOG("Removed user: %llu", playerID); LOG("Removed user: %llu", playerID);
m_Players.erase(playerID); m_Players.erase(playerID);
Database::Get()->UpdateActivityLog(playerID, eActivityType::PlayerLoggedOut, player.zoneID.GetMapID()); Database::Get()->UpdateActivityLog(playerID, eActivityType::PlayerLoggedOut, player->zoneID.GetMapID());
} }
void PlayerContainer::MuteUpdate(Packet* packet) { void PlayerContainer::MuteUpdate(Packet* packet) {
@@ -107,15 +95,15 @@ void PlayerContainer::MuteUpdate(Packet* packet) {
time_t expire = 0; time_t expire = 0;
inStream.Read(expire); inStream.Read(expire);
auto& player = this->GetPlayerDataMutable(playerID); auto* player = this->GetPlayerData(playerID);
if (!player) { if (player == nullptr) {
LOG("Failed to find user: %llu", playerID); LOG("Failed to find user: %llu", playerID);
return; return;
} }
player.muteExpire = expire; player->muteExpire = expire;
BroadcastMuteUpdate(playerID, expire); BroadcastMuteUpdate(playerID, expire);
} }
@@ -213,11 +201,11 @@ TeamData* PlayerContainer::GetTeam(LWOOBJID playerID) {
} }
void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) { void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) {
if (team->memberIDs.size() >= 4) { if (team->memberIDs.size() >= 4){
LOG("Tried to add player to team that already had 4 players"); LOG("Tried to add player to team that already had 4 players");
const auto& player = GetPlayerData(playerID); auto* player = GetPlayerData(playerID);
if (!player) return; if (!player) return;
ChatPackets::SendSystemMessage(player.sysAddr, u"The teams is full! You have not been added to a team!"); ChatPackets::SendSystemMessage(player->sysAddr, u"The teams is full! You have not been added to a team!");
return; return;
} }
@@ -227,18 +215,18 @@ void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) {
team->memberIDs.push_back(playerID); team->memberIDs.push_back(playerID);
const auto& leader = GetPlayerData(team->leaderID); auto* leader = GetPlayerData(team->leaderID);
const auto& member = GetPlayerData(playerID); auto* member = GetPlayerData(playerID);
if (!leader || !member) return; if (leader == nullptr || member == nullptr) return;
const auto leaderName = GeneralUtils::UTF8ToUTF16(leader.playerName); const auto leaderName = GeneralUtils::UTF8ToUTF16(leader->playerName);
const auto memberName = GeneralUtils::UTF8ToUTF16(member.playerName); const auto memberName = GeneralUtils::UTF8ToUTF16(member->playerName);
ChatPacketHandler::SendTeamInviteConfirm(member, false, leader.playerID, leader.zoneID, team->lootFlag, 0, 0, leaderName); ChatPacketHandler::SendTeamInviteConfirm(member, false, leader->playerID, leader->zoneID, team->lootFlag, 0, 0, leaderName);
if (!team->local) { if (!team->local) {
ChatPacketHandler::SendTeamSetLeader(member, leader.playerID); ChatPacketHandler::SendTeamSetLeader(member, leader->playerID);
} else { } else {
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY); ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
} }
@@ -246,16 +234,16 @@ void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) {
UpdateTeamsOnWorld(team, false); UpdateTeamsOnWorld(team, false);
for (const auto memberId : team->memberIDs) { for (const auto memberId : team->memberIDs) {
const auto& otherMember = GetPlayerData(memberId); auto* otherMember = GetPlayerData(memberId);
if (otherMember == member) continue; if (otherMember == member) continue;
const auto otherMemberName = GetName(memberId); const auto otherMemberName = GetName(memberId);
ChatPacketHandler::SendTeamAddPlayer(member, false, team->local, false, memberId, otherMemberName, otherMember ? otherMember.zoneID : LWOZONEID(0, 0, 0)); ChatPacketHandler::SendTeamAddPlayer(member, false, team->local, false, memberId, otherMemberName, otherMember != nullptr ? otherMember->zoneID : LWOZONEID(0, 0, 0));
if (otherMember) { if (otherMember != nullptr) {
ChatPacketHandler::SendTeamAddPlayer(otherMember, false, team->local, false, member.playerID, memberName, member.zoneID); ChatPacketHandler::SendTeamAddPlayer(otherMember, false, team->local, false, member->playerID, memberName, member->zoneID);
} }
} }
} }
@@ -265,9 +253,9 @@ void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disba
if (index == team->memberIDs.end()) return; if (index == team->memberIDs.end()) return;
const auto& member = GetPlayerData(playerID); auto* member = GetPlayerData(playerID);
if (member && !silent) { if (member != nullptr && !silent) {
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY); ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
} }
@@ -278,9 +266,9 @@ void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disba
continue; continue;
} }
const auto& otherMember = GetPlayerData(memberId); auto* otherMember = GetPlayerData(memberId);
if (!otherMember) continue; if (otherMember == nullptr) continue;
ChatPacketHandler::SendTeamRemovePlayer(otherMember, disband, kicked, leaving, false, team->leaderID, playerID, memberName); ChatPacketHandler::SendTeamRemovePlayer(otherMember, disband, kicked, leaving, false, team->leaderID, playerID, memberName);
} }
@@ -302,9 +290,9 @@ void PlayerContainer::PromoteMember(TeamData* team, LWOOBJID newLeader) {
team->leaderID = newLeader; team->leaderID = newLeader;
for (const auto memberId : team->memberIDs) { for (const auto memberId : team->memberIDs) {
const auto& otherMember = GetPlayerData(memberId); auto* otherMember = GetPlayerData(memberId);
if (!otherMember) continue; if (otherMember == nullptr) continue;
ChatPacketHandler::SendTeamSetLeader(otherMember, newLeader); ChatPacketHandler::SendTeamSetLeader(otherMember, newLeader);
} }
@@ -316,14 +304,14 @@ void PlayerContainer::DisbandTeam(TeamData* team) {
if (index == mTeams.end()) return; if (index == mTeams.end()) return;
for (const auto memberId : team->memberIDs) { for (const auto memberId : team->memberIDs) {
const auto& otherMember = GetPlayerData(memberId); auto* otherMember = GetPlayerData(memberId);
if (!otherMember) continue; if (otherMember == nullptr) continue;
const auto memberName = GeneralUtils::UTF8ToUTF16(otherMember.playerName); const auto memberName = GeneralUtils::UTF8ToUTF16(otherMember->playerName);
ChatPacketHandler::SendTeamSetLeader(otherMember, LWOOBJID_EMPTY); ChatPacketHandler::SendTeamSetLeader(otherMember, LWOOBJID_EMPTY);
ChatPacketHandler::SendTeamRemovePlayer(otherMember, true, false, false, team->local, team->leaderID, otherMember.playerID, memberName); ChatPacketHandler::SendTeamRemovePlayer(otherMember, true, false, false, team->local, team->leaderID, otherMember->playerID, memberName);
} }
UpdateTeamsOnWorld(team, true); UpdateTeamsOnWorld(team, true);
@@ -338,19 +326,19 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) {
if (index == mTeams.end()) return; if (index == mTeams.end()) return;
const auto& leader = GetPlayerData(team->leaderID); auto* leader = GetPlayerData(team->leaderID);
if (!leader) return; if (leader == nullptr) return;
const auto leaderName = GeneralUtils::UTF8ToUTF16(leader.playerName); const auto leaderName = GeneralUtils::UTF8ToUTF16(leader->playerName);
for (const auto memberId : team->memberIDs) { for (const auto memberId : team->memberIDs) {
const auto& otherMember = GetPlayerData(memberId); auto* otherMember = GetPlayerData(memberId);
if (!otherMember) continue; if (otherMember == nullptr) continue;
if (!team->local) { if (!team->local) {
ChatPacketHandler::SendTeamStatus(otherMember, team->leaderID, leader.zoneID, team->lootFlag, 0, leaderName); ChatPacketHandler::SendTeamStatus(otherMember, team->leaderID, leader->zoneID, team->lootFlag, 0, leaderName);
} }
} }
@@ -376,42 +364,23 @@ void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
} }
std::u16string PlayerContainer::GetName(LWOOBJID playerID) { std::u16string PlayerContainer::GetName(LWOOBJID playerID) {
const auto iter = m_Names.find(playerID); const auto& pair = m_Names.find(playerID);
if (iter == m_Names.end()) return u""; if (pair == m_Names.end()) return u"";
return iter->second; return pair->second;
} }
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) { LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) {
LWOOBJID toReturn = LWOOBJID_EMPTY; for (const auto& pair : m_Names) {
if (pair.second == playerName) {
for (const auto& [id, name] : m_Names) { return pair.first;
if (name == playerName) {
toReturn = id;
break;
} }
} }
return toReturn; return LWOOBJID_EMPTY;
} }
PlayerData& PlayerContainer::GetPlayerDataMutable(const LWOOBJID& playerID) { bool PlayerContainer::GetIsMuted(PlayerData* data) {
return m_Players[playerID]; return data->muteExpire == 1 || data->muteExpire > time(NULL);
}
PlayerData& PlayerContainer::GetPlayerDataMutable(const std::string& playerName) {
for (auto& [id, player] : m_Players) {
if (!player) continue;
if (player.playerName == playerName) return player;
}
return m_Players[LWOOBJID_EMPTY];
}
const PlayerData& PlayerContainer::GetPlayerData(const LWOOBJID& playerID) {
return GetPlayerDataMutable(playerID);
}
const PlayerData& PlayerContainer::GetPlayerData(const std::string& playerName) {
return GetPlayerDataMutable(playerName);
} }

View File

@@ -7,10 +7,7 @@
#include "dServer.h" #include "dServer.h"
#include <unordered_map> #include <unordered_map>
enum class eGameMasterLevel : uint8_t;
struct IgnoreData { struct IgnoreData {
IgnoreData(const std::string& name, const LWOOBJID& id) : playerName(name), playerId(id) {}
inline bool operator==(const std::string& other) const noexcept { inline bool operator==(const std::string& other) const noexcept {
return playerName == other; return playerName == other;
} }
@@ -19,34 +16,19 @@ struct IgnoreData {
return playerId == other; return playerId == other;
} }
LWOOBJID playerId = LWOOBJID_EMPTY; LWOOBJID playerId;
std::string playerName; std::string playerName;
}; };
struct PlayerData { struct PlayerData {
PlayerData(); LWOOBJID playerID;
operator bool() const noexcept {
return playerID != LWOOBJID_EMPTY;
}
bool operator==(const PlayerData& other) const noexcept {
return playerID == other.playerID;
}
bool GetIsMuted() const {
return muteExpire == 1 || muteExpire > time(NULL);
}
SystemAddress sysAddr{};
LWOZONEID zoneID{};
LWOOBJID playerID = LWOOBJID_EMPTY;
time_t muteExpire = 0;
uint8_t countOfBestFriends = 0;
std::string playerName; std::string playerName;
SystemAddress sysAddr;
LWOZONEID zoneID;
std::vector<FriendData> friends; std::vector<FriendData> friends;
std::vector<IgnoreData> ignoredPlayers; std::vector<IgnoreData> ignoredPlayers;
eGameMasterLevel gmLevel; time_t muteExpire;
bool isFTP = false; uint8_t countOfBestFriends = 0;
}; };
struct TeamData { struct TeamData {
@@ -70,10 +52,22 @@ public:
void CreateTeamServer(Packet* packet); void CreateTeamServer(Packet* packet);
void BroadcastMuteUpdate(LWOOBJID player, time_t time); void BroadcastMuteUpdate(LWOOBJID player, time_t time);
const PlayerData& GetPlayerData(const LWOOBJID& playerID); PlayerData* GetPlayerData(const LWOOBJID& playerID) {
const PlayerData& GetPlayerData(const std::string& playerName); auto it = m_Players.find(playerID);
PlayerData& GetPlayerDataMutable(const LWOOBJID& playerID); if (it != m_Players.end()) return it->second;
PlayerData& GetPlayerDataMutable(const std::string& playerName); return nullptr;
}
PlayerData* GetPlayerData(const std::string& playerName) {
for (auto player : m_Players) {
if (player.second) {
std::string pn = player.second->playerName.c_str();
if (pn == playerName) return player.second;
}
}
return nullptr;
}
TeamData* CreateLocalTeam(std::vector<LWOOBJID> members); TeamData* CreateLocalTeam(std::vector<LWOOBJID> members);
TeamData* CreateTeam(LWOOBJID leader, bool local = false); TeamData* CreateTeam(LWOOBJID leader, bool local = false);
@@ -86,12 +80,15 @@ public:
void UpdateTeamsOnWorld(TeamData* team, bool deleteTeam); void UpdateTeamsOnWorld(TeamData* team, bool deleteTeam);
std::u16string GetName(LWOOBJID playerID); std::u16string GetName(LWOOBJID playerID);
LWOOBJID GetId(const std::u16string& playerName); LWOOBJID GetId(const std::u16string& playerName);
bool GetIsMuted(PlayerData* data);
uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; } uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; }
uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; } uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; }
std::map<LWOOBJID, PlayerData*>& GetAllPlayerData() { return m_Players; }
private: private:
LWOOBJID m_TeamIDCounter = 0; LWOOBJID m_TeamIDCounter = 0;
std::map<LWOOBJID, PlayerData> m_Players; std::map<LWOOBJID, PlayerData*> m_Players;
std::vector<TeamData*> mTeams; std::vector<TeamData*> mTeams;
std::unordered_map<LWOOBJID, std::u16string> m_Names; std::unordered_map<LWOOBJID, std::u16string> m_Names;
uint32_t m_MaxNumberOfBestFriends = 5; uint32_t m_MaxNumberOfBestFriends = 5;

View File

@@ -4,7 +4,7 @@
#include "Amf3.h" #include "Amf3.h"
// RakNet // RakNet
#include "BitStream.h" #include <BitStream.h>
/*! /*!
\file AmfSerialize.h \file AmfSerialize.h

View File

@@ -20,12 +20,6 @@ set(DCOMMON_SOURCES
"FdbToSqlite.cpp" "FdbToSqlite.cpp"
) )
# Workaround for compiler bug where the optimized code could result in a memcpy of 0 bytes, even though that isnt possible.
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97185
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set_source_files_properties("FdbToSqlite.cpp" PROPERTIES COMPILE_FLAGS "-Wno-stringop-overflow")
endif()
add_subdirectory(dClient) add_subdirectory(dClient)
foreach(file ${DCOMMON_DCLIENT_SOURCES}) foreach(file ${DCOMMON_DCLIENT_SOURCES})
@@ -68,8 +62,3 @@ else ()
endif () endif ()
target_link_libraries(dCommon ZLIB::ZLIB) target_link_libraries(dCommon ZLIB::ZLIB)
# Disable deprecation warnings on MD5.cpp and SHA512.cpp for Apple Clang
if (APPLE)
set_source_files_properties("MD5.cpp" "SHA512.cpp" PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations")
endif()

View File

@@ -9,7 +9,7 @@
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>
#include <stdexcept> #include <stdexcept>
#include "BitStream.h" #include <BitStream.h>
#include "NiPoint3.h" #include "NiPoint3.h"
#include "Game.h" #include "Game.h"

View File

@@ -1,24 +1,210 @@
#include "NiPoint3.h" #include "NiPoint3.h"
#include "NiQuaternion.h"
// C++ // C++
#include <cmath> #include <cmath>
// MARK: Member Functions // Static Variables
const NiPoint3 NiPoint3::ZERO(0.0f, 0.0f, 0.0f);
const NiPoint3 NiPoint3::UNIT_X(1.0f, 0.0f, 0.0f);
const NiPoint3 NiPoint3::UNIT_Y(0.0f, 1.0f, 0.0f);
const NiPoint3 NiPoint3::UNIT_Z(0.0f, 0.0f, 1.0f);
const NiPoint3 NiPoint3::UNIT_ALL(1.0f, 1.0f, 1.0f);
//! Initializer
NiPoint3::NiPoint3(void) {
this->x = 0;
this->y = 0;
this->z = 0;
}
//! Initializer
NiPoint3::NiPoint3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
//! Copy Constructor
NiPoint3::NiPoint3(const NiPoint3& point) {
this->x = point.x;
this->y = point.y;
this->z = point.z;
}
//! Destructor
NiPoint3::~NiPoint3(void) {}
// MARK: Getters / Setters
//! Gets the X coordinate
float NiPoint3::GetX(void) const {
return this->x;
}
//! Sets the X coordinate
void NiPoint3::SetX(float x) {
this->x = x;
}
//! Gets the Y coordinate
float NiPoint3::GetY(void) const {
return this->y;
}
//! Sets the Y coordinate
void NiPoint3::SetY(float y) {
this->y = y;
}
//! Gets the Z coordinate
float NiPoint3::GetZ(void) const {
return this->z;
}
//! Sets the Z coordinate
void NiPoint3::SetZ(float z) {
this->z = z;
}
// MARK: Functions
//! Gets the length of the vector //! Gets the length of the vector
float NiPoint3::Length() const { float NiPoint3::Length(void) const {
return std::sqrt(x * x + y * y + z * z); return sqrt(x * x + y * y + z * z);
}
//! Gets the squared length of a vector
float NiPoint3::SquaredLength(void) const {
return (x * x + y * y + z * z);
}
//! Returns the dot product of the vector dotted with another vector
float NiPoint3::DotProduct(const Vector3& vec) const {
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
}
//! Returns the cross product of the vector crossed with another vector
Vector3 NiPoint3::CrossProduct(const Vector3& vec) const {
return Vector3(((this->y * vec.z) - (this->z * vec.y)),
((this->z * vec.x) - (this->x * vec.z)),
((this->x * vec.y) - (this->y * vec.x)));
} }
//! Unitize the vector //! Unitize the vector
NiPoint3 NiPoint3::Unitize() const { NiPoint3 NiPoint3::Unitize(void) const {
float length = this->Length(); float length = this->Length();
return length != 0 ? *this / length : NiPoint3Constant::ZERO; return length != 0 ? *this / length : NiPoint3::ZERO;
} }
// MARK: Operators
//! Operator to check for equality
bool NiPoint3::operator==(const NiPoint3& point) const {
return point.x == this->x && point.y == this->y && point.z == this->z;
}
//! Operator to check for inequality
bool NiPoint3::operator!=(const NiPoint3& point) const {
return !(*this == point);
}
//! Operator for subscripting
float& NiPoint3::operator[](int i) {
float* base = &x;
return base[i];
}
//! Operator for subscripting
const float& NiPoint3::operator[](int i) const {
const float* base = &x;
return base[i];
}
//! Operator for addition of vectors
NiPoint3 NiPoint3::operator+(const NiPoint3& point) const {
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
}
//! Operator for addition of vectors
NiPoint3& NiPoint3::operator+=(const NiPoint3& point) {
this->x += point.x;
this->y += point.y;
this->z += point.z;
return *this;
}
NiPoint3& NiPoint3::operator*=(const float scalar) {
this->x *= scalar;
this->y *= scalar;
this->z *= scalar;
return *this;
}
//! Operator for subtraction of vectors
NiPoint3 NiPoint3::operator-(const NiPoint3& point) const {
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
}
//! Operator for addition of a scalar on all vector components
NiPoint3 NiPoint3::operator+(float fScalar) const {
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
}
//! Operator for subtraction of a scalar on all vector components
NiPoint3 NiPoint3::operator-(float fScalar) const {
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
}
//! Operator for scalar multiplication of a vector
NiPoint3 NiPoint3::operator*(float fScalar) const {
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
}
//! Operator for scalar division of a vector
NiPoint3 NiPoint3::operator/(float fScalar) const {
float retX = this->x != 0 ? this->x / fScalar : 0;
float retY = this->y != 0 ? this->y / fScalar : 0;
float retZ = this->z != 0 ? this->z / fScalar : 0;
return NiPoint3(retX, retY, retZ);
}
// MARK: Helper Functions // MARK: Helper Functions
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
bool NiPoint3::IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) {
if (this->x < minPoint.x) return false;
if (this->x > maxPoint.x) return false;
if (this->y < minPoint.y) return false;
if (this->y > maxPoint.y) return false;
return (this->z < maxPoint.z && this->z > minPoint.z);
}
//! Checks to see if the point (or vector) is within a sphere
bool NiPoint3::IsWithinSpehere(const NiPoint3& sphereCenter, float radius) {
Vector3 diffVec = Vector3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
return (diffVec.SquaredLength() <= (radius * radius));
}
NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) {
if (a == b) return a;
const auto pa = p - a;
const auto ab = b - a;
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
if (t <= 0.0f) return a;
if (t >= 1.0f) return b;
return a + ab * t;
}
float NiPoint3::Angle(const NiPoint3& a, const NiPoint3& b) { float NiPoint3::Angle(const NiPoint3& a, const NiPoint3& b) {
const auto dot = a.DotProduct(b); const auto dot = a.DotProduct(b);
const auto lenA = a.SquaredLength(); const auto lenA = a.SquaredLength();
@@ -34,7 +220,15 @@ float NiPoint3::Distance(const NiPoint3& a, const NiPoint3& b) {
return std::sqrt(dx * dx + dy * dy + dz * dz); return std::sqrt(dx * dx + dy * dy + dz * dz);
} }
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, const float maxDistanceDelta) { float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b) {
const auto dx = a.x - b.x;
const auto dy = a.y - b.y;
const auto dz = a.z - b.z;
return dx * dx + dy * dy + dz * dz;
}
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta) {
float dx = target.x - current.x; float dx = target.x - current.x;
float dy = target.y - current.y; float dy = target.y - current.y;
float dz = target.z - current.z; float dz = target.z - current.z;
@@ -55,3 +249,29 @@ NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target,
float length = std::sqrt(lengthSquared); float length = std::sqrt(lengthSquared);
return NiPoint3(current.x + dx / length * maxDistanceDelta, current.y + dy / length * maxDistanceDelta, current.z + dz / length * maxDistanceDelta); return NiPoint3(current.x + dx / length * maxDistanceDelta, current.y + dy / length * maxDistanceDelta, current.z + dz / length * maxDistanceDelta);
} }
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible.
NiPoint3 NiPoint3::RotateByQuaternion(const NiQuaternion& rotation) {
Vector3 vector;
float num12 = rotation.x + rotation.x;
float num2 = rotation.y + rotation.y;
float num = rotation.z + rotation.z;
float num11 = rotation.w * num12;
float num10 = rotation.w * num2;
float num9 = rotation.w * num;
float num8 = rotation.x * num12;
float num7 = rotation.x * num2;
float num6 = rotation.x * num;
float num5 = rotation.y * num2;
float num4 = rotation.y * num;
float num3 = rotation.z * num;
NiPoint3 value = *this;
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
vector.x = num15;
vector.y = num14;
vector.z = num13;
return vector;
}

View File

@@ -1,5 +1,4 @@
#ifndef __NIPOINT3_H__ #pragma once
#define __NIPOINT3_H__
/*! /*!
\file NiPoint3.hpp \file NiPoint3.hpp
@@ -13,13 +12,13 @@ typedef NiPoint3 Vector3; //!< The Vector3 class is technically the NiPoin
//! A custom class the defines a point in space //! A custom class the defines a point in space
class NiPoint3 { class NiPoint3 {
public: public:
float x{ 0 }; //!< The x position float x; //!< The x position
float y{ 0 }; //!< The y position float y; //!< The y position
float z{ 0 }; //!< The z position float z; //!< The z position
//! Initializer //! Initializer
constexpr NiPoint3() = default; NiPoint3(void);
//! Initializer //! Initializer
/*! /*!
@@ -27,21 +26,23 @@ public:
\param y The y coordinate \param y The y coordinate
\param z The z coordinate \param z The z coordinate
*/ */
constexpr NiPoint3(const float x, const float y, const float z) noexcept NiPoint3(float x, float y, float z);
: x{ x }
, y{ y }
, z{ z } {
}
//! Copy Constructor //! Copy Constructor
/*! /*!
\param point The point to copy \param point The point to copy
*/ */
constexpr NiPoint3(const NiPoint3& point) noexcept NiPoint3(const NiPoint3& point);
: x{ point.x }
, y{ point.y } //! Destructor
, z{ point.z } { ~NiPoint3(void);
}
// MARK: Constants
static const NiPoint3 ZERO; //!< Point(0, 0, 0)
static const NiPoint3 UNIT_X; //!< Point(1, 0, 0)
static const NiPoint3 UNIT_Y; //!< Point(0, 1, 0)
static const NiPoint3 UNIT_Z; //!< Point(0, 0, 1)
static const NiPoint3 UNIT_ALL; //!< Point(1, 1, 1)
// MARK: Getters / Setters // MARK: Getters / Setters
@@ -49,37 +50,38 @@ public:
/*! /*!
\return The x coordinate \return The x coordinate
*/ */
[[nodiscard]] constexpr float GetX() const noexcept; float GetX(void) const;
//! Sets the X coordinate //! Sets the X coordinate
/*! /*!
\param x The x coordinate \param x The x coordinate
*/ */
constexpr void SetX(const float x) noexcept; void SetX(float x);
//! Gets the Y coordinate //! Gets the Y coordinate
/*! /*!
\return The y coordinate \return The y coordinate
*/ */
[[nodiscard]] constexpr float GetY() const noexcept; float GetY(void) const;
//! Sets the Y coordinate //! Sets the Y coordinate
/*! /*!
\param y The y coordinate \param y The y coordinate
*/ */
constexpr void SetY(const float y) noexcept; void SetY(float y);
//! Gets the Z coordinate //! Gets the Z coordinate
/*! /*!
\return The z coordinate \return The z coordinate
*/ */
[[nodiscard]] constexpr float GetZ() const noexcept; float GetZ(void) const;
//! Sets the Z coordinate //! Sets the Z coordinate
/*! /*!
\param z The z coordinate \param z The z coordinate
*/ */
constexpr void SetZ(const float z) noexcept; void SetZ(float z);
// MARK: Member Functions // MARK: Member Functions
@@ -87,70 +89,72 @@ public:
/*! /*!
\return The scalar length of the vector \return The scalar length of the vector
*/ */
[[nodiscard]] float Length() const; float Length(void) const;
//! Gets the squared length of a vector //! Gets the squared length of a vector
/*! /*!
\return The squared length of a vector \return The squared length of a vector
*/ */
[[nodiscard]] constexpr float SquaredLength() const noexcept; float SquaredLength(void) const;
//! Returns the dot product of the vector dotted with another vector //! Returns the dot product of the vector dotted with another vector
/*! /*!
\param vec The second vector \param vec The second vector
\return The dot product of the two vectors \return The dot product of the two vectors
*/ */
[[nodiscard]] constexpr float DotProduct(const Vector3& vec) const noexcept; float DotProduct(const Vector3& vec) const;
//! Returns the cross product of the vector crossed with another vector //! Returns the cross product of the vector crossed with another vector
/*! /*!
\param vec The second vector \param vec The second vector
\return The cross product of the two vectors \return The cross product of the two vectors
*/ */
[[nodiscard]] constexpr Vector3 CrossProduct(const Vector3& vec) const noexcept; Vector3 CrossProduct(const Vector3& vec) const;
//! Unitize the vector //! Unitize the vector
/*! /*!
\returns The current vector \returns The current vector
*/ */
[[nodiscard]] NiPoint3 Unitize() const; NiPoint3 Unitize(void) const;
// MARK: Operators // MARK: Operators
//! Operator to check for equality //! Operator to check for equality
constexpr bool operator==(const NiPoint3& point) const noexcept; bool operator==(const NiPoint3& point) const;
//! Operator to check for inequality //! Operator to check for inequality
constexpr bool operator!=(const NiPoint3& point) const noexcept; bool operator!=(const NiPoint3& point) const;
//! Operator for subscripting //! Operator for subscripting
constexpr float& operator[](const int i) noexcept; float& operator[](int i);
//! Operator for subscripting //! Operator for subscripting
constexpr const float& operator[](const int i) const noexcept; const float& operator[](int i) const;
//! Operator for addition of vectors //! Operator for addition of vectors
constexpr NiPoint3 operator+(const NiPoint3& point) const noexcept; NiPoint3 operator+(const NiPoint3& point) const;
//! Operator for addition of vectors //! Operator for addition of vectors
constexpr NiPoint3& operator+=(const NiPoint3& point) noexcept; NiPoint3& operator+=(const NiPoint3& point);
constexpr NiPoint3& operator*=(const float scalar) noexcept; NiPoint3& operator*=(const float scalar);
//! Operator for subtraction of vectors //! Operator for subtraction of vectors
constexpr NiPoint3 operator-(const NiPoint3& point) const noexcept; NiPoint3 operator-(const NiPoint3& point) const;
//! Operator for addition of a scalar on all vector components //! Operator for addition of a scalar on all vector components
constexpr NiPoint3 operator+(const float fScalar) const noexcept; NiPoint3 operator+(float fScalar) const;
//! Operator for subtraction of a scalar on all vector components //! Operator for subtraction of a scalar on all vector components
constexpr NiPoint3 operator-(const float fScalar) const noexcept; NiPoint3 operator-(float fScalar) const;
//! Operator for scalar multiplication of a vector //! Operator for scalar multiplication of a vector
constexpr NiPoint3 operator*(const float fScalar) const noexcept; NiPoint3 operator*(float fScalar) const;
//! Operator for scalar division of a vector //! Operator for scalar division of a vector
constexpr NiPoint3 operator/(const float fScalar) const noexcept; NiPoint3 operator/(float fScalar) const;
// MARK: Helper Functions // MARK: Helper Functions
@@ -160,14 +164,14 @@ public:
\param maxPoint The maximum point of the bounding box \param maxPoint The maximum point of the bounding box
\return Whether or not this point lies within the box \return Whether or not this point lies within the box
*/ */
[[nodiscard]] constexpr bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) noexcept; bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint);
//! Checks to see if the point (or vector) is within a sphere //! Checks to see if the point (or vector) is within a sphere
/*! /*!
\param sphereCenter The sphere center \param sphereCenter The sphere center
\param radius The radius \param radius The radius
*/ */
[[nodiscard]] constexpr bool IsWithinSphere(const NiPoint3& sphereCenter, const float radius) noexcept; bool IsWithinSpehere(const NiPoint3& sphereCenter, float radius);
/*! /*!
\param a Start of line \param a Start of line
@@ -175,30 +179,15 @@ public:
\param p Refrence point \param p Refrence point
\return The point of line AB which is closest to P \return The point of line AB which is closest to P
*/ */
[[nodiscard]] static constexpr NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) noexcept; static NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p);
[[nodiscard]] static float Angle(const NiPoint3& a, const NiPoint3& b); static float Angle(const NiPoint3& a, const NiPoint3& b);
[[nodiscard]] static float Distance(const NiPoint3& a, const NiPoint3& b); static float Distance(const NiPoint3& a, const NiPoint3& b);
[[nodiscard]] static constexpr float DistanceSquared(const NiPoint3& a, const NiPoint3& b) noexcept; static float DistanceSquared(const NiPoint3& a, const NiPoint3& b);
[[nodiscard]] static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, const float maxDistanceDelta); static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta);
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible. NiPoint3 RotateByQuaternion(const NiQuaternion& rotation);
[[nodiscard]] constexpr NiPoint3 RotateByQuaternion(const NiQuaternion& rotation) noexcept;
}; };
// Static Variables
namespace NiPoint3Constant {
constexpr NiPoint3 ZERO(0.0f, 0.0f, 0.0f);
constexpr NiPoint3 UNIT_X(1.0f, 0.0f, 0.0f);
constexpr NiPoint3 UNIT_Y(0.0f, 1.0f, 0.0f);
constexpr NiPoint3 UNIT_Z(0.0f, 0.0f, 1.0f);
constexpr NiPoint3 UNIT_ALL(1.0f, 1.0f, 1.0f);
}
// .inl file needed for code organization and to circumvent circular dependency issues
#include "NiPoint3.inl"
#endif // !__NIPOINT3_H__

View File

@@ -1,196 +0,0 @@
#pragma once
#ifndef __NIPOINT3_H__
#error "This should only be included inline in NiPoint3.h: Do not include directly!"
#endif
#include "NiQuaternion.h"
// MARK: Getters / Setters
//! Gets the X coordinate
constexpr float NiPoint3::GetX() const noexcept {
return this->x;
}
//! Sets the X coordinate
constexpr void NiPoint3::SetX(const float x) noexcept {
this->x = x;
}
//! Gets the Y coordinate
constexpr float NiPoint3::GetY() const noexcept {
return this->y;
}
//! Sets the Y coordinate
constexpr void NiPoint3::SetY(const float y) noexcept {
this->y = y;
}
//! Gets the Z coordinate
constexpr float NiPoint3::GetZ() const noexcept {
return this->z;
}
//! Sets the Z coordinate
constexpr void NiPoint3::SetZ(const float z) noexcept {
this->z = z;
}
// MARK: Member Functions
//! Gets the squared length of a vector
constexpr float NiPoint3::SquaredLength() const noexcept {
return (x * x + y * y + z * z);
}
//! Returns the dot product of the vector dotted with another vector
constexpr float NiPoint3::DotProduct(const Vector3& vec) const noexcept {
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
}
//! Returns the cross product of the vector crossed with another vector
constexpr Vector3 NiPoint3::CrossProduct(const Vector3& vec) const noexcept {
return Vector3(((this->y * vec.z) - (this->z * vec.y)),
((this->z * vec.x) - (this->x * vec.z)),
((this->x * vec.y) - (this->y * vec.x)));
}
// MARK: Operators
//! Operator to check for equality
constexpr bool NiPoint3::operator==(const NiPoint3& point) const noexcept {
return point.x == this->x && point.y == this->y && point.z == this->z;
}
//! Operator to check for inequality
constexpr bool NiPoint3::operator!=(const NiPoint3& point) const noexcept {
return !(*this == point);
}
//! Operator for subscripting
constexpr float& NiPoint3::operator[](const int i) noexcept {
float* base = &x;
return base[i];
}
//! Operator for subscripting
constexpr const float& NiPoint3::operator[](const int i) const noexcept {
const float* base = &x;
return base[i];
}
//! Operator for addition of vectors
constexpr NiPoint3 NiPoint3::operator+(const NiPoint3& point) const noexcept {
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
}
//! Operator for addition of vectors
constexpr NiPoint3& NiPoint3::operator+=(const NiPoint3& point) noexcept {
this->x += point.x;
this->y += point.y;
this->z += point.z;
return *this;
}
constexpr NiPoint3& NiPoint3::operator*=(const float scalar) noexcept {
this->x *= scalar;
this->y *= scalar;
this->z *= scalar;
return *this;
}
//! Operator for subtraction of vectors
constexpr NiPoint3 NiPoint3::operator-(const NiPoint3& point) const noexcept {
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
}
//! Operator for addition of a scalar on all vector components
constexpr NiPoint3 NiPoint3::operator+(const float fScalar) const noexcept {
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
}
//! Operator for subtraction of a scalar on all vector components
constexpr NiPoint3 NiPoint3::operator-(const float fScalar) const noexcept {
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
}
//! Operator for scalar multiplication of a vector
constexpr NiPoint3 NiPoint3::operator*(const float fScalar) const noexcept {
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
}
//! Operator for scalar division of a vector
constexpr NiPoint3 NiPoint3::operator/(const float fScalar) const noexcept {
float retX = this->x != 0 ? this->x / fScalar : 0;
float retY = this->y != 0 ? this->y / fScalar : 0;
float retZ = this->z != 0 ? this->z / fScalar : 0;
return NiPoint3(retX, retY, retZ);
}
// MARK: Helper Functions
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
constexpr bool NiPoint3::IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) noexcept {
if (this->x < minPoint.x) return false;
if (this->x > maxPoint.x) return false;
if (this->y < minPoint.y) return false;
if (this->y > maxPoint.y) return false;
return (this->z < maxPoint.z && this->z > minPoint.z);
}
//! Checks to see if the point (or vector) is within a sphere
constexpr bool NiPoint3::IsWithinSphere(const NiPoint3& sphereCenter, const float radius) noexcept {
Vector3 diffVec = Vector3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
return (diffVec.SquaredLength() <= (radius * radius));
}
constexpr NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) noexcept {
if (a == b) return a;
const auto pa = p - a;
const auto ab = b - a;
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
if (t <= 0.0f) return a;
if (t >= 1.0f) return b;
return a + ab * t;
}
constexpr float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b) noexcept {
const auto dx = a.x - b.x;
const auto dy = a.y - b.y;
const auto dz = a.z - b.z;
return dx * dx + dy * dy + dz * dz;
}
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible.
constexpr NiPoint3 NiPoint3::RotateByQuaternion(const NiQuaternion& rotation) noexcept {
Vector3 vector;
float num12 = rotation.x + rotation.x;
float num2 = rotation.y + rotation.y;
float num = rotation.z + rotation.z;
float num11 = rotation.w * num12;
float num10 = rotation.w * num2;
float num9 = rotation.w * num;
float num8 = rotation.x * num12;
float num7 = rotation.x * num2;
float num6 = rotation.x * num;
float num5 = rotation.y * num2;
float num4 = rotation.y * num;
float num3 = rotation.z * num;
NiPoint3 value = *this;
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
vector.x = num15;
vector.y = num14;
vector.z = num13;
return vector;
}

View File

@@ -3,8 +3,89 @@
// C++ // C++
#include <cmath> #include <cmath>
// Static Variables
const NiQuaternion NiQuaternion::IDENTITY(1, 0, 0, 0);
//! The initializer
NiQuaternion::NiQuaternion(void) {
this->w = 1;
this->x = 0;
this->y = 0;
this->z = 0;
}
//! The initializer
NiQuaternion::NiQuaternion(float w, float x, float y, float z) {
this->w = w;
this->x = x;
this->y = y;
this->z = z;
}
//! Destructor
NiQuaternion::~NiQuaternion(void) {}
// MARK: Setters / Getters
//! Gets the W coordinate
float NiQuaternion::GetW(void) const {
return this->w;
}
//! Sets the W coordinate
void NiQuaternion::SetW(float w) {
this->w = w;
}
//! Gets the X coordinate
float NiQuaternion::GetX(void) const {
return this->x;
}
//! Sets the X coordinate
void NiQuaternion::SetX(float x) {
this->x = x;
}
//! Gets the Y coordinate
float NiQuaternion::GetY(void) const {
return this->y;
}
//! Sets the Y coordinate
void NiQuaternion::SetY(float y) {
this->y = y;
}
//! Gets the Z coordinate
float NiQuaternion::GetZ(void) const {
return this->z;
}
//! Sets the Z coordinate
void NiQuaternion::SetZ(float z) {
this->z = z;
}
// MARK: Member Functions // MARK: Member Functions
//! Returns the forward vector from the quaternion
Vector3 NiQuaternion::GetForwardVector(void) const {
return Vector3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
}
//! Returns the up vector from the quaternion
Vector3 NiQuaternion::GetUpVector(void) const {
return Vector3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
}
//! Returns the right vector from the quaternion
Vector3 NiQuaternion::GetRightVector(void) const {
return Vector3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
}
Vector3 NiQuaternion::GetEulerAngles() const { Vector3 NiQuaternion::GetEulerAngles() const {
Vector3 angles; Vector3 angles;
@@ -30,9 +111,22 @@ Vector3 NiQuaternion::GetEulerAngles() const {
return angles; return angles;
} }
// MARK: Operators
//! Operator to check for equality
bool NiQuaternion::operator==(const NiQuaternion& rot) const {
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
}
//! Operator to check for inequality
bool NiQuaternion::operator!=(const NiQuaternion& rot) const {
return !(*this == rot);
}
// MARK: Helper Functions // MARK: Helper Functions
//! Look from a specific point in space to another point in space (Y-locked) //! Look from a specific point in space to another point in space
NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) { NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
//To make sure we don't orient around the X/Z axis: //To make sure we don't orient around the X/Z axis:
NiPoint3 source = sourcePoint; NiPoint3 source = sourcePoint;
@@ -42,7 +136,7 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
NiPoint3 forwardVector = NiPoint3(dest - source).Unitize(); NiPoint3 forwardVector = NiPoint3(dest - source).Unitize();
NiPoint3 posZ = NiPoint3Constant::UNIT_Z; NiPoint3 posZ = NiPoint3::UNIT_Z;
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize(); NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
float dot = posZ.DotProduct(forwardVector); float dot = posZ.DotProduct(forwardVector);
@@ -54,11 +148,10 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle); return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
} }
//! Look from a specific point in space to another point in space
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) { NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize(); NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
NiPoint3 posZ = NiPoint3Constant::UNIT_Z; NiPoint3 posZ = NiPoint3::UNIT_Z;
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize(); NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
float dot = posZ.DotProduct(forwardVector); float dot = posZ.DotProduct(forwardVector);

View File

@@ -1,5 +1,4 @@
#ifndef __NIQUATERNION_H__ #pragma once
#define __NIQUATERNION_H__
// Custom Classes // Custom Classes
#include "NiPoint3.h" #include "NiPoint3.h"
@@ -15,14 +14,14 @@ typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version o
//! A class that defines a rotation in space //! A class that defines a rotation in space
class NiQuaternion { class NiQuaternion {
public: public:
float w{ 1 }; //!< The w coordinate float w; //!< The w coordinate
float x{ 0 }; //!< The x coordinate float x; //!< The x coordinate
float y{ 0 }; //!< The y coordinate float y; //!< The y coordinate
float z{ 0 }; //!< The z coordinate float z; //!< The z coordinate
//! The initializer //! The initializer
constexpr NiQuaternion() = default; NiQuaternion(void);
//! The initializer //! The initializer
/*! /*!
@@ -31,12 +30,13 @@ public:
\param y The y coordinate \param y The y coordinate
\param z The z coordinate \param z The z coordinate
*/ */
constexpr NiQuaternion(const float w, const float x, const float y, const float z) noexcept NiQuaternion(float w, float x, float y, float z);
: w{ w }
, x{ x } //! Destructor
, y{ y } ~NiQuaternion(void);
, z{ z } {
} // MARK: Constants
static const NiQuaternion IDENTITY; //!< Quaternion(1, 0, 0, 0)
// MARK: Setters / Getters // MARK: Setters / Getters
@@ -44,49 +44,50 @@ public:
/*! /*!
\return The w coordinate \return The w coordinate
*/ */
[[nodiscard]] constexpr float GetW() const noexcept; float GetW(void) const;
//! Sets the W coordinate //! Sets the W coordinate
/*! /*!
\param w The w coordinate \param w The w coordinate
*/ */
constexpr void SetW(const float w) noexcept; void SetW(float w);
//! Gets the X coordinate //! Gets the X coordinate
/*! /*!
\return The x coordinate \return The x coordinate
*/ */
[[nodiscard]] constexpr float GetX() const noexcept; float GetX(void) const;
//! Sets the X coordinate //! Sets the X coordinate
/*! /*!
\param x The x coordinate \param x The x coordinate
*/ */
constexpr void SetX(const float x) noexcept; void SetX(float x);
//! Gets the Y coordinate //! Gets the Y coordinate
/*! /*!
\return The y coordinate \return The y coordinate
*/ */
[[nodiscard]] constexpr float GetY() const noexcept; float GetY(void) const;
//! Sets the Y coordinate //! Sets the Y coordinate
/*! /*!
\param y The y coordinate \param y The y coordinate
*/ */
constexpr void SetY(const float y) noexcept; void SetY(float y);
//! Gets the Z coordinate //! Gets the Z coordinate
/*! /*!
\return The z coordinate \return The z coordinate
*/ */
[[nodiscard]] constexpr float GetZ() const noexcept; float GetZ(void) const;
//! Sets the Z coordinate //! Sets the Z coordinate
/*! /*!
\param z The z coordinate \param z The z coordinate
*/ */
constexpr void SetZ(const float z) noexcept; void SetZ(float z);
// MARK: Member Functions // MARK: Member Functions
@@ -94,29 +95,31 @@ public:
/*! /*!
\return The forward vector of the quaternion \return The forward vector of the quaternion
*/ */
[[nodiscard]] constexpr Vector3 GetForwardVector() const noexcept; Vector3 GetForwardVector(void) const;
//! Returns the up vector from the quaternion //! Returns the up vector from the quaternion
/*! /*!
\return The up vector fo the quaternion \return The up vector fo the quaternion
*/ */
[[nodiscard]] constexpr Vector3 GetUpVector() const noexcept; Vector3 GetUpVector(void) const;
//! Returns the right vector from the quaternion //! Returns the right vector from the quaternion
/*! /*!
\return The right vector of the quaternion \return The right vector of the quaternion
*/ */
[[nodiscard]] constexpr Vector3 GetRightVector() const noexcept; Vector3 GetRightVector(void) const;
Vector3 GetEulerAngles() const;
[[nodiscard]] Vector3 GetEulerAngles() const;
// MARK: Operators // MARK: Operators
//! Operator to check for equality //! Operator to check for equality
constexpr bool operator==(const NiQuaternion& rot) const noexcept; bool operator==(const NiQuaternion& rot) const;
//! Operator to check for inequality //! Operator to check for inequality
constexpr bool operator!=(const NiQuaternion& rot) const noexcept; bool operator!=(const NiQuaternion& rot) const;
// MARK: Helper Functions // MARK: Helper Functions
@@ -126,7 +129,7 @@ public:
\param destPoint The destination location \param destPoint The destination location
\return The Quaternion with the rotation towards the destination \return The Quaternion with the rotation towards the destination
*/ */
[[nodiscard]] static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint); static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Look from a specific point in space to another point in space //! Look from a specific point in space to another point in space
/*! /*!
@@ -134,7 +137,7 @@ public:
\param destPoint The destination location \param destPoint The destination location
\return The Quaternion with the rotation towards the destination \return The Quaternion with the rotation towards the destination
*/ */
[[nodiscard]] static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint); static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Creates a Quaternion from a specific axis and angle relative to that axis //! Creates a Quaternion from a specific axis and angle relative to that axis
/*! /*!
@@ -142,17 +145,7 @@ public:
\param angle The angle relative to this axis \param angle The angle relative to this axis
\return A quaternion created from the axis and angle \return A quaternion created from the axis and angle
*/ */
[[nodiscard]] static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle); static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle);
[[nodiscard]] static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles); static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
}; };
// Static Variables
namespace NiQuaternionConstant {
constexpr NiQuaternion IDENTITY(1, 0, 0, 0);
}
// Include constexpr and inline function definitions in a seperate file for readability
#include "NiQuaternion.inl"
#endif // !__NIQUATERNION_H__

View File

@@ -1,75 +0,0 @@
#pragma once
#ifndef __NIQUATERNION_H__
#error "This should only be included inline in NiQuaternion.h: Do not include directly!"
#endif
// MARK: Setters / Getters
//! Gets the W coordinate
constexpr float NiQuaternion::GetW() const noexcept {
return this->w;
}
//! Sets the W coordinate
constexpr void NiQuaternion::SetW(const float w) noexcept {
this->w = w;
}
//! Gets the X coordinate
constexpr float NiQuaternion::GetX() const noexcept {
return this->x;
}
//! Sets the X coordinate
constexpr void NiQuaternion::SetX(const float x) noexcept {
this->x = x;
}
//! Gets the Y coordinate
constexpr float NiQuaternion::GetY() const noexcept {
return this->y;
}
//! Sets the Y coordinate
constexpr void NiQuaternion::SetY(const float y) noexcept {
this->y = y;
}
//! Gets the Z coordinate
constexpr float NiQuaternion::GetZ() const noexcept {
return this->z;
}
//! Sets the Z coordinate
constexpr void NiQuaternion::SetZ(const float z) noexcept {
this->z = z;
}
// MARK: Member Functions
//! Returns the forward vector from the quaternion
constexpr Vector3 NiQuaternion::GetForwardVector() const noexcept {
return Vector3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
}
//! Returns the up vector from the quaternion
constexpr Vector3 NiQuaternion::GetUpVector() const noexcept {
return Vector3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
}
//! Returns the right vector from the quaternion
constexpr Vector3 NiQuaternion::GetRightVector() const noexcept {
return Vector3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
}
// MARK: Operators
//! Operator to check for equality
constexpr bool NiQuaternion::operator==(const NiQuaternion& rot) const noexcept {
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
}
//! Operator to check for inequality
constexpr bool NiQuaternion::operator!=(const NiQuaternion& rot) const noexcept {
return !(*this == rot);
}

View File

@@ -1,50 +0,0 @@
#ifndef __POSITIONUPDATE__H__
#define __POSITIONUPDATE__H__
#include "NiPoint3.h"
#include "NiQuaternion.h"
struct RemoteInputInfo {
RemoteInputInfo() {
m_RemoteInputX = 0;
m_RemoteInputY = 0;
m_IsPowersliding = false;
m_IsModified = false;
}
void operator=(const RemoteInputInfo& other) {
m_RemoteInputX = other.m_RemoteInputX;
m_RemoteInputY = other.m_RemoteInputY;
m_IsPowersliding = other.m_IsPowersliding;
m_IsModified = other.m_IsModified;
}
bool operator==(const RemoteInputInfo& other) {
return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified;
}
float m_RemoteInputX;
float m_RemoteInputY;
bool m_IsPowersliding;
bool m_IsModified;
};
struct LocalSpaceInfo {
LWOOBJID objectId = LWOOBJID_EMPTY;
NiPoint3 position = NiPoint3Constant::ZERO;
NiPoint3 linearVelocity = NiPoint3Constant::ZERO;
};
struct PositionUpdate {
NiPoint3 position = NiPoint3Constant::ZERO;
NiQuaternion rotation = NiQuaternionConstant::IDENTITY;
bool onGround = false;
bool onRail = false;
NiPoint3 velocity = NiPoint3Constant::ZERO;
NiPoint3 angularVelocity = NiPoint3Constant::ZERO;
LocalSpaceInfo localSpaceInfo;
RemoteInputInfo remoteInputInfo;
};
#endif //!__POSITIONUPDATE__H__

View File

@@ -1,6 +1,6 @@
#include "ZCompression.h" #include "ZCompression.h"
#include "zlib.h" #include <zlib.h>
namespace ZCompression { namespace ZCompression {
int32_t GetMaxCompressedLength(int32_t nLenSrc) { int32_t GetMaxCompressedLength(int32_t nLenSrc) {

View File

@@ -4,7 +4,7 @@
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "Logger.h"
#include "zlib.h" #include <zlib.h>
AssetManager::AssetManager(const std::filesystem::path& path) { AssetManager::AssetManager(const std::filesystem::path& path) {
if (!std::filesystem::is_directory(path)) { if (!std::filesystem::is_directory(path)) {

View File

@@ -9,15 +9,15 @@ namespace StringifiedEnum {
const std::string_view ToString(const T e) { const std::string_view ToString(const T e) {
static_assert(std::is_enum_v<T>, "Not an enum"); // Check type static_assert(std::is_enum_v<T>, "Not an enum"); // Check type
constexpr auto& sv = magic_enum::enum_entries<T>(); constexpr auto sv = &magic_enum::enum_entries<T>();
const auto it = std::lower_bound( const auto it = std::lower_bound(
sv.begin(), sv.end(), e, sv->begin(), sv->end(), e,
[&](const std::pair<T, std::string_view>& lhs, const T rhs) { return lhs.first < rhs; } [&](const std::pair<T, std::string_view>& lhs, const T rhs) { return lhs.first < rhs; }
); );
std::string_view output; std::string_view output;
if (it != sv.end() && it->first == e) { if (it != sv->end() && it->first == e) {
output = it->second; output = it->second;
} else { } else {
output = "UNKNOWN"; output = "UNKNOWN";

View File

@@ -130,7 +130,7 @@ public:
LWOOBJID friendID; LWOOBJID friendID;
std::string friendName; std::string friendName;
void Serialize(RakNet::BitStream& bitStream) const { void Serialize(RakNet::BitStream& bitStream) {
bitStream.Write<uint8_t>(isOnline); bitStream.Write<uint8_t>(isOnline);
bitStream.Write<uint8_t>(isBestFriend); bitStream.Write<uint8_t>(isBestFriend);
bitStream.Write<uint8_t>(isFTP); bitStream.Write<uint8_t>(isFTP);

View File

@@ -629,7 +629,7 @@ enum class eGameMessageType : uint16_t {
GET_INSTRUCTION_COUNT = 676, GET_INSTRUCTION_COUNT = 676,
GET_IS_NPC = 677, GET_IS_NPC = 677,
ACTIVATE_BUBBLE_BUFF = 678, ACTIVATE_BUBBLE_BUFF = 678,
DECTIVATE_BUBBLE_BUFF = 679, // This is spelled wrong in the client, so we misspell it here. DECTIVATE_BUBBLE_BUFF = 679, // thanks netdevil
EXHIBIT_VOTE = 680, EXHIBIT_VOTE = 680,
ADD_PET_TO_PLAYER = 681, ADD_PET_TO_PLAYER = 681,
REMOVE_PET_FROM_PLAYER = 682, REMOVE_PET_FROM_PLAYER = 682,

View File

@@ -1,13 +0,0 @@
#ifndef __EPETABILITYTYPE__H__
#define __EPETABILITYTYPE__H__
#include <cstdint>
enum class ePetAbilityType : uint32_t {
Invalid,
GoToObject,
JumpOnObject,
DigAtPosition
};
#endif //!__EPETABILITYTYPE__H__

View File

@@ -4,13 +4,9 @@
// Static Variables // Static Variables
static CppSQLite3DB* conn = new CppSQLite3DB(); static CppSQLite3DB* conn = new CppSQLite3DB();
// Status Variables
bool CDClientDatabase::isConnected = false;
//! Opens a connection with the CDClient //! Opens a connection with the CDClient
void CDClientDatabase::Connect(const std::string& filename) { void CDClientDatabase::Connect(const std::string& filename) {
conn->open(filename.c_str()); conn->open(filename.c_str());
isConnected = true;
} }
//! Queries the CDClient //! Queries the CDClient

View File

@@ -15,10 +15,6 @@
//! The CDClient Database namespace //! The CDClient Database namespace
namespace CDClientDatabase { namespace CDClientDatabase {
/**
* Boolean defining the connection status of CDClient
*/
extern bool isConnected;
//! Opens a connection with the CDClient //! Opens a connection with the CDClient
/*! /*!

View File

@@ -3,7 +3,6 @@
#include "CDAnimationsTable.h" #include "CDAnimationsTable.h"
#include "CDBehaviorParameterTable.h" #include "CDBehaviorParameterTable.h"
#include "CDBehaviorTemplateTable.h" #include "CDBehaviorTemplateTable.h"
#include "CDClientDatabase.h"
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
#include "CDCurrencyTableTable.h" #include "CDCurrencyTableTable.h"
#include "CDDestructibleComponentTable.h" #include "CDDestructibleComponentTable.h"
@@ -40,8 +39,6 @@
#include "CDRailActivatorComponent.h" #include "CDRailActivatorComponent.h"
#include "CDRewardCodesTable.h" #include "CDRewardCodesTable.h"
#include <exception>
#ifndef CDCLIENT_CACHE_ALL #ifndef CDCLIENT_CACHE_ALL
// Uncomment this to cache the full cdclient database into memory. This will make the server load faster, but will use more memory. // Uncomment this to cache the full cdclient database into memory. This will make the server load faster, but will use more memory.
// A vanilla CDClient takes about 46MB of memory + the regular world data. // A vanilla CDClient takes about 46MB of memory + the regular world data.
@@ -54,16 +51,7 @@
#define CDCLIENT_DONT_CACHE_TABLE(x) #define CDCLIENT_DONT_CACHE_TABLE(x)
#endif #endif
class CDClientConnectionException : public std::exception { CDClientManager::CDClientManager() {
public:
virtual const char* what() const throw() {
return "CDClientDatabase is not connected!";
}
};
void CDClientManager::LoadValuesFromDatabase() {
if (!CDClientDatabase::isConnected) throw CDClientConnectionException();
CDActivityRewardsTable::Instance().LoadValuesFromDatabase(); CDActivityRewardsTable::Instance().LoadValuesFromDatabase();
CDActivitiesTable::Instance().LoadValuesFromDatabase(); CDActivitiesTable::Instance().LoadValuesFromDatabase();
CDCLIENT_DONT_CACHE_TABLE(CDAnimationsTable::Instance().LoadValuesFromDatabase()); CDCLIENT_DONT_CACHE_TABLE(CDAnimationsTable::Instance().LoadValuesFromDatabase());
@@ -91,7 +79,6 @@ void CDClientManager::LoadValuesFromDatabase() {
CDCLIENT_DONT_CACHE_TABLE(CDObjectsTable::Instance().LoadValuesFromDatabase()); CDCLIENT_DONT_CACHE_TABLE(CDObjectsTable::Instance().LoadValuesFromDatabase());
CDPhysicsComponentTable::Instance().LoadValuesFromDatabase(); CDPhysicsComponentTable::Instance().LoadValuesFromDatabase();
CDPackageComponentTable::Instance().LoadValuesFromDatabase(); CDPackageComponentTable::Instance().LoadValuesFromDatabase();
CDPetComponentTable::Instance().LoadValuesFromDatabase();
CDProximityMonitorComponentTable::Instance().LoadValuesFromDatabase(); CDProximityMonitorComponentTable::Instance().LoadValuesFromDatabase();
CDPropertyEntranceComponentTable::Instance().LoadValuesFromDatabase(); CDPropertyEntranceComponentTable::Instance().LoadValuesFromDatabase();
CDPropertyTemplateTable::Instance().LoadValuesFromDatabase(); CDPropertyTemplateTable::Instance().LoadValuesFromDatabase();
@@ -105,9 +92,3 @@ void CDClientManager::LoadValuesFromDatabase() {
CDVendorComponentTable::Instance().LoadValuesFromDatabase(); CDVendorComponentTable::Instance().LoadValuesFromDatabase();
CDZoneTableTable::Instance().LoadValuesFromDatabase(); CDZoneTableTable::Instance().LoadValuesFromDatabase();
} }
void CDClientManager::LoadValuesFromDefaults() {
LOG("Loading default CDClient tables!");
CDPetComponentTable::Instance().LoadValuesFromDefaults();
}

View File

@@ -11,10 +11,7 @@
*/ */
class CDClientManager : public Singleton<CDClientManager> { class CDClientManager : public Singleton<CDClientManager> {
public: public:
CDClientManager() = default; CDClientManager();
void LoadValuesFromDatabase();
void LoadValuesFromDefaults();
/** /**
* Fetch a table from CDClient * Fetch a table from CDClient

View File

@@ -2,7 +2,7 @@
void CDActivitiesTable::LoadValuesFromDatabase() { void CDActivitiesTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Activities"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Activities");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,22 +4,22 @@
#include "CDTable.h" #include "CDTable.h"
struct CDActivities { struct CDActivities {
uint32_t ActivityID; unsigned int ActivityID;
uint32_t locStatus; unsigned int locStatus;
uint32_t instanceMapID; unsigned int instanceMapID;
uint32_t minTeams; unsigned int minTeams;
uint32_t maxTeams; unsigned int maxTeams;
uint32_t minTeamSize; unsigned int minTeamSize;
uint32_t maxTeamSize; unsigned int maxTeamSize;
uint32_t waitTime; unsigned int waitTime;
uint32_t startDelay; unsigned int startDelay;
bool requiresUniqueData; bool requiresUniqueData;
uint32_t leaderboardType; unsigned int leaderboardType;
bool localize; bool localize;
int32_t optionalCostLOT; int optionalCostLOT;
int32_t optionalCostCount; int optionalCostCount;
bool showUIRewards; bool showUIRewards;
uint32_t CommunityActivityFlagID; unsigned int CommunityActivityFlagID;
std::string gate_version; std::string gate_version;
bool noTeamLootOnDeath; bool noTeamLootOnDeath;
float optionalPercentage; float optionalPercentage;

View File

@@ -3,7 +3,7 @@
void CDActivityRewardsTable::LoadValuesFromDatabase() { void CDActivityRewardsTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ActivityRewards"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ActivityRewards");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,12 +4,12 @@
#include "CDTable.h" #include "CDTable.h"
struct CDActivityRewards { struct CDActivityRewards {
uint32_t objectTemplate; //!< The object template (?) unsigned int objectTemplate; //!< The object template (?)
uint32_t ActivityRewardIndex; //!< The activity reward index unsigned int ActivityRewardIndex; //!< The activity reward index
int32_t activityRating; //!< The activity rating int activityRating; //!< The activity rating
uint32_t LootMatrixIndex; //!< The loot matrix index unsigned int LootMatrixIndex; //!< The loot matrix index
uint32_t CurrencyIndex; //!< The currency index unsigned int CurrencyIndex; //!< The currency index
uint32_t ChallengeRating; //!< The challenge rating unsigned int ChallengeRating; //!< The challenge rating
std::string description; //!< The description std::string description; //!< The description
}; };

View File

@@ -4,13 +4,13 @@
#include <list> #include <list>
struct CDAnimation { struct CDAnimation {
// uint32_t animationGroupID; // unsigned int animationGroupID;
// std::string animation_type; // std::string animation_type;
// The above two are a pair to represent a primary key in the map. // The above two are a pair to represent a primary key in the map.
std::string animation_name; //!< The animation name std::string animation_name; //!< The animation name
float chance_to_play; //!< The chance to play the animation float chance_to_play; //!< The chance to play the animation
UNUSED_COLUMN(uint32_t min_loops;) //!< The minimum number of loops UNUSED_COLUMN(unsigned int min_loops;) //!< The minimum number of loops
UNUSED_COLUMN(uint32_t max_loops;) //!< The maximum number of loops UNUSED_COLUMN(unsigned int max_loops;) //!< The maximum number of loops
float animation_length; //!< The animation length float animation_length; //!< The animation length
UNUSED_COLUMN(bool hideEquip;) //!< Whether or not to hide the equip UNUSED_COLUMN(bool hideEquip;) //!< Whether or not to hide the equip
UNUSED_COLUMN(bool ignoreUpperBody;) //!< Whether or not to ignore the upper body UNUSED_COLUMN(bool ignoreUpperBody;) //!< Whether or not to ignore the upper body

View File

@@ -3,7 +3,7 @@
void CDBehaviorTemplateTable::LoadValuesFromDatabase() { void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BehaviorTemplate"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BehaviorTemplate");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -6,9 +6,9 @@
#include <unordered_set> #include <unordered_set>
struct CDBehaviorTemplate { struct CDBehaviorTemplate {
uint32_t behaviorID; //!< The Behavior ID unsigned int behaviorID; //!< The Behavior ID
uint32_t templateID; //!< The Template ID (LOT) unsigned int templateID; //!< The Template ID (LOT)
uint32_t effectID; //!< The Effect ID attached unsigned int effectID; //!< The Effect ID attached
std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle
}; };

View File

@@ -3,7 +3,7 @@
void CDBrickIDTableTable::LoadValuesFromDatabase() { void CDBrickIDTableTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BrickIDTable"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BrickIDTable");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -10,8 +10,8 @@
//! BrickIDTable Entry Struct //! BrickIDTable Entry Struct
struct CDBrickIDTable { struct CDBrickIDTable {
uint32_t NDObjectID; unsigned int NDObjectID;
uint32_t LEGOBrickID; unsigned int LEGOBrickID;
}; };

View File

@@ -7,9 +7,9 @@
enum class eReplicaComponentType : uint32_t; enum class eReplicaComponentType : uint32_t;
struct CDComponentsRegistry { struct CDComponentsRegistry {
uint32_t id; //!< The LOT is used as the ID unsigned int id; //!< The LOT is used as the ID
eReplicaComponentType component_type; //!< See ComponentTypes enum for values eReplicaComponentType component_type; //!< See ComponentTypes enum for values
uint32_t component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0 unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0
}; };

View File

@@ -4,7 +4,7 @@
void CDCurrencyTableTable::LoadValuesFromDatabase() { void CDCurrencyTableTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM CurrencyTable"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM CurrencyTable");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -10,11 +10,11 @@
//! CurrencyTable Struct //! CurrencyTable Struct
struct CDCurrencyTable { struct CDCurrencyTable {
uint32_t currencyIndex; //!< The Currency Index unsigned int currencyIndex; //!< The Currency Index
uint32_t npcminlevel; //!< The minimum level of the npc unsigned int npcminlevel; //!< The minimum level of the npc
uint32_t minvalue; //!< The minimum currency unsigned int minvalue; //!< The minimum currency
uint32_t maxvalue; //!< The maximum currency unsigned int maxvalue; //!< The maximum currency
uint32_t id; //!< The ID of the currency index unsigned int id; //!< The ID of the currency index
}; };
//! CurrencyTable table //! CurrencyTable table

View File

@@ -2,7 +2,7 @@
void CDDestructibleComponentTable::LoadValuesFromDatabase() { void CDDestructibleComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,20 +4,20 @@
#include "CDTable.h" #include "CDTable.h"
struct CDDestructibleComponent { struct CDDestructibleComponent {
uint32_t id; //!< The component ID from the ComponentsRegistry Table unsigned int id; //!< The component ID from the ComponentsRegistry Table
int32_t faction; //!< The Faction ID of the object int faction; //!< The Faction ID of the object
std::string factionList; //!< A list of the faction IDs std::string factionList; //!< A list of the faction IDs
int32_t life; //!< The amount of life of the object int life; //!< The amount of life of the object
uint32_t imagination; //!< The amount of imagination of the object unsigned int imagination; //!< The amount of imagination of the object
int32_t LootMatrixIndex; //!< The Loot Matrix Index int LootMatrixIndex; //!< The Loot Matrix Index
int32_t CurrencyIndex; //!< The Currency Index int CurrencyIndex; //!< The Currency Index
uint32_t level; //!< ??? unsigned int level; //!< ???
float armor; //!< The amount of armor of the object float armor; //!< The amount of armor of the object
uint32_t death_behavior; //!< The behavior ID of the death behavior unsigned int death_behavior; //!< The behavior ID of the death behavior
bool isnpc; //!< Whether or not the object is an NPC bool isnpc; //!< Whether or not the object is an NPC
uint32_t attack_priority; //!< ??? unsigned int attack_priority; //!< ???
bool isSmashable; //!< Whether or not the object is smashable bool isSmashable; //!< Whether or not the object is smashable
int32_t difficultyLevel; //!< ??? int difficultyLevel; //!< ???
}; };
class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable> { class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable> {

View File

@@ -20,7 +20,7 @@ void CDEmoteTableTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
CDEmoteTable* CDEmoteTableTable::GetEmote(int32_t id) { CDEmoteTable* CDEmoteTableTable::GetEmote(int id) {
auto itr = entries.find(id); auto itr = entries.find(id);
return itr != entries.end() ? &itr->second : nullptr; return itr != entries.end() ? &itr->second : nullptr;
} }

View File

@@ -16,11 +16,11 @@ struct CDEmoteTable {
gateVersion = ""; gateVersion = "";
} }
int32_t ID; int ID;
std::string animationName; std::string animationName;
std::string iconFilename; std::string iconFilename;
int32_t locState; int locState;
int32_t channel; int channel;
bool locked; bool locked;
bool localize; bool localize;
std::string gateVersion; std::string gateVersion;
@@ -33,5 +33,5 @@ private:
public: public:
void LoadValuesFromDatabase(); void LoadValuesFromDatabase();
// Returns an emote by ID // Returns an emote by ID
CDEmoteTable* GetEmote(int32_t id); CDEmoteTable* GetEmote(int id);
}; };

View File

@@ -3,7 +3,7 @@
void CDFeatureGatingTable::LoadValuesFromDatabase() { void CDFeatureGatingTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM FeatureGating"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM FeatureGating");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -3,7 +3,7 @@
void CDInventoryComponentTable::LoadValuesFromDatabase() { void CDInventoryComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM InventoryComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM InventoryComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,9 +4,9 @@
#include "CDTable.h" #include "CDTable.h"
struct CDInventoryComponent { struct CDInventoryComponent {
uint32_t id; //!< The component ID for this object unsigned int id; //!< The component ID for this object
uint32_t itemid; //!< The LOT of the object unsigned int itemid; //!< The LOT of the object
uint32_t count; //!< The count of the items the object has unsigned int count; //!< The count of the items the object has
bool equip; //!< Whether or not to equip the item bool equip; //!< Whether or not to equip the item
}; };

View File

@@ -5,7 +5,7 @@ CDItemComponent CDItemComponentTable::Default = {};
void CDItemComponentTable::LoadValuesFromDatabase() { void CDItemComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);
@@ -69,7 +69,7 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t skillID) { const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int skillID) {
const auto& it = this->entries.find(skillID); const auto& it = this->entries.find(skillID);
if (it != this->entries.end()) { if (it != this->entries.end()) {
return it->second; return it->second;

View File

@@ -5,60 +5,60 @@
#include "dCommonVars.h" #include "dCommonVars.h"
struct CDItemComponent { struct CDItemComponent {
uint32_t id; //!< The Component ID unsigned int id; //!< The Component ID
std::string equipLocation; //!< The equip location std::string equipLocation; //!< The equip location
uint32_t baseValue; //!< The monetary base value of the item unsigned int baseValue; //!< The monetary base value of the item
bool isKitPiece; //!< Whether or not the item belongs to a kit bool isKitPiece; //!< Whether or not the item belongs to a kit
uint32_t rarity; //!< The rarity of the item unsigned int rarity; //!< The rarity of the item
uint32_t itemType; //!< The item type unsigned int itemType; //!< The item type
int64_t itemInfo; //!< The item info int64_t itemInfo; //!< The item info
bool inLootTable; //!< Whether or not the item is in a loot table bool inLootTable; //!< Whether or not the item is in a loot table
bool inVendor; //!< Whether or not the item is in a vendor inventory bool inVendor; //!< Whether or not the item is in a vendor inventory
bool isUnique; //!< ??? bool isUnique; //!< ???
bool isBOP; //!< ??? bool isBOP; //!< ???
bool isBOE; //!< ??? bool isBOE; //!< ???
uint32_t reqFlagID; //!< User must have completed this flag to get the item unsigned int reqFlagID; //!< User must have completed this flag to get the item
uint32_t reqSpecialtyID; //!< ??? unsigned int reqSpecialtyID; //!< ???
uint32_t reqSpecRank; //!< ??? unsigned int reqSpecRank; //!< ???
uint32_t reqAchievementID; //!< The required achievement must be completed unsigned int reqAchievementID; //!< The required achievement must be completed
uint32_t stackSize; //!< The stack size of the item unsigned int stackSize; //!< The stack size of the item
uint32_t color1; //!< Something to do with item color... unsigned int color1; //!< Something to do with item color...
uint32_t decal; //!< The decal of the item unsigned int decal; //!< The decal of the item
uint32_t offsetGroupID; //!< Something to do with group IDs unsigned int offsetGroupID; //!< Something to do with group IDs
uint32_t buildTypes; //!< Something to do with building unsigned int buildTypes; //!< Something to do with building
std::string reqPrecondition; //!< The required precondition std::string reqPrecondition; //!< The required precondition
uint32_t animationFlag; //!< The Animation Flag unsigned int animationFlag; //!< The Animation Flag
uint32_t equipEffects; //!< The effect played when the item is equipped unsigned int equipEffects; //!< The effect played when the item is equipped
bool readyForQA; //!< ??? bool readyForQA; //!< ???
uint32_t itemRating; //!< ??? unsigned int itemRating; //!< ???
bool isTwoHanded; //!< Whether or not the item is double handed bool isTwoHanded; //!< Whether or not the item is double handed
uint32_t minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object? unsigned int minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object?
uint32_t delResIndex; //!< ??? unsigned int delResIndex; //!< ???
uint32_t currencyLOT; //!< ??? unsigned int currencyLOT; //!< ???
uint32_t altCurrencyCost; //!< ??? unsigned int altCurrencyCost; //!< ???
std::string subItems; //!< A comma seperate string of sub items (maybe for multi-itemed things like faction test gear set) std::string subItems; //!< A comma seperate string of sub items (maybe for multi-itemed things like faction test gear set)
UNUSED(std::string audioEventUse); //!< ??? UNUSED(std::string audioEventUse); //!< ???
bool noEquipAnimation; //!< Whether or not there is an equip animation bool noEquipAnimation; //!< Whether or not there is an equip animation
uint32_t commendationLOT; //!< The commendation LOT unsigned int commendationLOT; //!< The commendation LOT
uint32_t commendationCost; //!< The commendation cost unsigned int commendationCost; //!< The commendation cost
UNUSED(std::string audioEquipMetaEventSet); //!< ??? UNUSED(std::string audioEquipMetaEventSet); //!< ???
std::string currencyCosts; //!< Used for crafting std::string currencyCosts; //!< Used for crafting
UNUSED(std::string ingredientInfo); //!< Unused UNUSED(std::string ingredientInfo); //!< Unused
uint32_t locStatus; //!< ??? unsigned int locStatus; //!< ???
uint32_t forgeType; //!< Forge Type unsigned int forgeType; //!< Forge Type
float SellMultiplier; //!< Something to do with early vendors perhaps (but replaced) float SellMultiplier; //!< Something to do with early vendors perhaps (but replaced)
}; };
class CDItemComponentTable : public CDTable<CDItemComponentTable> { class CDItemComponentTable : public CDTable<CDItemComponentTable> {
private: private:
std::map<uint32_t, CDItemComponent> entries; std::map<unsigned int, CDItemComponent> entries;
public: public:
void LoadValuesFromDatabase(); void LoadValuesFromDatabase();
static std::map<LOT, uint32_t> ParseCraftingCurrencies(const CDItemComponent& itemComponent); static std::map<LOT, uint32_t> ParseCraftingCurrencies(const CDItemComponent& itemComponent);
// Gets an entry by ID // Gets an entry by ID
const CDItemComponent& GetItemComponentByID(uint32_t skillID); const CDItemComponent& GetItemComponentByID(unsigned int skillID);
static CDItemComponent Default; static CDItemComponent Default;
}; };

View File

@@ -3,7 +3,7 @@
void CDItemSetSkillsTable::LoadValuesFromDatabase() { void CDItemSetSkillsTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemSetSkills"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemSetSkills");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);
@@ -44,7 +44,7 @@ const std::vector<CDItemSetSkills>& CDItemSetSkillsTable::GetEntries() const {
return this->entries; return this->entries;
} }
std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetBySkillID(uint32_t SkillSetID) { std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetBySkillID(unsigned int SkillSetID) {
std::vector<CDItemSetSkills> toReturn; std::vector<CDItemSetSkills> toReturn;
for (CDItemSetSkills entry : this->entries) { for (CDItemSetSkills entry : this->entries) {

View File

@@ -4,9 +4,9 @@
#include "CDTable.h" #include "CDTable.h"
struct CDItemSetSkills { struct CDItemSetSkills {
uint32_t SkillSetID; //!< The skill set ID unsigned int SkillSetID; //!< The skill set ID
uint32_t SkillID; //!< The skill ID unsigned int SkillID; //!< The skill ID
uint32_t SkillCastType; //!< The skill cast type unsigned int SkillCastType; //!< The skill cast type
}; };
class CDItemSetSkillsTable : public CDTable<CDItemSetSkillsTable> { class CDItemSetSkillsTable : public CDTable<CDItemSetSkillsTable> {
@@ -20,5 +20,5 @@ public:
const std::vector<CDItemSetSkills>& GetEntries() const; const std::vector<CDItemSetSkills>& GetEntries() const;
std::vector<CDItemSetSkills> GetBySkillID(uint32_t SkillSetID); std::vector<CDItemSetSkills> GetBySkillID(unsigned int SkillSetID);
}; };

View File

@@ -3,7 +3,7 @@
void CDItemSetsTable::LoadValuesFromDatabase() { void CDItemSetsTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemSets"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemSets");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,20 +4,20 @@
#include "CDTable.h" #include "CDTable.h"
struct CDItemSets { struct CDItemSets {
uint32_t setID; //!< The item set ID unsigned int setID; //!< The item set ID
uint32_t locStatus; //!< The loc status unsigned int locStatus; //!< The loc status
std::string itemIDs; //!< THe item IDs std::string itemIDs; //!< THe item IDs
uint32_t kitType; //!< The item kit type unsigned int kitType; //!< The item kit type
uint32_t kitRank; //!< The item kit rank unsigned int kitRank; //!< The item kit rank
uint32_t kitImage; //!< The item kit image unsigned int kitImage; //!< The item kit image
uint32_t skillSetWith2; //!< The skill set with 2 unsigned int skillSetWith2; //!< The skill set with 2
uint32_t skillSetWith3; //!< The skill set with 3 unsigned int skillSetWith3; //!< The skill set with 3
uint32_t skillSetWith4; //!< The skill set with 4 unsigned int skillSetWith4; //!< The skill set with 4
uint32_t skillSetWith5; //!< The skill set with 5 unsigned int skillSetWith5; //!< The skill set with 5
uint32_t skillSetWith6; //!< The skill set with 6 unsigned int skillSetWith6; //!< The skill set with 6
bool localize; //!< Whether or localize bool localize; //!< Whether or localize
std::string gate_version; //!< The gate version std::string gate_version; //!< The gate version
uint32_t kitID; //!< The kit ID unsigned int kitID; //!< The kit ID
float priority; //!< The priority float priority; //!< The priority
}; };

View File

@@ -3,7 +3,7 @@
void CDLevelProgressionLookupTable::LoadValuesFromDatabase() { void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM LevelProgressionLookup"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM LevelProgressionLookup");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,8 +4,8 @@
#include "CDTable.h" #include "CDTable.h"
struct CDLevelProgressionLookup { struct CDLevelProgressionLookup {
uint32_t id; //!< The Level ID unsigned int id; //!< The Level ID
uint32_t requiredUScore; //!< The required LEGO Score unsigned int requiredUScore; //!< The required LEGO Score
std::string BehaviorEffect; //!< The behavior effect attached to this std::string BehaviorEffect; //!< The behavior effect attached to this
}; };

View File

@@ -16,7 +16,7 @@ CDLootMatrix CDLootMatrixTable::ReadRow(CppSQLite3Query& tableData) const {
void CDLootMatrixTable::LoadValuesFromDatabase() { void CDLootMatrixTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM LootMatrix"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM LootMatrix");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,12 +4,12 @@
#include "CDTable.h" #include "CDTable.h"
struct CDLootMatrix { struct CDLootMatrix {
uint32_t LootTableIndex; //!< The Loot Table Index unsigned int LootTableIndex; //!< The Loot Table Index
uint32_t RarityTableIndex; //!< The Rarity Table Index unsigned int RarityTableIndex; //!< The Rarity Table Index
float percent; //!< The percent that this matrix is used? float percent; //!< The percent that this matrix is used?
uint32_t minToDrop; //!< The minimum amount of loot from this matrix to drop unsigned int minToDrop; //!< The minimum amount of loot from this matrix to drop
uint32_t maxToDrop; //!< The maximum amount of loot from this matrix to drop unsigned int maxToDrop; //!< The maximum amount of loot from this matrix to drop
uint32_t flagID; //!< ??? unsigned int flagID; //!< ???
UNUSED(std::string gate_version); //!< The Gate Version UNUSED(std::string gate_version); //!< The Gate Version
}; };

View File

@@ -40,7 +40,7 @@ CDLootTable CDLootTableTable::ReadRow(CppSQLite3Query& tableData) const {
void CDLootTableTable::LoadValuesFromDatabase() { void CDLootTableTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM LootTable"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM LootTable");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,10 +4,10 @@
#include "CDTable.h" #include "CDTable.h"
struct CDLootTable { struct CDLootTable {
uint32_t itemid; //!< The LOT of the item unsigned int itemid; //!< The LOT of the item
uint32_t LootTableIndex; //!< The Loot Table Index unsigned int LootTableIndex; //!< The Loot Table Index
bool MissionDrop; //!< Whether or not this loot table is a mission drop bool MissionDrop; //!< Whether or not this loot table is a mission drop
uint32_t sortPriority; //!< The sorting priority unsigned int sortPriority; //!< The sorting priority
}; };
typedef uint32_t LootTableIndex; typedef uint32_t LootTableIndex;

View File

@@ -3,7 +3,7 @@
void CDMissionEmailTable::LoadValuesFromDatabase() { void CDMissionEmailTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionEmail"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionEmail");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,13 +4,13 @@
#include "CDTable.h" #include "CDTable.h"
struct CDMissionEmail { struct CDMissionEmail {
uint32_t ID; unsigned int ID;
uint32_t messageType; unsigned int messageType;
uint32_t notificationGroup; unsigned int notificationGroup;
uint32_t missionID; unsigned int missionID;
uint32_t attachmentLOT; unsigned int attachmentLOT;
bool localize; bool localize;
uint32_t locStatus; unsigned int locStatus;
std::string gate_version; std::string gate_version;
}; };

View File

@@ -3,7 +3,7 @@
void CDMissionNPCComponentTable::LoadValuesFromDatabase() { void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionNPCComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionNPCComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,8 +4,8 @@
#include "CDTable.h" #include "CDTable.h"
struct CDMissionNPCComponent { struct CDMissionNPCComponent {
uint32_t id; //!< The ID unsigned int id; //!< The ID
uint32_t missionID; //!< The Mission ID unsigned int missionID; //!< The Mission ID
bool offersMission; //!< Whether or not this NPC offers a mission bool offersMission; //!< Whether or not this NPC offers a mission
bool acceptsMission; //!< Whether or not this NPC accepts a mission bool acceptsMission; //!< Whether or not this NPC accepts a mission
std::string gate_version; //!< The gate version std::string gate_version; //!< The gate version

View File

@@ -3,7 +3,7 @@
void CDMissionTasksTable::LoadValuesFromDatabase() { void CDMissionTasksTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionTasks"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionTasks");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,17 +4,17 @@
#include "CDTable.h" #include "CDTable.h"
struct CDMissionTasks { struct CDMissionTasks {
uint32_t id; //!< The Mission ID that the task belongs to unsigned int id; //!< The Mission ID that the task belongs to
UNUSED(uint32_t locStatus); //!< ??? UNUSED(unsigned int locStatus); //!< ???
uint32_t taskType; //!< The task type unsigned int taskType; //!< The task type
uint32_t target; //!< The mission target unsigned int target; //!< The mission target
std::string targetGroup; //!< The mission target group std::string targetGroup; //!< The mission target group
int32_t targetValue; //!< The target value int targetValue; //!< The target value
std::string taskParam1; //!< The task param 1 std::string taskParam1; //!< The task param 1
UNUSED(std::string largeTaskIcon); //!< ??? UNUSED(std::string largeTaskIcon); //!< ???
UNUSED(uint32_t IconID); //!< ??? UNUSED(unsigned int IconID); //!< ???
uint32_t uid; //!< ??? unsigned int uid; //!< ???
UNUSED(uint32_t largeTaskIconID); //!< ??? UNUSED(unsigned int largeTaskIconID); //!< ???
UNUSED(bool localize); //!< Whether or not the task should be localized UNUSED(bool localize); //!< Whether or not the task should be localized
UNUSED(std::string gate_version); //!< ??? UNUSED(std::string gate_version); //!< ???
}; };

View File

@@ -5,7 +5,7 @@ CDMissions CDMissionsTable::Default = {};
void CDMissionsTable::LoadValuesFromDatabase() { void CDMissionsTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Missions"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Missions");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -6,58 +6,58 @@
#include <cstdint> #include <cstdint>
struct CDMissions { struct CDMissions {
int32_t id; //!< The Mission ID int id; //!< The Mission ID
std::string defined_type; //!< The type of mission std::string defined_type; //!< The type of mission
std::string defined_subtype; //!< The subtype of the mission std::string defined_subtype; //!< The subtype of the mission
int32_t UISortOrder; //!< The UI Sort Order for the mission int UISortOrder; //!< The UI Sort Order for the mission
int32_t offer_objectID; //!< The LOT of the mission giver int offer_objectID; //!< The LOT of the mission giver
int32_t target_objectID; //!< The LOT of the mission's target int target_objectID; //!< The LOT of the mission's target
int64_t reward_currency; //!< The amount of currency to reward the player int64_t reward_currency; //!< The amount of currency to reward the player
int32_t LegoScore; //!< The amount of LEGO Score to reward the player int LegoScore; //!< The amount of LEGO Score to reward the player
int64_t reward_reputation; //!< The reputation to award the player int64_t reward_reputation; //!< The reputation to award the player
bool isChoiceReward; //!< Whether or not the user has the option to choose their loot bool isChoiceReward; //!< Whether or not the user has the option to choose their loot
int32_t reward_item1; //!< The first rewarded item int reward_item1; //!< The first rewarded item
int32_t reward_item1_count; //!< The count of the first item to be rewarded int reward_item1_count; //!< The count of the first item to be rewarded
int32_t reward_item2; //!< The second rewarded item int reward_item2; //!< The second rewarded item
int32_t reward_item2_count; //!< The count of the second item to be rewarded int reward_item2_count; //!< The count of the second item to be rewarded
int32_t reward_item3; //!< The third rewarded item int reward_item3; //!< The third rewarded item
int32_t reward_item3_count; //!< The count of the third item to be rewarded int reward_item3_count; //!< The count of the third item to be rewarded
int32_t reward_item4; //!< The fourth rewarded item int reward_item4; //!< The fourth rewarded item
int32_t reward_item4_count; //!< The count of the fourth item to be rewarded int reward_item4_count; //!< The count of the fourth item to be rewarded
int32_t reward_emote; //!< The first emote to be rewarded int reward_emote; //!< The first emote to be rewarded
int32_t reward_emote2; //!< The second emote to be rewarded int reward_emote2; //!< The second emote to be rewarded
int32_t reward_emote3; //!< The third emote to be rewarded int reward_emote3; //!< The third emote to be rewarded
int32_t reward_emote4; //!< The fourth emote to be rewarded int reward_emote4; //!< The fourth emote to be rewarded
int32_t reward_maximagination; //!< The amount of max imagination to reward int reward_maximagination; //!< The amount of max imagination to reward
int32_t reward_maxhealth; //!< The amount of max health to reward int reward_maxhealth; //!< The amount of max health to reward
int32_t reward_maxinventory; //!< The amount of max inventory to reward int reward_maxinventory; //!< The amount of max inventory to reward
int32_t reward_maxmodel; //!< ??? int reward_maxmodel; //!< ???
int32_t reward_maxwidget; //!< ??? int reward_maxwidget; //!< ???
int32_t reward_maxwallet; //!< ??? int reward_maxwallet; //!< ???
bool repeatable; //!< Whether or not this mission can be repeated (for instance, is it a daily mission) bool repeatable; //!< Whether or not this mission can be repeated (for instance, is it a daily mission)
int64_t reward_currency_repeatable; //!< The repeatable reward int64_t reward_currency_repeatable; //!< The repeatable reward
int32_t reward_item1_repeatable; //!< The first rewarded item int reward_item1_repeatable; //!< The first rewarded item
int32_t reward_item1_repeat_count; //!< The count of the first item to be rewarded int reward_item1_repeat_count; //!< The count of the first item to be rewarded
int32_t reward_item2_repeatable; //!< The second rewarded item int reward_item2_repeatable; //!< The second rewarded item
int32_t reward_item2_repeat_count; //!< The count of the second item to be rewarded int reward_item2_repeat_count; //!< The count of the second item to be rewarded
int32_t reward_item3_repeatable; //!< The third rewarded item int reward_item3_repeatable; //!< The third rewarded item
int32_t reward_item3_repeat_count; //!< The count of the third item to be rewarded int reward_item3_repeat_count; //!< The count of the third item to be rewarded
int32_t reward_item4_repeatable; //!< The fourth rewarded item int reward_item4_repeatable; //!< The fourth rewarded item
int32_t reward_item4_repeat_count; //!< The count of the fourth item to be rewarded int reward_item4_repeat_count; //!< The count of the fourth item to be rewarded
int32_t time_limit; //!< The time limit of the mission int time_limit; //!< The time limit of the mission
bool isMission; //!< Maybe to differentiate between missions and achievements? bool isMission; //!< Maybe to differentiate between missions and achievements?
int32_t missionIconID; //!< The mission icon ID int missionIconID; //!< The mission icon ID
std::string prereqMissionID; //!< A '|' seperated list of prerequisite missions std::string prereqMissionID; //!< A '|' seperated list of prerequisite missions
bool localize; //!< Whether or not to localize the mission bool localize; //!< Whether or not to localize the mission
bool inMOTD; //!< In Match of the Day(?) bool inMOTD; //!< In Match of the Day(?)
int64_t cooldownTime; //!< The mission cooldown time int64_t cooldownTime; //!< The mission cooldown time
bool isRandom; //!< ??? bool isRandom; //!< ???
std::string randomPool; //!< ??? std::string randomPool; //!< ???
int32_t UIPrereqID; //!< ??? int UIPrereqID; //!< ???
UNUSED(std::string gate_version); //!< The gate version UNUSED(std::string gate_version); //!< The gate version
UNUSED(std::string HUDStates); //!< ??? UNUSED(std::string HUDStates); //!< ???
UNUSED(int32_t locStatus); //!< ??? UNUSED(int locStatus); //!< ???
int32_t reward_bankinventory; //!< The amount of bank space this mission rewards int reward_bankinventory; //!< The amount of bank space this mission rewards
}; };
class CDMissionsTable : public CDTable<CDMissionsTable> { class CDMissionsTable : public CDTable<CDMissionsTable> {

View File

@@ -3,7 +3,7 @@
void CDMovementAIComponentTable::LoadValuesFromDatabase() { void CDMovementAIComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MovementAIComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MovementAIComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,7 +4,7 @@
#include "CDTable.h" #include "CDTable.h"
struct CDMovementAIComponent { struct CDMovementAIComponent {
uint32_t id; unsigned int id;
std::string MovementType; std::string MovementType;
float WanderChance; float WanderChance;
float WanderDelayMin; float WanderDelayMin;

View File

@@ -3,7 +3,7 @@
void CDObjectSkillsTable::LoadValuesFromDatabase() { void CDObjectSkillsTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ObjectSkills"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ObjectSkills");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,10 +4,10 @@
#include "CDTable.h" #include "CDTable.h"
struct CDObjectSkills { struct CDObjectSkills {
uint32_t objectTemplate; //!< The LOT of the item unsigned int objectTemplate; //!< The LOT of the item
uint32_t skillID; //!< The Skill ID of the object unsigned int skillID; //!< The Skill ID of the object
uint32_t castOnType; //!< ??? unsigned int castOnType; //!< ???
uint32_t AICombatWeight; //!< ??? unsigned int AICombatWeight; //!< ???
}; };
class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable> { class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable> {

View File

@@ -2,7 +2,7 @@
void CDObjectsTable::LoadValuesFromDatabase() { void CDObjectsTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Objects"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Objects");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);
@@ -40,7 +40,7 @@ void CDObjectsTable::LoadValuesFromDatabase() {
m_default.id = 0; m_default.id = 0;
} }
const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) { const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) {
const auto& it = this->entries.find(LOT); const auto& it = this->entries.find(LOT);
if (it != this->entries.end()) { if (it != this->entries.end()) {
return it->second; return it->second;

View File

@@ -4,30 +4,30 @@
#include "CDTable.h" #include "CDTable.h"
struct CDObjects { struct CDObjects {
uint32_t id; //!< The LOT of the object unsigned int id; //!< The LOT of the object
std::string name; //!< The internal name of the object std::string name; //!< The internal name of the object
UNUSED(uint32_t placeable); //!< Whether or not the object is placable UNUSED(unsigned int placeable); //!< Whether or not the object is placable
std::string type; //!< The object type std::string type; //!< The object type
UNUSED(std::string description); //!< An internal description of the object UNUSED(std::string description); //!< An internal description of the object
UNUSED(uint32_t localize); //!< Whether or not the object should localize UNUSED(unsigned int localize); //!< Whether or not the object should localize
UNUSED(uint32_t npcTemplateID); //!< Something related to NPCs... UNUSED(unsigned int npcTemplateID); //!< Something related to NPCs...
UNUSED(std::string displayName); //!< The display name of the object UNUSED(std::string displayName); //!< The display name of the object
float interactionDistance; //!< The interaction distance of the object float interactionDistance; //!< The interaction distance of the object
UNUSED(uint32_t nametag); //!< ??? UNUSED(unsigned int nametag); //!< ???
UNUSED(std::string _internalNotes); //!< Some internal notes (rarely used) UNUSED(std::string _internalNotes); //!< Some internal notes (rarely used)
UNUSED(uint32_t locStatus); //!< ??? UNUSED(unsigned int locStatus); //!< ???
UNUSED(std::string gate_version); //!< The gate version for the object UNUSED(std::string gate_version); //!< The gate version for the object
UNUSED(uint32_t HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com UNUSED(unsigned int HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com
}; };
class CDObjectsTable : public CDTable<CDObjectsTable> { class CDObjectsTable : public CDTable<CDObjectsTable> {
private: private:
std::map<uint32_t, CDObjects> entries; std::map<unsigned int, CDObjects> entries;
CDObjects m_default; CDObjects m_default;
public: public:
void LoadValuesFromDatabase(); void LoadValuesFromDatabase();
// Gets an entry by ID // Gets an entry by ID
const CDObjects& GetByID(uint32_t LOT); const CDObjects& GetByID(unsigned int LOT);
}; };

View File

@@ -3,7 +3,7 @@
void CDPackageComponentTable::LoadValuesFromDatabase() { void CDPackageComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM PackageComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM PackageComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,9 +4,9 @@
#include "CDTable.h" #include "CDTable.h"
struct CDPackageComponent { struct CDPackageComponent {
uint32_t id; unsigned int id;
uint32_t LootMatrixIndex; unsigned int LootMatrixIndex;
uint32_t packageType; unsigned int packageType;
}; };
class CDPackageComponentTable : public CDTable<CDPackageComponentTable> { class CDPackageComponentTable : public CDTable<CDPackageComponentTable> {

View File

@@ -1,61 +0,0 @@
#include "CDPetComponentTable.h"
namespace {
// Default entries for fallback
CDPetComponent defaultEntry{
.id = 0,
UNUSED_ENTRY(.minTameUpdateTime = 60.0f,)
UNUSED_ENTRY(.maxTameUpdateTime = 300.0f,)
UNUSED_ENTRY(.percentTameChance = 101.0f,)
UNUSED_ENTRY(.tameability = 100.0f,)
UNUSED_ENTRY(.elementType = 1,)
.walkSpeed = 2.5f,
.runSpeed = 5.0f,
.sprintSpeed = 10.0f,
UNUSED_ENTRY(.idleTimeMin = 60.0f,)
UNUSED_ENTRY(.idleTimeMax = 300.0f,)
UNUSED_ENTRY(.petForm = 0,)
.imaginationDrainRate = 60.0f,
UNUSED_ENTRY(.AudioMetaEventSet = "",)
UNUSED_ENTRY(.buffIDs = "",)
};
}
void CDPetComponentTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PetComponent");
while (!tableData.eof()) {
const uint32_t componentID = tableData.getIntField("id", defaultEntry.id);
auto& entry = m_Entries[componentID];
entry.id = componentID;
UNUSED_COLUMN(entry.minTameUpdateTime = tableData.getFloatField("minTameUpdateTime", defaultEntry.minTameUpdateTime));
UNUSED_COLUMN(entry.maxTameUpdateTime = tableData.getFloatField("maxTameUpdateTime", defaultEntry.maxTameUpdateTime));
UNUSED_COLUMN(entry.percentTameChance = tableData.getFloatField("percentTameChance", defaultEntry.percentTameChance));
UNUSED_COLUMN(entry.tameability = tableData.getFloatField("tamability", defaultEntry.tameability)); // Mispelled as "tamability" in CDClient
UNUSED_COLUMN(entry.elementType = tableData.getIntField("elementType", defaultEntry.elementType));
entry.walkSpeed = static_cast<float>(tableData.getFloatField("walkSpeed", defaultEntry.walkSpeed));
entry.runSpeed = static_cast<float>(tableData.getFloatField("runSpeed", defaultEntry.runSpeed));
entry.sprintSpeed = static_cast<float>(tableData.getFloatField("sprintSpeed", defaultEntry.sprintSpeed));
UNUSED_COLUMN(entry.idleTimeMin = tableData.getFloatField("idleTimeMin", defaultEntry.idleTimeMin));
UNUSED_COLUMN(entry.idleTimeMax = tableData.getFloatField("idleTimeMax", defaultEntry.idleTimeMax));
UNUSED_COLUMN(entry.petForm = tableData.getIntField("petForm", defaultEntry.petForm));
entry.imaginationDrainRate = static_cast<float>(tableData.getFloatField("imaginationDrainRate", defaultEntry.imaginationDrainRate));
UNUSED_COLUMN(entry.AudioMetaEventSet = tableData.getStringField("AudioMetaEventSet", defaultEntry.AudioMetaEventSet));
UNUSED_COLUMN(entry.buffIDs = tableData.getStringField("buffIDs", defaultEntry.buffIDs));
tableData.nextRow();
}
}
void CDPetComponentTable::LoadValuesFromDefaults() {
m_Entries.insert(std::make_pair(defaultEntry.id, defaultEntry));
}
CDPetComponent& CDPetComponentTable::GetByID(const uint32_t componentID) {
auto itr = m_Entries.find(componentID);
if (itr == m_Entries.end()) {
LOG("Unable to load pet component (ID %i) values from database! Using default values instead.", componentID);
return defaultEntry;
}
return itr->second;
}

View File

@@ -1,45 +0,0 @@
#pragma once
#include "CDTable.h"
#include <cstdint>
#include <string>
struct CDPetComponent {
uint32_t id;
UNUSED_COLUMN(float minTameUpdateTime;)
UNUSED_COLUMN(float maxTameUpdateTime;)
UNUSED_COLUMN(float percentTameChance;)
UNUSED_COLUMN(float tameability;) // Mispelled as "tamability" in CDClient
UNUSED_COLUMN(uint32_t elementType;)
float walkSpeed;
float runSpeed;
float sprintSpeed;
UNUSED_COLUMN(float idleTimeMin;)
UNUSED_COLUMN(float idleTimeMax;)
UNUSED_COLUMN(uint32_t petForm;)
float imaginationDrainRate;
UNUSED_COLUMN(std::string AudioMetaEventSet;)
UNUSED_COLUMN(std::string buffIDs;)
};
class CDPetComponentTable : public CDTable<CDPetComponentTable> {
public:
/**
* Load values from the CD client database
*/
void LoadValuesFromDatabase();
/**
* Load the default values into memory instead of attempting to connect to the CD client database
*/
void LoadValuesFromDefaults();
/**
* Gets the pet component table corresponding to the pet component ID
* @returns A reference to the corresponding table, or the default if one could not be found
*/
CDPetComponent& GetByID(const uint32_t componentID);
private:
std::map<uint32_t, CDPetComponent> m_Entries;
};

View File

@@ -28,7 +28,7 @@ void CDPhysicsComponentTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(uint32_t componentID) { CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) {
auto itr = m_entries.find(componentID); auto itr = m_entries.find(componentID);
return itr != m_entries.end() ? &itr->second : nullptr; return itr != m_entries.end() ? &itr->second : nullptr;
} }

View File

@@ -3,7 +3,7 @@
#include <string> #include <string>
struct CDPhysicsComponent { struct CDPhysicsComponent {
int32_t id; int id;
bool bStatic; bool bStatic;
std::string physicsAsset; std::string physicsAsset;
UNUSED(bool jump); UNUSED(bool jump);
@@ -12,8 +12,8 @@ struct CDPhysicsComponent {
UNUSED(float rotSpeed); UNUSED(float rotSpeed);
float playerHeight; float playerHeight;
float playerRadius; float playerRadius;
int32_t pcShapeType; int pcShapeType;
int32_t collisionGroup; int collisionGroup;
UNUSED(float airSpeed); UNUSED(float airSpeed);
UNUSED(std::string boundaryAsset); UNUSED(std::string boundaryAsset);
UNUSED(float jumpAirSpeed); UNUSED(float jumpAirSpeed);
@@ -26,8 +26,8 @@ public:
void LoadValuesFromDatabase(); void LoadValuesFromDatabase();
static const std::string GetTableName() { return "PhysicsComponent"; }; static const std::string GetTableName() { return "PhysicsComponent"; };
CDPhysicsComponent* GetByID(uint32_t componentID); CDPhysicsComponent* GetByID(unsigned int componentID);
private: private:
std::map<uint32_t, CDPhysicsComponent> m_entries; std::map<unsigned int, CDPhysicsComponent> m_entries;
}; };

View File

@@ -3,7 +3,7 @@
void CDProximityMonitorComponentTable::LoadValuesFromDatabase() { void CDProximityMonitorComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ProximityMonitorComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ProximityMonitorComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,7 +4,7 @@
#include "CDTable.h" #include "CDTable.h"
struct CDProximityMonitorComponent { struct CDProximityMonitorComponent {
uint32_t id; unsigned int id;
std::string Proximities; std::string Proximities;
bool LoadOnClient; bool LoadOnClient;
bool LoadOnServer; bool LoadOnServer;

View File

@@ -3,7 +3,7 @@
void CDRarityTableTable::LoadValuesFromDatabase() { void CDRarityTableTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM RarityTable"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM RarityTable");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -5,7 +5,7 @@
struct CDRarityTable { struct CDRarityTable {
float randmax; float randmax;
uint32_t rarity; unsigned int rarity;
}; };
typedef std::vector<CDRarityTable> RarityTable; typedef std::vector<CDRarityTable> RarityTable;

View File

@@ -3,7 +3,7 @@
void CDRebuildComponentTable::LoadValuesFromDatabase() { void CDRebuildComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM RebuildComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM RebuildComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -4,15 +4,15 @@
#include "CDTable.h" #include "CDTable.h"
struct CDRebuildComponent { struct CDRebuildComponent {
uint32_t id; //!< The component Id unsigned int id; //!< The component Id
float reset_time; //!< The reset time float reset_time; //!< The reset time
float complete_time; //!< The complete time float complete_time; //!< The complete time
uint32_t take_imagination; //!< The amount of imagination it costs unsigned int take_imagination; //!< The amount of imagination it costs
bool interruptible; //!< Whether or not the rebuild is interruptible bool interruptible; //!< Whether or not the rebuild is interruptible
bool self_activator; //!< Whether or not the rebuild is a rebuild activator itself bool self_activator; //!< Whether or not the rebuild is a rebuild activator itself
std::string custom_modules; //!< The custom modules std::string custom_modules; //!< The custom modules
uint32_t activityID; //!< The activity ID unsigned int activityID; //!< The activity ID
uint32_t post_imagination_cost; //!< The post imagination cost unsigned int post_imagination_cost; //!< The post imagination cost
float time_before_smash; //!< The time before smash float time_before_smash; //!< The time before smash
}; };

View File

@@ -3,7 +3,7 @@
void CDRewardCodesTable::LoadValuesFromDatabase() { void CDRewardCodesTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM RewardCodes"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM RewardCodes");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);

View File

@@ -3,7 +3,7 @@
void CDScriptComponentTable::LoadValuesFromDatabase() { void CDScriptComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
uint32_t size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ScriptComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ScriptComponent");
while (!tableSize.eof()) { while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0); size = tableSize.getIntField(0, 0);
@@ -28,8 +28,8 @@ void CDScriptComponentTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
const CDScriptComponent& CDScriptComponentTable::GetByID(uint32_t id) { const CDScriptComponent& CDScriptComponentTable::GetByID(unsigned int id) {
std::map<uint32_t, CDScriptComponent>::iterator it = this->entries.find(id); std::map<unsigned int, CDScriptComponent>::iterator it = this->entries.find(id);
if (it != this->entries.end()) { if (it != this->entries.end()) {
return it->second; return it->second;
} }

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