mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-30 08:49:51 -06:00
Compare commits
24 Commits
crash_fix
...
cdclient-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0ddbce8e7 | ||
|
|
4a50c60559 | ||
|
|
fbdcc17bb5 | ||
|
|
e4469f997e | ||
| dbe4a0ced3 | |||
|
|
b683413a60 | ||
|
|
14c20fbd62 | ||
| 325598cd99 | |||
|
|
0c104e819d | ||
|
|
0dc6763a3c | ||
|
|
440dc8b88f | ||
|
|
3deec6499d | ||
|
|
15a461d857 | ||
|
|
2804dc3ec2 | ||
|
|
870b56fe02 | ||
|
|
66ac5a1b7a | ||
| 321d354e96 | |||
| 72b69c7899 | |||
|
|
d283bbd1c4 | ||
|
|
10baa98f00 | ||
|
|
c7c84c21ef | ||
|
|
09fb1dfff9 | ||
| 9116317834 | |||
|
|
a84ca1f00d |
@@ -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
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
# Full path to the LEGO Universe client
|
# Full path to the LEGO Universe client
|
||||||
CLIENT_PATH=/Users/someuser/LEGO Universe
|
CLIENT_PATH=./client
|
||||||
# Can improve build time
|
|
||||||
BUILD_THREADS=1
|
|
||||||
# Updates NET_VERSION in CMakeVariables.txt
|
# Updates NET_VERSION in CMakeVariables.txt
|
||||||
BUILD_VERSION=171022
|
NET_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=
|
||||||
@@ -12,6 +10,5 @@ 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=SECRET_VALUE_CHANGE_ME
|
MARIADB_PASSWORD=
|
||||||
MARIADB_ROOT_PASSWORD=SECRET_VALUE_CHANGE_ME
|
|
||||||
MARIADB_DATABASE=darkflame
|
MARIADB_DATABASE=darkflame
|
||||||
|
|||||||
56
.github/workflows/build-and-push-docker.yml
vendored
Normal file
56
.github/workflows/build-and-push-docker.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
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 }}
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -14,9 +14,6 @@
|
|||||||
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
|
||||||
|
|||||||
@@ -51,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} -std=gnu++17 -O2 -Wuninitialized -fPIC")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -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)
|
||||||
@@ -100,6 +100,9 @@ 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)
|
||||||
@@ -234,84 +237,13 @@ 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"
|
||||||
@@ -382,6 +314,7 @@ 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")
|
||||||
@@ -401,12 +334,6 @@ 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}
|
||||||
|
|||||||
46
Docker.md
46
Docker.md
@@ -1,46 +0,0 @@
|
|||||||
# 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`
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
# Installation under Windows
|
|
||||||
## First Run
|
|
||||||
1. Navigate to the [Docker download page](https://www.docker.com/products/docker-desktop) and download docker.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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_
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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".
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
19. Create an admin account by pasting `docker compose exec darkflame /app/MasterServer -a` and following the prompts.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||

|
|
||||||
51
Dockerfile
Normal file
51
Dockerfile
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
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" ]
|
||||||
57
README.md
57
README.md
@@ -37,6 +37,7 @@ 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)
|
||||||
@@ -347,6 +348,62 @@ 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
|
||||||
|
|
||||||
|
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)
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ 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})
|
||||||
|
|||||||
@@ -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,6 +25,9 @@
|
|||||||
#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;
|
||||||
@@ -33,7 +36,6 @@ 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) {
|
||||||
@@ -46,14 +48,11 @@ 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);
|
||||||
|
|
||||||
//Create all the objects we need to run our service:
|
|
||||||
Game::logger = SetupLogger();
|
|
||||||
if (!Game::logger) return EXIT_FAILURE;
|
|
||||||
|
|
||||||
//Read our config:
|
|
||||||
Game::config = new dConfig("authconfig.ini");
|
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");
|
//Create all the objects we need to run our service:
|
||||||
|
Server::SetupLogger("AuthServer");
|
||||||
|
if (!Game::logger) return EXIT_FAILURE;
|
||||||
|
|
||||||
LOG("Starting Auth server...");
|
LOG("Starting Auth server...");
|
||||||
LOG("Version: %s", PROJECT_VERSION);
|
LOG("Version: %s", PROJECT_VERSION);
|
||||||
@@ -83,12 +82,15 @@ 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 = 50;
|
uint32_t maxClients = 999;
|
||||||
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.
|
||||||
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
std::string ourIP = "localhost";
|
||||||
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
|
||||||
|
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(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal);
|
Game::server = new dServer(ourIP, 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();
|
||||||
@@ -159,18 +161,6 @@ 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;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
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}\"")
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ 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)
|
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#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"
|
||||||
@@ -26,37 +25,36 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
|
|||||||
LWOOBJID playerId;
|
LWOOBJID playerId;
|
||||||
inStream.Read(playerId);
|
inStream.Read(playerId);
|
||||||
|
|
||||||
auto* receiver = Game::playerContainer.GetPlayerData(playerId);
|
auto& receiver = Game::playerContainer.GetPlayerDataMutable(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", playerId);
|
LOG_DEBUG("Player %llu already has an ignore list, but is requesting it again.", playerId);
|
||||||
return;
|
} else {
|
||||||
}
|
auto ignoreList = Database::Get()->GetIgnoreList(static_cast<uint32_t>(playerId));
|
||||||
|
if (ignoreList.empty()) {
|
||||||
|
LOG_DEBUG("Player %llu has no ignores", playerId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto ignoreList = Database::Get()->GetIgnoreList(static_cast<uint32_t>(playerId));
|
for (auto& ignoredPlayer : ignoreList) {
|
||||||
if (ignoreList.empty()) {
|
receiver.ignoredPlayers.emplace_back(ignoredPlayer.name, ignoredPlayer.id);
|
||||||
LOG_DEBUG("Player %llu has no ignores", playerId);
|
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::CHARACTER);
|
||||||
return;
|
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::PERSISTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& ignoredPlayer : ignoreList) {
|
|
||||||
receiver->ignoredPlayers.push_back(IgnoreData{ ignoredPlayer.id, ignoredPlayer.name });
|
|
||||||
GeneralUtils::SetBit(receiver->ignoredPlayers.back().playerId, eObjectBits::CHARACTER);
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
@@ -69,14 +67,14 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
|
|||||||
LWOOBJID playerId;
|
LWOOBJID playerId;
|
||||||
inStream.Read(playerId);
|
inStream.Read(playerId);
|
||||||
|
|
||||||
auto* receiver = Game::playerContainer.GetPlayerData(playerId);
|
auto& receiver = Game::playerContainer.GetPlayerDataMutable(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;
|
||||||
}
|
}
|
||||||
@@ -88,21 +86,21 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
|
|||||||
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
|
||||||
auto* playerData = Game::playerContainer.GetPlayerData(toIgnoreStr);
|
const 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);
|
||||||
@@ -112,7 +110,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) {
|
||||||
@@ -120,7 +118,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.push_back(IgnoreData{ ignoredPlayerId, toIgnoreStr });
|
receiver.ignoredPlayers.emplace_back(toIgnoreStr, ignoredPlayerId);
|
||||||
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);
|
||||||
@@ -141,7 +139,7 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
|
|||||||
LWOOBJID playerId;
|
LWOOBJID playerId;
|
||||||
inStream.Read(playerId);
|
inStream.Read(playerId);
|
||||||
|
|
||||||
auto* receiver = Game::playerContainer.GetPlayerData(playerId);
|
auto& receiver = Game::playerContainer.GetPlayerDataMutable(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;
|
||||||
@@ -153,17 +151,17 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
|
|||||||
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);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
|||||||
LWOOBJID playerID = 0;
|
LWOOBJID playerID = 0;
|
||||||
inStream.Read(playerID);
|
inStream.Read(playerID);
|
||||||
|
|
||||||
auto player = Game::playerContainer.GetPlayerData(playerID);
|
auto& player = Game::playerContainer.GetPlayerDataMutable(playerID);
|
||||||
if (!player) return;
|
if (!player) return;
|
||||||
|
|
||||||
auto friendsList = Database::Get()->GetFriendsList(playerID);
|
auto friendsList = Database::Get()->GetFriendsList(playerID);
|
||||||
@@ -37,15 +37,15 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
|||||||
GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER);
|
GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER);
|
||||||
|
|
||||||
fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
|
fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
|
||||||
if (fd.isBestFriend) player->countOfBestFriends += 1;
|
if (fd.isBestFriend) player.countOfBestFriends += 1;
|
||||||
fd.friendName = friendData.friendName;
|
fd.friendName = friendData.friendName;
|
||||||
|
|
||||||
//Now check if they're online:
|
//Now check if they're online:
|
||||||
auto fr = Game::playerContainer.GetPlayerData(fd.friendID);
|
const auto& fr = Game::playerContainer.GetPlayerData(fd.friendID);
|
||||||
|
|
||||||
if (fr) {
|
if (fr) {
|
||||||
fd.isOnline = true;
|
fd.isOnline = true;
|
||||||
fd.zoneID = fr->zoneID;
|
fd.zoneID = fr.zoneID;
|
||||||
|
|
||||||
//Since this friend is online, we need to update them on the fact that we've just logged in:
|
//Since this friend is online, we need to update them on the fact that we've just logged in:
|
||||||
SendFriendUpdate(fr, player, 1, fd.isBestFriend);
|
SendFriendUpdate(fr, player, 1, fd.isBestFriend);
|
||||||
@@ -54,7 +54,7 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
|||||||
fd.zoneID = LWOZONEID();
|
fd.zoneID = LWOZONEID();
|
||||||
}
|
}
|
||||||
|
|
||||||
player->friends.push_back(fd);
|
player.friends.push_back(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Now, we need to send the friendlist to the server they came from:
|
//Now, we need to send the friendlist to the server they came from:
|
||||||
@@ -66,13 +66,13 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
|||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE);
|
||||||
bitStream.Write<uint8_t>(0);
|
bitStream.Write<uint8_t>(0);
|
||||||
bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it.
|
bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it.
|
||||||
bitStream.Write<uint16_t>(player->friends.size());
|
bitStream.Write<uint16_t>(player.friends.size());
|
||||||
|
|
||||||
for (auto& data : player->friends) {
|
for (const auto& data : player.friends) {
|
||||||
data.Serialize(bitStream);
|
data.Serialize(bitStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemAddress sysAddr = player->sysAddr;
|
SystemAddress sysAddr = player.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,51 +95,49 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
|
|||||||
char isBestFriendRequest{};
|
char isBestFriendRequest{};
|
||||||
inStream.Read(isBestFriendRequest);
|
inStream.Read(isBestFriendRequest);
|
||||||
|
|
||||||
auto requestor = Game::playerContainer.GetPlayerData(requestorPlayerID);
|
auto& requestor = Game::playerContainer.GetPlayerDataMutable(requestorPlayerID);
|
||||||
if (!requestor) {
|
if (!requestor) {
|
||||||
LOG("No requestor player %llu sent to %s found.", requestorPlayerID, playerName.c_str());
|
LOG("No requestor player %llu sent to %s found.", requestorPlayerID, playerName.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestor->playerName == playerName) {
|
if (requestor.playerName == playerName) {
|
||||||
SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN);
|
SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
std::unique_ptr<PlayerData> requestee(Game::playerContainer.GetPlayerData(playerName));
|
|
||||||
|
auto& requestee = Game::playerContainer.GetPlayerDataMutable(playerName);
|
||||||
|
|
||||||
// Check if player is online first
|
// Check if player is online first
|
||||||
if (isBestFriendRequest && !requestee) {
|
if (isBestFriendRequest && !requestee) {
|
||||||
for (auto friendDataCandidate : requestor->friends) {
|
for (auto& friendDataCandidate : requestor.friends) {
|
||||||
if (friendDataCandidate.friendName == playerName) {
|
if (friendDataCandidate.friendName != playerName) continue;
|
||||||
requestee.reset(new PlayerData());
|
// Setup the needed info since you can add a best friend offline.
|
||||||
// Setup the needed info since you can add a best friend offline.
|
requestee.playerID = friendDataCandidate.friendID;
|
||||||
requestee->playerID = friendDataCandidate.friendID;
|
requestee.playerName = friendDataCandidate.friendName;
|
||||||
requestee->playerName = friendDataCandidate.friendName;
|
requestee.zoneID = LWOZONEID();
|
||||||
requestee->zoneID = LWOZONEID();
|
|
||||||
|
|
||||||
FriendData requesteeFriendData{};
|
FriendData requesteeFriendData{};
|
||||||
requesteeFriendData.friendID = requestor->playerID;
|
requesteeFriendData.friendID = requestor.playerID;
|
||||||
requesteeFriendData.friendName = requestor->playerName;
|
requesteeFriendData.friendName = requestor.playerName;
|
||||||
requesteeFriendData.isFTP = false;
|
requesteeFriendData.isFTP = false;
|
||||||
requesteeFriendData.isOnline = false;
|
requesteeFriendData.isOnline = false;
|
||||||
requesteeFriendData.zoneID = requestor->zoneID;
|
requesteeFriendData.zoneID = requestor.zoneID;
|
||||||
requestee->friends.push_back(requesteeFriendData);
|
requestee.friends.push_back(requesteeFriendData);
|
||||||
requestee->sysAddr = UNASSIGNED_SYSTEM_ADDRESS;
|
requestee.sysAddr = UNASSIGNED_SYSTEM_ADDRESS;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If at this point we dont have a target, then they arent online and we cant send the request.
|
// If at this point we dont have a target, then they arent online and we cant send the request.
|
||||||
// Send the response code that corresponds to what the error is.
|
// Send the response code that corresponds to what the error is.
|
||||||
if (!requestee) {
|
if (!requestee) {
|
||||||
requestee.reset(new PlayerData());
|
requestee.playerName = playerName;
|
||||||
requestee->playerName = playerName;
|
|
||||||
auto responseType = Database::Get()->GetCharacterInfo(playerName)
|
auto responseType = Database::Get()->GetCharacterInfo(playerName)
|
||||||
? eAddFriendResponseType::NOTONLINE
|
? eAddFriendResponseType::NOTONLINE
|
||||||
: eAddFriendResponseType::INVALIDCHARACTER;
|
: eAddFriendResponseType::INVALIDCHARACTER;
|
||||||
|
|
||||||
SendFriendResponse(requestor, requestee.get(), responseType);
|
SendFriendResponse(requestor, requestee, responseType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +145,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
|
|||||||
|
|
||||||
uint8_t oldBestFriendStatus{};
|
uint8_t oldBestFriendStatus{};
|
||||||
uint8_t bestFriendStatus{};
|
uint8_t bestFriendStatus{};
|
||||||
auto bestFriendInfo = Database::Get()->GetBestFriendStatus(requestorPlayerID, requestee->playerID);
|
auto bestFriendInfo = Database::Get()->GetBestFriendStatus(requestorPlayerID, requestee.playerID);
|
||||||
if (bestFriendInfo) {
|
if (bestFriendInfo) {
|
||||||
// Get the IDs
|
// Get the IDs
|
||||||
LWOOBJID queryPlayerID = bestFriendInfo->playerCharacterId;
|
LWOOBJID queryPlayerID = bestFriendInfo->playerCharacterId;
|
||||||
@@ -174,51 +172,48 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
|
|||||||
// Only do updates if there was a change in the bff status.
|
// Only do updates if there was a change in the bff status.
|
||||||
if (oldBestFriendStatus != bestFriendStatus) {
|
if (oldBestFriendStatus != bestFriendStatus) {
|
||||||
auto maxBestFriends = Game::playerContainer.GetMaxNumberOfBestFriends();
|
auto maxBestFriends = Game::playerContainer.GetMaxNumberOfBestFriends();
|
||||||
if (requestee->countOfBestFriends >= maxBestFriends || requestor->countOfBestFriends >= maxBestFriends) {
|
if (requestee.countOfBestFriends >= maxBestFriends || requestor.countOfBestFriends >= maxBestFriends) {
|
||||||
if (requestee->countOfBestFriends >= maxBestFriends) {
|
if (requestee.countOfBestFriends >= maxBestFriends) {
|
||||||
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::THEIRFRIENDLISTFULL, false);
|
SendFriendResponse(requestor, requestee, eAddFriendResponseType::THEIRFRIENDLISTFULL, false);
|
||||||
}
|
}
|
||||||
if (requestor->countOfBestFriends >= maxBestFriends) {
|
if (requestor.countOfBestFriends >= maxBestFriends) {
|
||||||
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::YOURFRIENDSLISTFULL, false);
|
SendFriendResponse(requestor, requestee, eAddFriendResponseType::YOURFRIENDSLISTFULL, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Then update the database with this new info.
|
// Then update the database with this new info.
|
||||||
Database::Get()->SetBestFriendStatus(requestorPlayerID, requestee->playerID, bestFriendStatus);
|
Database::Get()->SetBestFriendStatus(requestorPlayerID, requestee.playerID, bestFriendStatus);
|
||||||
// Sent the best friend update here if the value is 3
|
// Sent the best friend update here if the value is 3
|
||||||
if (bestFriendStatus == 3U) {
|
if (bestFriendStatus == 3U) {
|
||||||
requestee->countOfBestFriends += 1;
|
requestee.countOfBestFriends += 1;
|
||||||
requestor->countOfBestFriends += 1;
|
requestor.countOfBestFriends += 1;
|
||||||
if (requestee->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestee.get(), requestor, eAddFriendResponseType::ACCEPTED, false, true);
|
if (requestee.sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestee, requestor, eAddFriendResponseType::ACCEPTED, false, true);
|
||||||
if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::ACCEPTED, false, true);
|
if (requestor.sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee, eAddFriendResponseType::ACCEPTED, false, true);
|
||||||
for (auto& friendData : requestor->friends) {
|
for (auto& friendData : requestor.friends) {
|
||||||
if (friendData.friendID == requestee->playerID) {
|
if (friendData.friendID == requestee.playerID) {
|
||||||
friendData.isBestFriend = true;
|
friendData.isBestFriend = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& friendData : requestee->friends) {
|
for (auto& friendData : requestee.friends) {
|
||||||
if (friendData.friendID == requestor->playerID) {
|
if (friendData.friendID == requestor.playerID) {
|
||||||
friendData.isBestFriend = true;
|
friendData.isBestFriend = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::WAITINGAPPROVAL, true, true);
|
if (requestor.sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee, eAddFriendResponseType::WAITINGAPPROVAL, true, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto maxFriends = Game::playerContainer.GetMaxNumberOfFriends();
|
auto maxFriends = Game::playerContainer.GetMaxNumberOfFriends();
|
||||||
if (requestee->friends.size() >= maxFriends) {
|
if (requestee.friends.size() >= maxFriends) {
|
||||||
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::THEIRFRIENDLISTFULL, false);
|
SendFriendResponse(requestor, requestee, eAddFriendResponseType::THEIRFRIENDLISTFULL, false);
|
||||||
} else if (requestor->friends.size() >= maxFriends) {
|
} else if (requestor.friends.size() >= maxFriends) {
|
||||||
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::YOURFRIENDSLISTFULL, false);
|
SendFriendResponse(requestor, requestee, eAddFriendResponseType::YOURFRIENDSLISTFULL, false);
|
||||||
} else {
|
} else {
|
||||||
// Do not send this if we are requesting to be a best friend.
|
// Do not send this if we are requesting to be a best friend.
|
||||||
SendFriendRequest(requestee.get(), requestor);
|
SendFriendRequest(requestee, requestor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the player is actually a player and not a ghost one defined above, release it from being deleted.
|
|
||||||
if (requestee->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) requestee.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
|
void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
|
||||||
@@ -230,8 +225,8 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
|
|||||||
std::string friendName = PacketUtils::ReadString(0x15, packet, true);
|
std::string friendName = PacketUtils::ReadString(0x15, packet, true);
|
||||||
|
|
||||||
//Now to try and find both of these:
|
//Now to try and find both of these:
|
||||||
auto requestor = Game::playerContainer.GetPlayerData(playerID);
|
auto& requestor = Game::playerContainer.GetPlayerDataMutable(playerID);
|
||||||
auto requestee = Game::playerContainer.GetPlayerData(friendName);
|
auto& requestee = Game::playerContainer.GetPlayerDataMutable(friendName);
|
||||||
if (!requestor || !requestee) return;
|
if (!requestor || !requestee) return;
|
||||||
|
|
||||||
eAddFriendResponseType serverResponseCode{};
|
eAddFriendResponseType serverResponseCode{};
|
||||||
@@ -254,8 +249,8 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
|
|||||||
|
|
||||||
// Now that we have handled the base cases, we need to check the other cases.
|
// Now that we have handled the base cases, we need to check the other cases.
|
||||||
if (serverResponseCode == eAddFriendResponseType::ACCEPTED) {
|
if (serverResponseCode == eAddFriendResponseType::ACCEPTED) {
|
||||||
for (auto friendData : requestor->friends) {
|
for (const auto& friendData : requestor.friends) {
|
||||||
if (friendData.friendID == requestee->playerID) {
|
if (friendData.friendID == requestee.playerID) {
|
||||||
serverResponseCode = eAddFriendResponseType::ALREADYFRIEND;
|
serverResponseCode = eAddFriendResponseType::ALREADYFRIEND;
|
||||||
if (friendData.isBestFriend) {
|
if (friendData.isBestFriend) {
|
||||||
isAlreadyBestFriends = 1U;
|
isAlreadyBestFriends = 1U;
|
||||||
@@ -267,25 +262,23 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
|
|||||||
// This message is NOT sent for best friends and is handled differently for those requests.
|
// This message is NOT sent for best friends and is handled differently for those requests.
|
||||||
if (serverResponseCode == eAddFriendResponseType::ACCEPTED) {
|
if (serverResponseCode == eAddFriendResponseType::ACCEPTED) {
|
||||||
// Add the each player to the others friend list.
|
// Add the each player to the others friend list.
|
||||||
FriendData requestorData;
|
auto& requestorData = requestee.friends.emplace_back();
|
||||||
requestorData.zoneID = requestor->zoneID;
|
requestorData.zoneID = requestor.zoneID;
|
||||||
requestorData.friendID = requestor->playerID;
|
requestorData.friendID = requestor.playerID;
|
||||||
requestorData.friendName = requestor->playerName;
|
requestorData.friendName = requestor.playerName;
|
||||||
requestorData.isBestFriend = false;
|
requestorData.isBestFriend = false;
|
||||||
requestorData.isFTP = false;
|
requestorData.isFTP = false;
|
||||||
requestorData.isOnline = true;
|
requestorData.isOnline = true;
|
||||||
requestee->friends.push_back(requestorData);
|
|
||||||
|
|
||||||
FriendData requesteeData;
|
auto& requesteeData = requestor.friends.emplace_back();
|
||||||
requesteeData.zoneID = requestee->zoneID;
|
requesteeData.zoneID = requestee.zoneID;
|
||||||
requesteeData.friendID = requestee->playerID;
|
requesteeData.friendID = requestee.playerID;
|
||||||
requesteeData.friendName = requestee->playerName;
|
requesteeData.friendName = requestee.playerName;
|
||||||
requesteeData.isBestFriend = false;
|
requesteeData.isBestFriend = false;
|
||||||
requesteeData.isFTP = false;
|
requesteeData.isFTP = false;
|
||||||
requesteeData.isOnline = true;
|
requesteeData.isOnline = true;
|
||||||
requestor->friends.push_back(requesteeData);
|
|
||||||
|
|
||||||
Database::Get()->AddFriend(requestor->playerID, requestee->playerID);
|
Database::Get()->AddFriend(requestor.playerID, requestee.playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverResponseCode != eAddFriendResponseType::DECLINED) SendFriendResponse(requestor, requestee, serverResponseCode, isAlreadyBestFriends);
|
if (serverResponseCode != eAddFriendResponseType::DECLINED) SendFriendResponse(requestor, requestee, serverResponseCode, isAlreadyBestFriends);
|
||||||
@@ -313,26 +306,27 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
|
|||||||
Database::Get()->RemoveFriend(playerID, friendID);
|
Database::Get()->RemoveFriend(playerID, friendID);
|
||||||
|
|
||||||
//Now, we need to send an update to notify the sender (and possibly, receiver) that their friendship has been ended:
|
//Now, we need to send an update to notify the sender (and possibly, receiver) that their friendship has been ended:
|
||||||
auto goonA = Game::playerContainer.GetPlayerData(playerID);
|
auto& goonA = Game::playerContainer.GetPlayerDataMutable(playerID);
|
||||||
if (goonA) {
|
if (goonA) {
|
||||||
// Remove the friend from our list of friends
|
// Remove the friend from our list of friends
|
||||||
for (auto friendData = goonA->friends.begin(); friendData != goonA->friends.end(); friendData++) {
|
for (auto friendData = goonA.friends.cbegin(); friendData != goonA.friends.cend(); friendData++) {
|
||||||
if ((*friendData).friendID == friendID) {
|
if (friendData->friendID == friendID) {
|
||||||
if ((*friendData).isBestFriend) --goonA->countOfBestFriends;
|
if (friendData->isBestFriend) --goonA.countOfBestFriends;
|
||||||
goonA->friends.erase(friendData);
|
goonA.friends.erase(friendData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SendRemoveFriend(goonA, friendName, true);
|
SendRemoveFriend(goonA, friendName, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto goonB = Game::playerContainer.GetPlayerData(friendID);
|
auto& goonB = Game::playerContainer.GetPlayerDataMutable(friendID);
|
||||||
if (!goonB) return;
|
if (!goonB) return;
|
||||||
|
|
||||||
// Do it again for other person
|
// Do it again for other person
|
||||||
for (auto friendData = goonB->friends.begin(); friendData != goonB->friends.end(); friendData++) {
|
for (auto friendData = goonB.friends.cbegin(); friendData != goonB.friends.cend(); friendData++) {
|
||||||
if ((*friendData).friendID == playerID) {
|
if (friendData->friendID == playerID) {
|
||||||
if ((*friendData).isBestFriend) --goonB->countOfBestFriends;
|
if (friendData->isBestFriend) --goonB.countOfBestFriends;
|
||||||
goonB->friends.erase(friendData);
|
goonB.friends.erase(friendData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,13 +340,11 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) {
|
|||||||
LWOOBJID playerID = LWOOBJID_EMPTY;
|
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||||
inStream.Read(playerID);
|
inStream.Read(playerID);
|
||||||
|
|
||||||
auto* sender = Game::playerContainer.GetPlayerData(playerID);
|
const auto& sender = Game::playerContainer.GetPlayerData(playerID);
|
||||||
|
|
||||||
if (sender == nullptr) return;
|
if (!sender) return;
|
||||||
|
|
||||||
if (Game::playerContainer.GetIsMuted(sender)) return;
|
if (sender.GetIsMuted()) return;
|
||||||
|
|
||||||
const auto senderName = std::string(sender->playerName.c_str());
|
|
||||||
|
|
||||||
inStream.SetReadOffset(0x14 * 8);
|
inStream.SetReadOffset(0x14 * 8);
|
||||||
|
|
||||||
@@ -361,7 +353,7 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) {
|
|||||||
|
|
||||||
std::string message = PacketUtils::ReadString(0x66, packet, true, 512);
|
std::string message = PacketUtils::ReadString(0x66, packet, true, 512);
|
||||||
|
|
||||||
LOG("Got a message from (%s) [%d]: %s", senderName.c_str(), channel, message.c_str());
|
LOG("Got a message from (%s) [%d]: %s", sender.playerName.c_str(), channel, message.c_str());
|
||||||
|
|
||||||
if (channel != 8) return;
|
if (channel != 8) return;
|
||||||
|
|
||||||
@@ -370,30 +362,28 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) {
|
|||||||
if (team == nullptr) return;
|
if (team == nullptr) return;
|
||||||
|
|
||||||
for (const auto memberId : team->memberIDs) {
|
for (const auto memberId : team->memberIDs) {
|
||||||
auto* otherMember = Game::playerContainer.GetPlayerData(memberId);
|
const auto& otherMember = Game::playerContainer.GetPlayerData(memberId);
|
||||||
|
|
||||||
if (otherMember == nullptr) return;
|
if (!otherMember) return;
|
||||||
|
|
||||||
const auto otherName = std::string(otherMember->playerName.c_str());
|
|
||||||
|
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(otherMember->playerID);
|
bitStream.Write(otherMember.playerID);
|
||||||
|
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
||||||
bitStream.Write(otherMember->playerID);
|
bitStream.Write(otherMember.playerID);
|
||||||
bitStream.Write<uint8_t>(8);
|
bitStream.Write<uint8_t>(8);
|
||||||
bitStream.Write<unsigned int>(69);
|
bitStream.Write<unsigned int>(69);
|
||||||
bitStream.Write(LUWString(senderName));
|
bitStream.Write(LUWString(sender.playerName));
|
||||||
bitStream.Write(sender->playerID);
|
bitStream.Write(sender.playerID);
|
||||||
bitStream.Write<uint16_t>(0);
|
bitStream.Write<uint16_t>(0);
|
||||||
bitStream.Write<uint8_t>(0); //not mythran nametag
|
bitStream.Write<uint8_t>(0); //not mythran nametag
|
||||||
bitStream.Write(LUWString(otherName));
|
bitStream.Write(LUWString(otherMember.playerName));
|
||||||
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
||||||
bitStream.Write<uint8_t>(0); //teams?
|
bitStream.Write<uint8_t>(0); //teams?
|
||||||
bitStream.Write(LUWString(message, 512));
|
bitStream.Write(LUWString(message, 512));
|
||||||
|
|
||||||
SystemAddress sysAddr = otherMember->sysAddr;
|
SystemAddress sysAddr = otherMember.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,35 +394,32 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
|
|||||||
std::string message = PacketUtils::ReadString(0xAA, packet, true, 512);
|
std::string message = PacketUtils::ReadString(0xAA, packet, true, 512);
|
||||||
|
|
||||||
//Get the bois:
|
//Get the bois:
|
||||||
auto goonA = Game::playerContainer.GetPlayerData(senderID);
|
const auto& goonA = Game::playerContainer.GetPlayerData(senderID);
|
||||||
auto goonB = Game::playerContainer.GetPlayerData(receiverName);
|
const auto& goonB = Game::playerContainer.GetPlayerData(receiverName);
|
||||||
if (!goonA || !goonB) return;
|
if (!goonA || !goonB) return;
|
||||||
|
|
||||||
if (Game::playerContainer.GetIsMuted(goonA)) return;
|
if (goonA.GetIsMuted()) return;
|
||||||
|
|
||||||
std::string goonAName = goonA->playerName.c_str();
|
|
||||||
std::string goonBName = goonB->playerName.c_str();
|
|
||||||
|
|
||||||
//To the sender:
|
//To the sender:
|
||||||
{
|
{
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(goonA->playerID);
|
bitStream.Write(goonA.playerID);
|
||||||
|
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
||||||
bitStream.Write(goonA->playerID);
|
bitStream.Write(goonA.playerID);
|
||||||
bitStream.Write<uint8_t>(7);
|
bitStream.Write<uint8_t>(7);
|
||||||
bitStream.Write<unsigned int>(69);
|
bitStream.Write<unsigned int>(69);
|
||||||
bitStream.Write(LUWString(goonAName));
|
bitStream.Write(LUWString(goonA.playerName));
|
||||||
bitStream.Write(goonA->playerID);
|
bitStream.Write(goonA.playerID);
|
||||||
bitStream.Write<uint16_t>(0);
|
bitStream.Write<uint16_t>(0);
|
||||||
bitStream.Write<uint8_t>(0); //not mythran nametag
|
bitStream.Write<uint8_t>(0); //not mythran nametag
|
||||||
bitStream.Write(LUWString(goonBName));
|
bitStream.Write(LUWString(goonB.playerName));
|
||||||
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
||||||
bitStream.Write<uint8_t>(0); //success
|
bitStream.Write<uint8_t>(0); //success
|
||||||
bitStream.Write(LUWString(message, 512));
|
bitStream.Write(LUWString(message, 512));
|
||||||
|
|
||||||
SystemAddress sysAddr = goonA->sysAddr;
|
SystemAddress sysAddr = goonA.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,22 +427,22 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
|
|||||||
{
|
{
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(goonB->playerID);
|
bitStream.Write(goonB.playerID);
|
||||||
|
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
||||||
bitStream.Write(goonA->playerID);
|
bitStream.Write(goonA.playerID);
|
||||||
bitStream.Write<uint8_t>(7);
|
bitStream.Write<uint8_t>(7);
|
||||||
bitStream.Write<unsigned int>(69);
|
bitStream.Write<unsigned int>(69);
|
||||||
bitStream.Write(LUWString(goonAName));
|
bitStream.Write(LUWString(goonA.playerName));
|
||||||
bitStream.Write(goonA->playerID);
|
bitStream.Write(goonA.playerID);
|
||||||
bitStream.Write<uint16_t>(0);
|
bitStream.Write<uint16_t>(0);
|
||||||
bitStream.Write<uint8_t>(0); //not mythran nametag
|
bitStream.Write<uint8_t>(0); //not mythran nametag
|
||||||
bitStream.Write(LUWString(goonBName));
|
bitStream.Write(LUWString(goonB.playerName));
|
||||||
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
||||||
bitStream.Write<uint8_t>(3); //new whisper
|
bitStream.Write<uint8_t>(3); //new whisper
|
||||||
bitStream.Write(LUWString(message, 512));
|
bitStream.Write(LUWString(message, 512));
|
||||||
|
|
||||||
SystemAddress sysAddr = goonB->sysAddr;
|
SystemAddress sysAddr = goonB.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,11 +453,9 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
|
|||||||
inStream.Read(playerID);
|
inStream.Read(playerID);
|
||||||
std::string invitedPlayer = PacketUtils::ReadString(0x14, packet, true);
|
std::string invitedPlayer = PacketUtils::ReadString(0x14, packet, true);
|
||||||
|
|
||||||
auto* player = Game::playerContainer.GetPlayerData(playerID);
|
const auto& player = Game::playerContainer.GetPlayerData(playerID);
|
||||||
|
|
||||||
if (player == nullptr) {
|
if (!player) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* team = Game::playerContainer.GetTeam(playerID);
|
auto* team = Game::playerContainer.GetTeam(playerID);
|
||||||
|
|
||||||
@@ -478,13 +463,11 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
|
|||||||
team = Game::playerContainer.CreateTeam(playerID);
|
team = Game::playerContainer.CreateTeam(playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* other = Game::playerContainer.GetPlayerData(invitedPlayer);
|
const auto& other = Game::playerContainer.GetPlayerData(invitedPlayer);
|
||||||
|
|
||||||
if (other == nullptr) {
|
if (!other) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Game::playerContainer.GetTeam(other->playerID) != nullptr) {
|
if (Game::playerContainer.GetTeam(other.playerID) != nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,12 +541,12 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) {
|
|||||||
|
|
||||||
LOG("(%llu) kicking (%s) from team", playerID, kickedPlayer.c_str());
|
LOG("(%llu) kicking (%s) from team", playerID, kickedPlayer.c_str());
|
||||||
|
|
||||||
auto* kicked = Game::playerContainer.GetPlayerData(kickedPlayer);
|
const auto& kicked = Game::playerContainer.GetPlayerData(kickedPlayer);
|
||||||
|
|
||||||
LWOOBJID kickedId = LWOOBJID_EMPTY;
|
LWOOBJID kickedId = LWOOBJID_EMPTY;
|
||||||
|
|
||||||
if (kicked != nullptr) {
|
if (kicked) {
|
||||||
kickedId = kicked->playerID;
|
kickedId = kicked.playerID;
|
||||||
} else {
|
} else {
|
||||||
kickedId = Game::playerContainer.GetId(GeneralUtils::UTF8ToUTF16(kickedPlayer));
|
kickedId = Game::playerContainer.GetId(GeneralUtils::UTF8ToUTF16(kickedPlayer));
|
||||||
}
|
}
|
||||||
@@ -588,16 +571,16 @@ void ChatPacketHandler::HandleTeamPromote(Packet* packet) {
|
|||||||
|
|
||||||
LOG("(%llu) promoting (%s) to team leader", playerID, promotedPlayer.c_str());
|
LOG("(%llu) promoting (%s) to team leader", playerID, promotedPlayer.c_str());
|
||||||
|
|
||||||
auto* promoted = Game::playerContainer.GetPlayerData(promotedPlayer);
|
const auto& promoted = Game::playerContainer.GetPlayerData(promotedPlayer);
|
||||||
|
|
||||||
if (promoted == nullptr) return;
|
if (!promoted) return;
|
||||||
|
|
||||||
auto* team = Game::playerContainer.GetTeam(playerID);
|
auto* team = Game::playerContainer.GetTeam(playerID);
|
||||||
|
|
||||||
if (team != nullptr) {
|
if (team != nullptr) {
|
||||||
if (team->leaderID != playerID) return;
|
if (team->leaderID != playerID) return;
|
||||||
|
|
||||||
Game::playerContainer.PromoteMember(team, promoted->playerID);
|
Game::playerContainer.PromoteMember(team, promoted.playerID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,10 +613,10 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) {
|
|||||||
inStream.Read(playerID);
|
inStream.Read(playerID);
|
||||||
|
|
||||||
auto* team = Game::playerContainer.GetTeam(playerID);
|
auto* team = Game::playerContainer.GetTeam(playerID);
|
||||||
auto* data = Game::playerContainer.GetPlayerData(playerID);
|
const auto& data = Game::playerContainer.GetPlayerData(playerID);
|
||||||
|
|
||||||
if (team != nullptr && data != nullptr) {
|
if (team != nullptr && data) {
|
||||||
if (team->local && data->zoneID.GetMapID() != team->zoneId.GetMapID() && data->zoneID.GetCloneID() != team->zoneId.GetCloneID()) {
|
if (team->local && data.zoneID.GetMapID() != team->zoneId.GetMapID() && data.zoneID.GetCloneID() != team->zoneId.GetCloneID()) {
|
||||||
Game::playerContainer.RemoveMember(team, playerID, false, false, true, true);
|
Game::playerContainer.RemoveMember(team, playerID, false, false, true, true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -653,49 +636,49 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) {
|
|||||||
|
|
||||||
Game::playerContainer.TeamStatusUpdate(team);
|
Game::playerContainer.TeamStatusUpdate(team);
|
||||||
|
|
||||||
const auto leaderName = GeneralUtils::UTF8ToUTF16(data->playerName);
|
const auto leaderName = GeneralUtils::UTF8ToUTF16(data.playerName);
|
||||||
|
|
||||||
for (const auto memberId : team->memberIDs) {
|
for (const auto memberId : team->memberIDs) {
|
||||||
auto* otherMember = Game::playerContainer.GetPlayerData(memberId);
|
const auto& otherMember = Game::playerContainer.GetPlayerData(memberId);
|
||||||
|
|
||||||
if (memberId == playerID) continue;
|
if (memberId == playerID) continue;
|
||||||
|
|
||||||
const auto memberName = Game::playerContainer.GetName(memberId);
|
const auto memberName = Game::playerContainer.GetName(memberId);
|
||||||
|
|
||||||
if (otherMember != nullptr) {
|
if (otherMember) {
|
||||||
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, data->playerID, data->zoneID);
|
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, data.playerID, data.zoneID);
|
||||||
}
|
}
|
||||||
ChatPacketHandler::SendTeamAddPlayer(data, false, team->local, false, memberId, memberName, otherMember != nullptr ? otherMember->zoneID : LWOZONEID(0, 0, 0));
|
ChatPacketHandler::SendTeamAddPlayer(data, false, team->local, false, memberId, memberName, otherMember ? otherMember.zoneID : LWOZONEID(0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::playerContainer.UpdateTeamsOnWorld(team, false);
|
Game::playerContainer.UpdateTeamsOnWorld(team, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) {
|
void ChatPacketHandler::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE);
|
||||||
|
|
||||||
bitStream.Write(LUWString(sender->playerName.c_str()));
|
bitStream.Write(LUWString(sender.playerName.c_str()));
|
||||||
bitStream.Write(sender->playerID);
|
bitStream.Write(sender.playerID);
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) {
|
void ChatPacketHandler::SendTeamInviteConfirm(const PlayerData& receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
|
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
bitStream.Write(eGameMessageType::TEAM_INVITE_CONFIRM);
|
bitStream.Write(eGameMessageType::TEAM_INVITE_CONFIRM);
|
||||||
|
|
||||||
bitStream.Write(bLeaderIsFreeTrial);
|
bitStream.Write(bLeaderIsFreeTrial);
|
||||||
@@ -710,19 +693,19 @@ void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeader
|
|||||||
bitStream.Write(character);
|
bitStream.Write(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) {
|
void ChatPacketHandler::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
|
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
bitStream.Write(eGameMessageType::TEAM_GET_STATUS_RESPONSE);
|
bitStream.Write(eGameMessageType::TEAM_GET_STATUS_RESPONSE);
|
||||||
|
|
||||||
bitStream.Write(i64LeaderID);
|
bitStream.Write(i64LeaderID);
|
||||||
@@ -735,36 +718,36 @@ void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderI
|
|||||||
bitStream.Write(character);
|
bitStream.Write(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64PlayerID) {
|
void ChatPacketHandler::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
|
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
bitStream.Write(eGameMessageType::TEAM_SET_LEADER);
|
bitStream.Write(eGameMessageType::TEAM_SET_LEADER);
|
||||||
|
|
||||||
bitStream.Write(i64PlayerID);
|
bitStream.Write(i64PlayerID);
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) {
|
void ChatPacketHandler::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
|
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
bitStream.Write(eGameMessageType::TEAM_ADD_PLAYER);
|
bitStream.Write(eGameMessageType::TEAM_ADD_PLAYER);
|
||||||
|
|
||||||
bitStream.Write(bIsFreeTrial);
|
bitStream.Write(bIsFreeTrial);
|
||||||
@@ -776,24 +759,24 @@ void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTria
|
|||||||
bitStream.Write(character);
|
bitStream.Write(character);
|
||||||
}
|
}
|
||||||
bitStream.Write1();
|
bitStream.Write1();
|
||||||
if (receiver->zoneID.GetCloneID() == zoneID.GetCloneID()) {
|
if (receiver.zoneID.GetCloneID() == zoneID.GetCloneID()) {
|
||||||
zoneID = LWOZONEID(zoneID.GetMapID(), zoneID.GetInstanceID(), 0);
|
zoneID = LWOZONEID(zoneID.GetMapID(), zoneID.GetInstanceID(), 0);
|
||||||
}
|
}
|
||||||
bitStream.Write(zoneID);
|
bitStream.Write(zoneID);
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) {
|
void ChatPacketHandler::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
|
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
bitStream.Write(eGameMessageType::TEAM_REMOVE_PLAYER);
|
bitStream.Write(eGameMessageType::TEAM_REMOVE_PLAYER);
|
||||||
|
|
||||||
bitStream.Write(bDisband);
|
bitStream.Write(bDisband);
|
||||||
@@ -807,32 +790,32 @@ void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband
|
|||||||
bitStream.Write(character);
|
bitStream.Write(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
|
void ChatPacketHandler::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
|
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
bitStream.Write(eGameMessageType::TEAM_SET_OFF_WORLD_FLAG);
|
bitStream.Write(eGameMessageType::TEAM_SET_OFF_WORLD_FLAG);
|
||||||
|
|
||||||
bitStream.Write(i64PlayerID);
|
bitStream.Write(i64PlayerID);
|
||||||
if (receiver->zoneID.GetCloneID() == zoneID.GetCloneID()) {
|
if (receiver.zoneID.GetCloneID() == zoneID.GetCloneID()) {
|
||||||
zoneID = LWOZONEID(zoneID.GetMapID(), zoneID.GetInstanceID(), 0);
|
zoneID = LWOZONEID(zoneID.GetMapID(), zoneID.GetInstanceID(), 0);
|
||||||
}
|
}
|
||||||
bitStream.Write(zoneID);
|
bitStream.Write(zoneID);
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend) {
|
void ChatPacketHandler::SendFriendUpdate(const PlayerData& friendData, const PlayerData& playerData, uint8_t notifyType, uint8_t isBestFriend) {
|
||||||
/*chat notification is displayed if log in / out and friend is updated in friends list
|
/*chat notification is displayed if log in / out and friend is updated in friends list
|
||||||
[u8] - update type
|
[u8] - update type
|
||||||
Update types
|
Update types
|
||||||
@@ -848,38 +831,36 @@ void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* pla
|
|||||||
|
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(friendData->playerID);
|
bitStream.Write(friendData.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY);
|
||||||
bitStream.Write<uint8_t>(notifyType);
|
bitStream.Write<uint8_t>(notifyType);
|
||||||
|
|
||||||
std::string playerName = playerData->playerName.c_str();
|
std::string playerName = playerData.playerName.c_str();
|
||||||
|
|
||||||
bitStream.Write(LUWString(playerName));
|
bitStream.Write(LUWString(playerName));
|
||||||
|
|
||||||
bitStream.Write(playerData->zoneID.GetMapID());
|
bitStream.Write(playerData.zoneID.GetMapID());
|
||||||
bitStream.Write(playerData->zoneID.GetInstanceID());
|
bitStream.Write(playerData.zoneID.GetInstanceID());
|
||||||
|
|
||||||
if (playerData->zoneID.GetCloneID() == friendData->zoneID.GetCloneID()) {
|
if (playerData.zoneID.GetCloneID() == friendData.zoneID.GetCloneID()) {
|
||||||
bitStream.Write(0);
|
bitStream.Write(0);
|
||||||
} else {
|
} else {
|
||||||
bitStream.Write(playerData->zoneID.GetCloneID());
|
bitStream.Write(playerData.zoneID.GetCloneID());
|
||||||
}
|
}
|
||||||
|
|
||||||
bitStream.Write<uint8_t>(isBestFriend); //isBFF
|
bitStream.Write<uint8_t>(isBestFriend); //isBFF
|
||||||
bitStream.Write<uint8_t>(0); //isFTP
|
bitStream.Write<uint8_t>(0); //isFTP
|
||||||
|
|
||||||
SystemAddress sysAddr = friendData->sysAddr;
|
SystemAddress sysAddr = friendData.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* sender) {
|
void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const PlayerData& sender) {
|
||||||
if (!receiver || !sender) return;
|
|
||||||
|
|
||||||
//Make sure people aren't requesting people that they're already friends with:
|
//Make sure people aren't requesting people that they're already friends with:
|
||||||
for (auto fr : receiver->friends) {
|
for (const auto& fr : receiver.friends) {
|
||||||
if (fr.friendID == sender->playerID) {
|
if (fr.friendID == sender.playerID) {
|
||||||
SendFriendResponse(sender, receiver, eAddFriendResponseType::ALREADYFRIEND, fr.isBestFriend);
|
SendFriendResponse(sender, receiver, eAddFriendResponseType::ALREADYFRIEND, fr.isBestFriend);
|
||||||
return; //we have this player as a friend, yeet this function so it doesn't send another request.
|
return; //we have this player as a friend, yeet this function so it doesn't send another request.
|
||||||
}
|
}
|
||||||
@@ -887,54 +868,50 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send
|
|||||||
|
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST);
|
||||||
bitStream.Write(LUWString(sender->playerName.c_str()));
|
bitStream.Write(LUWString(sender.playerName));
|
||||||
bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side.
|
bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side.
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) {
|
void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const PlayerData& sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) {
|
||||||
if (!receiver || !sender) return;
|
|
||||||
|
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
// Portion that will get routed:
|
// Portion that will get routed:
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE);
|
||||||
bitStream.Write(responseCode);
|
bitStream.Write(responseCode);
|
||||||
// For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver.
|
// For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver.
|
||||||
bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS);
|
bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender.sysAddr != UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
// Then write the player name
|
// Then write the player name
|
||||||
bitStream.Write(LUWString(sender->playerName.c_str()));
|
bitStream.Write(LUWString(sender.playerName));
|
||||||
// Then if this is an acceptance code, write the following extra info.
|
// Then if this is an acceptance code, write the following extra info.
|
||||||
if (responseCode == eAddFriendResponseType::ACCEPTED) {
|
if (responseCode == eAddFriendResponseType::ACCEPTED) {
|
||||||
bitStream.Write(sender->playerID);
|
bitStream.Write(sender.playerID);
|
||||||
bitStream.Write(sender->zoneID);
|
bitStream.Write(sender.zoneID);
|
||||||
bitStream.Write(isBestFriendRequest); //isBFF
|
bitStream.Write(isBestFriendRequest); //isBFF
|
||||||
bitStream.Write<uint8_t>(0); //isFTP
|
bitStream.Write<uint8_t>(0); //isFTP
|
||||||
}
|
}
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPacketHandler::SendRemoveFriend(PlayerData* receiver, std::string& personToRemove, bool isSuccessful) {
|
void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) {
|
||||||
if (!receiver) return;
|
|
||||||
|
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||||
bitStream.Write(receiver->playerID);
|
bitStream.Write(receiver.playerID);
|
||||||
|
|
||||||
//portion that will get routed:
|
//portion that will get routed:
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE);
|
||||||
bitStream.Write<uint8_t>(isSuccessful); //isOnline
|
bitStream.Write<uint8_t>(isSuccessful); //isOnline
|
||||||
bitStream.Write(LUWString(personToRemove));
|
bitStream.Write(LUWString(personToRemove));
|
||||||
|
|
||||||
SystemAddress sysAddr = receiver->sysAddr;
|
SystemAddress sysAddr = receiver.sysAddr;
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "BitStream.h"
|
#include "BitStream.h"
|
||||||
|
|
||||||
struct PlayerData;
|
struct PlayerData;
|
||||||
|
|
||||||
enum class eAddFriendResponseType : uint8_t;
|
enum class eAddFriendResponseType : uint8_t;
|
||||||
|
|
||||||
namespace ChatPacketHandler {
|
namespace ChatPacketHandler {
|
||||||
@@ -23,18 +24,18 @@ namespace ChatPacketHandler {
|
|||||||
void HandleTeamLootOption(Packet* packet);
|
void HandleTeamLootOption(Packet* packet);
|
||||||
void HandleTeamStatusRequest(Packet* packet);
|
void HandleTeamStatusRequest(Packet* packet);
|
||||||
|
|
||||||
void SendTeamInvite(PlayerData* receiver, PlayerData* sender);
|
void SendTeamInvite(const PlayerData& receiver, const PlayerData& sender);
|
||||||
void SendTeamInviteConfirm(PlayerData* receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName);
|
void SendTeamInviteConfirm(const PlayerData& receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName);
|
||||||
void SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName);
|
void SendTeamStatus(const PlayerData& receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName);
|
||||||
void SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64PlayerID);
|
void SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID);
|
||||||
void SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID);
|
void SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID);
|
||||||
void SendTeamRemovePlayer(PlayerData* receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName);
|
void SendTeamRemovePlayer(const PlayerData& receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName);
|
||||||
void SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID);
|
void SendTeamSetOffWorldFlag(const 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(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend);
|
void SendFriendUpdate(const PlayerData& friendData, const PlayerData& playerData, uint8_t notifyType, uint8_t isBestFriend);
|
||||||
|
|
||||||
void SendFriendRequest(PlayerData* receiver, PlayerData* sender);
|
void SendFriendRequest(const PlayerData& receiver, const PlayerData& sender);
|
||||||
void SendFriendResponse(PlayerData* receiver, PlayerData* sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U);
|
void SendFriendResponse(const PlayerData& receiver, const PlayerData& sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U);
|
||||||
void SendRemoveFriend(PlayerData* receiver, std::string& personToRemove, bool isSuccessful);
|
void SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,10 +22,11 @@
|
|||||||
#include "ChatIgnoreList.h"
|
#include "ChatIgnoreList.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;
|
||||||
@@ -38,7 +39,6 @@ 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) {
|
||||||
@@ -51,14 +51,13 @@ 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:
|
||||||
Game::logger = SetupLogger();
|
Server::SetupLogger("ChatServer");
|
||||||
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,14 +98,19 @@ 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 = 50;
|
uint32_t maxClients = 999;
|
||||||
uint32_t ourPort = 1501;
|
uint32_t ourPort = 1501;
|
||||||
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
std::string ourIP = "localhost";
|
||||||
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
|
||||||
|
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(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal);
|
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal);
|
||||||
|
|
||||||
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf"))));
|
bool dontGenerateDCF = false;
|
||||||
|
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));
|
||||||
|
|
||||||
@@ -177,18 +181,6 @@ 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.");
|
||||||
|
|||||||
@@ -28,27 +28,32 @@ TeamData::TeamData() {
|
|||||||
|
|
||||||
void PlayerContainer::InsertPlayer(Packet* packet) {
|
void PlayerContainer::InsertPlayer(Packet* packet) {
|
||||||
CINSTREAM_SKIP_HEADER;
|
CINSTREAM_SKIP_HEADER;
|
||||||
PlayerData* data = new PlayerData();
|
LWOOBJID playerId;
|
||||||
inStream.Read(data->playerID);
|
if (!inStream.Read(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);
|
||||||
data->sysAddr = packet->systemAddress;
|
data.sysAddr = packet->systemAddress;
|
||||||
|
|
||||||
m_Names[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName);
|
m_Names[data.playerID] = GeneralUtils::UTF8ToUTF16(data.playerName);
|
||||||
|
|
||||||
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());
|
||||||
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) {
|
||||||
@@ -57,26 +62,27 @@ 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.
|
||||||
std::unique_ptr<PlayerData> player(this->GetPlayerData(playerID));
|
const auto& player = GetPlayerData(playerID);
|
||||||
|
|
||||||
if (player == nullptr) {
|
if (!player) {
|
||||||
|
LOG("Failed to find user: %llu", playerID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& fr : player->friends) {
|
for (const auto& fr : player.friends) {
|
||||||
auto fd = this->GetPlayerData(fr.friendID);
|
const auto& fd = this->GetPlayerData(fr.friendID);
|
||||||
if (fd) ChatPacketHandler::SendFriendUpdate(fd, player.get(), 0, fr.isBestFriend);
|
if (fd) ChatPacketHandler::SendFriendUpdate(fd, player, 0, fr.isBestFriend);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* team = GetTeam(playerID);
|
auto* team = GetTeam(playerID);
|
||||||
|
|
||||||
if (team != nullptr) {
|
if (team != nullptr) {
|
||||||
const auto memberName = GeneralUtils::UTF8ToUTF16(std::string(player->playerName.c_str()));
|
const auto memberName = GeneralUtils::UTF8ToUTF16(player.playerName);
|
||||||
|
|
||||||
for (const auto memberId : team->memberIDs) {
|
for (const auto memberId : team->memberIDs) {
|
||||||
auto* otherMember = GetPlayerData(memberId);
|
const auto& otherMember = GetPlayerData(memberId);
|
||||||
|
|
||||||
if (otherMember == nullptr) continue;
|
if (!otherMember) continue;
|
||||||
|
|
||||||
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, { 0, 0, 0 });
|
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, { 0, 0, 0 });
|
||||||
}
|
}
|
||||||
@@ -85,7 +91,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) {
|
||||||
@@ -95,15 +101,15 @@ void PlayerContainer::MuteUpdate(Packet* packet) {
|
|||||||
time_t expire = 0;
|
time_t expire = 0;
|
||||||
inStream.Read(expire);
|
inStream.Read(expire);
|
||||||
|
|
||||||
auto* player = this->GetPlayerData(playerID);
|
auto& player = this->GetPlayerDataMutable(playerID);
|
||||||
|
|
||||||
if (player == nullptr) {
|
if (!player) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -201,11 +207,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");
|
||||||
auto* player = GetPlayerData(playerID);
|
const 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,18 +221,18 @@ void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) {
|
|||||||
|
|
||||||
team->memberIDs.push_back(playerID);
|
team->memberIDs.push_back(playerID);
|
||||||
|
|
||||||
auto* leader = GetPlayerData(team->leaderID);
|
const auto& leader = GetPlayerData(team->leaderID);
|
||||||
auto* member = GetPlayerData(playerID);
|
const auto& member = GetPlayerData(playerID);
|
||||||
|
|
||||||
if (leader == nullptr || member == nullptr) return;
|
if (!leader || !member) 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);
|
||||||
}
|
}
|
||||||
@@ -234,16 +240,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) {
|
||||||
auto* otherMember = GetPlayerData(memberId);
|
const 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 != nullptr ? otherMember->zoneID : LWOZONEID(0, 0, 0));
|
ChatPacketHandler::SendTeamAddPlayer(member, false, team->local, false, memberId, otherMemberName, otherMember ? otherMember.zoneID : LWOZONEID(0, 0, 0));
|
||||||
|
|
||||||
if (otherMember != nullptr) {
|
if (otherMember) {
|
||||||
ChatPacketHandler::SendTeamAddPlayer(otherMember, false, team->local, false, member->playerID, memberName, member->zoneID);
|
ChatPacketHandler::SendTeamAddPlayer(otherMember, false, team->local, false, member.playerID, memberName, member.zoneID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,9 +259,9 @@ void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disba
|
|||||||
|
|
||||||
if (index == team->memberIDs.end()) return;
|
if (index == team->memberIDs.end()) return;
|
||||||
|
|
||||||
auto* member = GetPlayerData(playerID);
|
const auto& member = GetPlayerData(playerID);
|
||||||
|
|
||||||
if (member != nullptr && !silent) {
|
if (member && !silent) {
|
||||||
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
|
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,9 +272,9 @@ void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disba
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* otherMember = GetPlayerData(memberId);
|
const auto& otherMember = GetPlayerData(memberId);
|
||||||
|
|
||||||
if (otherMember == nullptr) continue;
|
if (!otherMember) continue;
|
||||||
|
|
||||||
ChatPacketHandler::SendTeamRemovePlayer(otherMember, disband, kicked, leaving, false, team->leaderID, playerID, memberName);
|
ChatPacketHandler::SendTeamRemovePlayer(otherMember, disband, kicked, leaving, false, team->leaderID, playerID, memberName);
|
||||||
}
|
}
|
||||||
@@ -290,9 +296,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) {
|
||||||
auto* otherMember = GetPlayerData(memberId);
|
const auto& otherMember = GetPlayerData(memberId);
|
||||||
|
|
||||||
if (otherMember == nullptr) continue;
|
if (!otherMember) continue;
|
||||||
|
|
||||||
ChatPacketHandler::SendTeamSetLeader(otherMember, newLeader);
|
ChatPacketHandler::SendTeamSetLeader(otherMember, newLeader);
|
||||||
}
|
}
|
||||||
@@ -304,14 +310,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) {
|
||||||
auto* otherMember = GetPlayerData(memberId);
|
const auto& otherMember = GetPlayerData(memberId);
|
||||||
|
|
||||||
if (otherMember == nullptr) continue;
|
if (!otherMember) 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);
|
||||||
@@ -326,19 +332,19 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) {
|
|||||||
|
|
||||||
if (index == mTeams.end()) return;
|
if (index == mTeams.end()) return;
|
||||||
|
|
||||||
auto* leader = GetPlayerData(team->leaderID);
|
const auto& leader = GetPlayerData(team->leaderID);
|
||||||
|
|
||||||
if (leader == nullptr) return;
|
if (!leader) 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) {
|
||||||
auto* otherMember = GetPlayerData(memberId);
|
const auto& otherMember = GetPlayerData(memberId);
|
||||||
|
|
||||||
if (otherMember == nullptr) continue;
|
if (!otherMember) 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,23 +370,42 @@ void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::u16string PlayerContainer::GetName(LWOOBJID playerID) {
|
std::u16string PlayerContainer::GetName(LWOOBJID playerID) {
|
||||||
const auto& pair = m_Names.find(playerID);
|
const auto iter = m_Names.find(playerID);
|
||||||
|
|
||||||
if (pair == m_Names.end()) return u"";
|
if (iter == m_Names.end()) return u"";
|
||||||
|
|
||||||
return pair->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) {
|
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) {
|
||||||
for (const auto& pair : m_Names) {
|
LWOOBJID toReturn = LWOOBJID_EMPTY;
|
||||||
if (pair.second == playerName) {
|
|
||||||
return pair.first;
|
for (const auto& [id, name] : m_Names) {
|
||||||
|
if (name == playerName) {
|
||||||
|
toReturn = id;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LWOOBJID_EMPTY;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerContainer::GetIsMuted(PlayerData* data) {
|
PlayerData& PlayerContainer::GetPlayerDataMutable(const LWOOBJID& playerID) {
|
||||||
return data->muteExpire == 1 || data->muteExpire > time(NULL);
|
return m_Players[playerID];
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -16,19 +17,31 @@ struct IgnoreData {
|
|||||||
return playerId == other;
|
return playerId == other;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWOOBJID playerId;
|
LWOOBJID playerId = LWOOBJID_EMPTY;
|
||||||
std::string playerName;
|
std::string playerName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerData {
|
struct 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;
|
||||||
time_t muteExpire;
|
|
||||||
uint8_t countOfBestFriends = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TeamData {
|
struct TeamData {
|
||||||
@@ -52,22 +65,10 @@ public:
|
|||||||
void CreateTeamServer(Packet* packet);
|
void CreateTeamServer(Packet* packet);
|
||||||
void BroadcastMuteUpdate(LWOOBJID player, time_t time);
|
void BroadcastMuteUpdate(LWOOBJID player, time_t time);
|
||||||
|
|
||||||
PlayerData* GetPlayerData(const LWOOBJID& playerID) {
|
const PlayerData& GetPlayerData(const LWOOBJID& playerID);
|
||||||
auto it = m_Players.find(playerID);
|
const PlayerData& GetPlayerData(const std::string& playerName);
|
||||||
if (it != m_Players.end()) return it->second;
|
PlayerData& GetPlayerDataMutable(const LWOOBJID& playerID);
|
||||||
return nullptr;
|
PlayerData& GetPlayerDataMutable(const std::string& playerName);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
@@ -80,15 +81,12 @@ 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;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "Amf3.h"
|
#include "Amf3.h"
|
||||||
|
|
||||||
// RakNet
|
// RakNet
|
||||||
#include <BitStream.h>
|
#include "BitStream.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file AmfSerialize.h
|
\file AmfSerialize.h
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
50
dCommon/PositionUpdate.h
Normal file
50
dCommon/PositionUpdate.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#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 = NiPoint3::ZERO;
|
||||||
|
NiPoint3 linearVelocity = NiPoint3::ZERO;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PositionUpdate {
|
||||||
|
NiPoint3 position = NiPoint3::ZERO;
|
||||||
|
NiQuaternion rotation = NiQuaternion::IDENTITY;
|
||||||
|
bool onGround = false;
|
||||||
|
bool onRail = false;
|
||||||
|
NiPoint3 velocity = NiPoint3::ZERO;
|
||||||
|
NiPoint3 angularVelocity = NiPoint3::ZERO;
|
||||||
|
LocalSpaceInfo localSpaceInfo;
|
||||||
|
RemoteInputInfo remoteInputInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //!__POSITIONUPDATE__H__
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public:
|
|||||||
LWOOBJID friendID;
|
LWOOBJID friendID;
|
||||||
std::string friendName;
|
std::string friendName;
|
||||||
|
|
||||||
void Serialize(RakNet::BitStream& bitStream) {
|
void Serialize(RakNet::BitStream& bitStream) const {
|
||||||
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);
|
||||||
|
|||||||
13
dCommon/dEnums/ePetAbilityType.h
Normal file
13
dCommon/dEnums/ePetAbilityType.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef __EPETABILITYTYPE__H__
|
||||||
|
#define __EPETABILITYTYPE__H__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
enum class ePetAbilityType : uint32_t {
|
||||||
|
Invalid,
|
||||||
|
GoToObject,
|
||||||
|
JumpOnObject,
|
||||||
|
DigAtPosition
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //!__EPETABILITYTYPE__H__
|
||||||
@@ -4,9 +4,13 @@
|
|||||||
// 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
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
//! 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
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#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"
|
||||||
@@ -39,6 +40,8 @@
|
|||||||
#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.
|
||||||
@@ -51,7 +54,16 @@
|
|||||||
#define CDCLIENT_DONT_CACHE_TABLE(x)
|
#define CDCLIENT_DONT_CACHE_TABLE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CDClientManager::CDClientManager() {
|
class CDClientConnectionException : public std::exception {
|
||||||
|
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());
|
||||||
@@ -79,6 +91,7 @@ CDClientManager::CDClientManager() {
|
|||||||
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();
|
||||||
@@ -92,3 +105,9 @@ CDClientManager::CDClientManager() {
|
|||||||
CDVendorComponentTable::Instance().LoadValuesFromDatabase();
|
CDVendorComponentTable::Instance().LoadValuesFromDatabase();
|
||||||
CDZoneTableTable::Instance().LoadValuesFromDatabase();
|
CDZoneTableTable::Instance().LoadValuesFromDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDClientManager::LoadValuesFromDefaults() {
|
||||||
|
LOG("Loading default CDClient tables!");
|
||||||
|
|
||||||
|
CDPetComponentTable::Instance().LoadValuesFromDefaults();
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,7 +11,10 @@
|
|||||||
*/
|
*/
|
||||||
class CDClientManager : public Singleton<CDClientManager> {
|
class CDClientManager : public Singleton<CDClientManager> {
|
||||||
public:
|
public:
|
||||||
CDClientManager();
|
CDClientManager() = default;
|
||||||
|
|
||||||
|
void LoadValuesFromDatabase();
|
||||||
|
void LoadValuesFromDefaults();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a table from CDClient
|
* Fetch a table from CDClient
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
void CDActivitiesTable::LoadValuesFromDatabase() {
|
void CDActivitiesTable::LoadValuesFromDatabase() {
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,22 +4,22 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDActivities {
|
struct CDActivities {
|
||||||
unsigned int ActivityID;
|
uint32_t ActivityID;
|
||||||
unsigned int locStatus;
|
uint32_t locStatus;
|
||||||
unsigned int instanceMapID;
|
uint32_t instanceMapID;
|
||||||
unsigned int minTeams;
|
uint32_t minTeams;
|
||||||
unsigned int maxTeams;
|
uint32_t maxTeams;
|
||||||
unsigned int minTeamSize;
|
uint32_t minTeamSize;
|
||||||
unsigned int maxTeamSize;
|
uint32_t maxTeamSize;
|
||||||
unsigned int waitTime;
|
uint32_t waitTime;
|
||||||
unsigned int startDelay;
|
uint32_t startDelay;
|
||||||
bool requiresUniqueData;
|
bool requiresUniqueData;
|
||||||
unsigned int leaderboardType;
|
uint32_t leaderboardType;
|
||||||
bool localize;
|
bool localize;
|
||||||
int optionalCostLOT;
|
int32_t optionalCostLOT;
|
||||||
int optionalCostCount;
|
int32_t optionalCostCount;
|
||||||
bool showUIRewards;
|
bool showUIRewards;
|
||||||
unsigned int CommunityActivityFlagID;
|
uint32_t CommunityActivityFlagID;
|
||||||
std::string gate_version;
|
std::string gate_version;
|
||||||
bool noTeamLootOnDeath;
|
bool noTeamLootOnDeath;
|
||||||
float optionalPercentage;
|
float optionalPercentage;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDActivityRewardsTable::LoadValuesFromDatabase() {
|
void CDActivityRewardsTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDActivityRewards {
|
struct CDActivityRewards {
|
||||||
unsigned int objectTemplate; //!< The object template (?)
|
uint32_t objectTemplate; //!< The object template (?)
|
||||||
unsigned int ActivityRewardIndex; //!< The activity reward index
|
uint32_t ActivityRewardIndex; //!< The activity reward index
|
||||||
int activityRating; //!< The activity rating
|
int32_t activityRating; //!< The activity rating
|
||||||
unsigned int LootMatrixIndex; //!< The loot matrix index
|
uint32_t LootMatrixIndex; //!< The loot matrix index
|
||||||
unsigned int CurrencyIndex; //!< The currency index
|
uint32_t CurrencyIndex; //!< The currency index
|
||||||
unsigned int ChallengeRating; //!< The challenge rating
|
uint32_t ChallengeRating; //!< The challenge rating
|
||||||
std::string description; //!< The description
|
std::string description; //!< The description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
struct CDAnimation {
|
struct CDAnimation {
|
||||||
// unsigned int animationGroupID;
|
// uint32_t 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(unsigned int min_loops;) //!< The minimum number of loops
|
UNUSED_COLUMN(uint32_t min_loops;) //!< The minimum number of loops
|
||||||
UNUSED_COLUMN(unsigned int max_loops;) //!< The maximum number of loops
|
UNUSED_COLUMN(uint32_t 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
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
|
void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
struct CDBehaviorTemplate {
|
struct CDBehaviorTemplate {
|
||||||
unsigned int behaviorID; //!< The Behavior ID
|
uint32_t behaviorID; //!< The Behavior ID
|
||||||
unsigned int templateID; //!< The Template ID (LOT)
|
uint32_t templateID; //!< The Template ID (LOT)
|
||||||
unsigned int effectID; //!< The Effect ID attached
|
uint32_t 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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDBrickIDTableTable::LoadValuesFromDatabase() {
|
void CDBrickIDTableTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
//! BrickIDTable Entry Struct
|
//! BrickIDTable Entry Struct
|
||||||
struct CDBrickIDTable {
|
struct CDBrickIDTable {
|
||||||
unsigned int NDObjectID;
|
uint32_t NDObjectID;
|
||||||
unsigned int LEGOBrickID;
|
uint32_t LEGOBrickID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
enum class eReplicaComponentType : uint32_t;
|
enum class eReplicaComponentType : uint32_t;
|
||||||
struct CDComponentsRegistry {
|
struct CDComponentsRegistry {
|
||||||
unsigned int id; //!< The LOT is used as the ID
|
uint32_t id; //!< The LOT is used as the ID
|
||||||
eReplicaComponentType component_type; //!< See ComponentTypes enum for values
|
eReplicaComponentType component_type; //!< See ComponentTypes enum for values
|
||||||
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
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
void CDCurrencyTableTable::LoadValuesFromDatabase() {
|
void CDCurrencyTableTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
//! CurrencyTable Struct
|
//! CurrencyTable Struct
|
||||||
struct CDCurrencyTable {
|
struct CDCurrencyTable {
|
||||||
unsigned int currencyIndex; //!< The Currency Index
|
uint32_t currencyIndex; //!< The Currency Index
|
||||||
unsigned int npcminlevel; //!< The minimum level of the npc
|
uint32_t npcminlevel; //!< The minimum level of the npc
|
||||||
unsigned int minvalue; //!< The minimum currency
|
uint32_t minvalue; //!< The minimum currency
|
||||||
unsigned int maxvalue; //!< The maximum currency
|
uint32_t maxvalue; //!< The maximum currency
|
||||||
unsigned int id; //!< The ID of the currency index
|
uint32_t id; //!< The ID of the currency index
|
||||||
};
|
};
|
||||||
|
|
||||||
//! CurrencyTable table
|
//! CurrencyTable table
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
void CDDestructibleComponentTable::LoadValuesFromDatabase() {
|
void CDDestructibleComponentTable::LoadValuesFromDatabase() {
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,20 +4,20 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDDestructibleComponent {
|
struct CDDestructibleComponent {
|
||||||
unsigned int id; //!< The component ID from the ComponentsRegistry Table
|
uint32_t id; //!< The component ID from the ComponentsRegistry Table
|
||||||
int faction; //!< The Faction ID of the object
|
int32_t 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
|
||||||
int life; //!< The amount of life of the object
|
int32_t life; //!< The amount of life of the object
|
||||||
unsigned int imagination; //!< The amount of imagination of the object
|
uint32_t imagination; //!< The amount of imagination of the object
|
||||||
int LootMatrixIndex; //!< The Loot Matrix Index
|
int32_t LootMatrixIndex; //!< The Loot Matrix Index
|
||||||
int CurrencyIndex; //!< The Currency Index
|
int32_t CurrencyIndex; //!< The Currency Index
|
||||||
unsigned int level; //!< ???
|
uint32_t level; //!< ???
|
||||||
float armor; //!< The amount of armor of the object
|
float armor; //!< The amount of armor of the object
|
||||||
unsigned int death_behavior; //!< The behavior ID of the death behavior
|
uint32_t 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
|
||||||
unsigned int attack_priority; //!< ???
|
uint32_t attack_priority; //!< ???
|
||||||
bool isSmashable; //!< Whether or not the object is smashable
|
bool isSmashable; //!< Whether or not the object is smashable
|
||||||
int difficultyLevel; //!< ???
|
int32_t difficultyLevel; //!< ???
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable> {
|
class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable> {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void CDEmoteTableTable::LoadValuesFromDatabase() {
|
|||||||
tableData.finalize();
|
tableData.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
CDEmoteTable* CDEmoteTableTable::GetEmote(int id) {
|
CDEmoteTable* CDEmoteTableTable::GetEmote(int32_t 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ struct CDEmoteTable {
|
|||||||
gateVersion = "";
|
gateVersion = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
int ID;
|
int32_t ID;
|
||||||
std::string animationName;
|
std::string animationName;
|
||||||
std::string iconFilename;
|
std::string iconFilename;
|
||||||
int locState;
|
int32_t locState;
|
||||||
int channel;
|
int32_t 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(int id);
|
CDEmoteTable* GetEmote(int32_t id);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDFeatureGatingTable::LoadValuesFromDatabase() {
|
void CDFeatureGatingTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDInventoryComponentTable::LoadValuesFromDatabase() {
|
void CDInventoryComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDInventoryComponent {
|
struct CDInventoryComponent {
|
||||||
unsigned int id; //!< The component ID for this object
|
uint32_t id; //!< The component ID for this object
|
||||||
unsigned int itemid; //!< The LOT of the object
|
uint32_t itemid; //!< The LOT of the object
|
||||||
unsigned int count; //!< The count of the items the object has
|
uint32_t 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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
unsigned int size = 0;
|
uint32_t 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(unsigned int skillID) {
|
const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t 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;
|
||||||
|
|||||||
@@ -5,60 +5,60 @@
|
|||||||
#include "dCommonVars.h"
|
#include "dCommonVars.h"
|
||||||
|
|
||||||
struct CDItemComponent {
|
struct CDItemComponent {
|
||||||
unsigned int id; //!< The Component ID
|
uint32_t id; //!< The Component ID
|
||||||
std::string equipLocation; //!< The equip location
|
std::string equipLocation; //!< The equip location
|
||||||
unsigned int baseValue; //!< The monetary base value of the item
|
uint32_t 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
|
||||||
unsigned int rarity; //!< The rarity of the item
|
uint32_t rarity; //!< The rarity of the item
|
||||||
unsigned int itemType; //!< The item type
|
uint32_t 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; //!< ???
|
||||||
unsigned int reqFlagID; //!< User must have completed this flag to get the item
|
uint32_t reqFlagID; //!< User must have completed this flag to get the item
|
||||||
unsigned int reqSpecialtyID; //!< ???
|
uint32_t reqSpecialtyID; //!< ???
|
||||||
unsigned int reqSpecRank; //!< ???
|
uint32_t reqSpecRank; //!< ???
|
||||||
unsigned int reqAchievementID; //!< The required achievement must be completed
|
uint32_t reqAchievementID; //!< The required achievement must be completed
|
||||||
unsigned int stackSize; //!< The stack size of the item
|
uint32_t stackSize; //!< The stack size of the item
|
||||||
unsigned int color1; //!< Something to do with item color...
|
uint32_t color1; //!< Something to do with item color...
|
||||||
unsigned int decal; //!< The decal of the item
|
uint32_t decal; //!< The decal of the item
|
||||||
unsigned int offsetGroupID; //!< Something to do with group IDs
|
uint32_t offsetGroupID; //!< Something to do with group IDs
|
||||||
unsigned int buildTypes; //!< Something to do with building
|
uint32_t buildTypes; //!< Something to do with building
|
||||||
std::string reqPrecondition; //!< The required precondition
|
std::string reqPrecondition; //!< The required precondition
|
||||||
unsigned int animationFlag; //!< The Animation Flag
|
uint32_t animationFlag; //!< The Animation Flag
|
||||||
unsigned int equipEffects; //!< The effect played when the item is equipped
|
uint32_t equipEffects; //!< The effect played when the item is equipped
|
||||||
bool readyForQA; //!< ???
|
bool readyForQA; //!< ???
|
||||||
unsigned int itemRating; //!< ???
|
uint32_t itemRating; //!< ???
|
||||||
bool isTwoHanded; //!< Whether or not the item is double handed
|
bool isTwoHanded; //!< Whether or not the item is double handed
|
||||||
unsigned int minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object?
|
uint32_t minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object?
|
||||||
unsigned int delResIndex; //!< ???
|
uint32_t delResIndex; //!< ???
|
||||||
unsigned int currencyLOT; //!< ???
|
uint32_t currencyLOT; //!< ???
|
||||||
unsigned int altCurrencyCost; //!< ???
|
uint32_t 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
|
||||||
unsigned int commendationLOT; //!< The commendation LOT
|
uint32_t commendationLOT; //!< The commendation LOT
|
||||||
unsigned int commendationCost; //!< The commendation cost
|
uint32_t 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
|
||||||
unsigned int locStatus; //!< ???
|
uint32_t locStatus; //!< ???
|
||||||
unsigned int forgeType; //!< Forge Type
|
uint32_t 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<unsigned int, CDItemComponent> entries;
|
std::map<uint32_t, 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(unsigned int skillID);
|
const CDItemComponent& GetItemComponentByID(uint32_t skillID);
|
||||||
|
|
||||||
static CDItemComponent Default;
|
static CDItemComponent Default;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDItemSetSkillsTable::LoadValuesFromDatabase() {
|
void CDItemSetSkillsTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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(unsigned int SkillSetID) {
|
std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetBySkillID(uint32_t SkillSetID) {
|
||||||
std::vector<CDItemSetSkills> toReturn;
|
std::vector<CDItemSetSkills> toReturn;
|
||||||
|
|
||||||
for (CDItemSetSkills entry : this->entries) {
|
for (CDItemSetSkills entry : this->entries) {
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDItemSetSkills {
|
struct CDItemSetSkills {
|
||||||
unsigned int SkillSetID; //!< The skill set ID
|
uint32_t SkillSetID; //!< The skill set ID
|
||||||
unsigned int SkillID; //!< The skill ID
|
uint32_t SkillID; //!< The skill ID
|
||||||
unsigned int SkillCastType; //!< The skill cast type
|
uint32_t 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(unsigned int SkillSetID);
|
std::vector<CDItemSetSkills> GetBySkillID(uint32_t SkillSetID);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDItemSetsTable::LoadValuesFromDatabase() {
|
void CDItemSetsTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,20 +4,20 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDItemSets {
|
struct CDItemSets {
|
||||||
unsigned int setID; //!< The item set ID
|
uint32_t setID; //!< The item set ID
|
||||||
unsigned int locStatus; //!< The loc status
|
uint32_t locStatus; //!< The loc status
|
||||||
std::string itemIDs; //!< THe item IDs
|
std::string itemIDs; //!< THe item IDs
|
||||||
unsigned int kitType; //!< The item kit type
|
uint32_t kitType; //!< The item kit type
|
||||||
unsigned int kitRank; //!< The item kit rank
|
uint32_t kitRank; //!< The item kit rank
|
||||||
unsigned int kitImage; //!< The item kit image
|
uint32_t kitImage; //!< The item kit image
|
||||||
unsigned int skillSetWith2; //!< The skill set with 2
|
uint32_t skillSetWith2; //!< The skill set with 2
|
||||||
unsigned int skillSetWith3; //!< The skill set with 3
|
uint32_t skillSetWith3; //!< The skill set with 3
|
||||||
unsigned int skillSetWith4; //!< The skill set with 4
|
uint32_t skillSetWith4; //!< The skill set with 4
|
||||||
unsigned int skillSetWith5; //!< The skill set with 5
|
uint32_t skillSetWith5; //!< The skill set with 5
|
||||||
unsigned int skillSetWith6; //!< The skill set with 6
|
uint32_t 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
|
||||||
unsigned int kitID; //!< The kit ID
|
uint32_t kitID; //!< The kit ID
|
||||||
float priority; //!< The priority
|
float priority; //!< The priority
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
|
void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDLevelProgressionLookup {
|
struct CDLevelProgressionLookup {
|
||||||
unsigned int id; //!< The Level ID
|
uint32_t id; //!< The Level ID
|
||||||
unsigned int requiredUScore; //!< The required LEGO Score
|
uint32_t requiredUScore; //!< The required LEGO Score
|
||||||
std::string BehaviorEffect; //!< The behavior effect attached to this
|
std::string BehaviorEffect; //!< The behavior effect attached to this
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDLootMatrix {
|
struct CDLootMatrix {
|
||||||
unsigned int LootTableIndex; //!< The Loot Table Index
|
uint32_t LootTableIndex; //!< The Loot Table Index
|
||||||
unsigned int RarityTableIndex; //!< The Rarity Table Index
|
uint32_t RarityTableIndex; //!< The Rarity Table Index
|
||||||
float percent; //!< The percent that this matrix is used?
|
float percent; //!< The percent that this matrix is used?
|
||||||
unsigned int minToDrop; //!< The minimum amount of loot from this matrix to drop
|
uint32_t minToDrop; //!< The minimum amount of loot from this matrix to drop
|
||||||
unsigned int maxToDrop; //!< The maximum amount of loot from this matrix to drop
|
uint32_t maxToDrop; //!< The maximum amount of loot from this matrix to drop
|
||||||
unsigned int flagID; //!< ???
|
uint32_t flagID; //!< ???
|
||||||
UNUSED(std::string gate_version); //!< The Gate Version
|
UNUSED(std::string gate_version); //!< The Gate Version
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDLootTable {
|
struct CDLootTable {
|
||||||
unsigned int itemid; //!< The LOT of the item
|
uint32_t itemid; //!< The LOT of the item
|
||||||
unsigned int LootTableIndex; //!< The Loot Table Index
|
uint32_t 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
|
||||||
unsigned int sortPriority; //!< The sorting priority
|
uint32_t sortPriority; //!< The sorting priority
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint32_t LootTableIndex;
|
typedef uint32_t LootTableIndex;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDMissionEmailTable::LoadValuesFromDatabase() {
|
void CDMissionEmailTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDMissionEmail {
|
struct CDMissionEmail {
|
||||||
unsigned int ID;
|
uint32_t ID;
|
||||||
unsigned int messageType;
|
uint32_t messageType;
|
||||||
unsigned int notificationGroup;
|
uint32_t notificationGroup;
|
||||||
unsigned int missionID;
|
uint32_t missionID;
|
||||||
unsigned int attachmentLOT;
|
uint32_t attachmentLOT;
|
||||||
bool localize;
|
bool localize;
|
||||||
unsigned int locStatus;
|
uint32_t locStatus;
|
||||||
std::string gate_version;
|
std::string gate_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
|
void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDMissionNPCComponent {
|
struct CDMissionNPCComponent {
|
||||||
unsigned int id; //!< The ID
|
uint32_t id; //!< The ID
|
||||||
unsigned int missionID; //!< The Mission ID
|
uint32_t 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
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDMissionTasksTable::LoadValuesFromDatabase() {
|
void CDMissionTasksTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,17 +4,17 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDMissionTasks {
|
struct CDMissionTasks {
|
||||||
unsigned int id; //!< The Mission ID that the task belongs to
|
uint32_t id; //!< The Mission ID that the task belongs to
|
||||||
UNUSED(unsigned int locStatus); //!< ???
|
UNUSED(uint32_t locStatus); //!< ???
|
||||||
unsigned int taskType; //!< The task type
|
uint32_t taskType; //!< The task type
|
||||||
unsigned int target; //!< The mission target
|
uint32_t target; //!< The mission target
|
||||||
std::string targetGroup; //!< The mission target group
|
std::string targetGroup; //!< The mission target group
|
||||||
int targetValue; //!< The target value
|
int32_t 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(unsigned int IconID); //!< ???
|
UNUSED(uint32_t IconID); //!< ???
|
||||||
unsigned int uid; //!< ???
|
uint32_t uid; //!< ???
|
||||||
UNUSED(unsigned int largeTaskIconID); //!< ???
|
UNUSED(uint32_t 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); //!< ???
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -6,58 +6,58 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
struct CDMissions {
|
struct CDMissions {
|
||||||
int id; //!< The Mission ID
|
int32_t 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
|
||||||
int UISortOrder; //!< The UI Sort Order for the mission
|
int32_t UISortOrder; //!< The UI Sort Order for the mission
|
||||||
int offer_objectID; //!< The LOT of the mission giver
|
int32_t offer_objectID; //!< The LOT of the mission giver
|
||||||
int target_objectID; //!< The LOT of the mission's target
|
int32_t 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
|
||||||
int LegoScore; //!< The amount of LEGO Score to reward the player
|
int32_t 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
|
||||||
int reward_item1; //!< The first rewarded item
|
int32_t reward_item1; //!< The first rewarded item
|
||||||
int reward_item1_count; //!< The count of the first item to be rewarded
|
int32_t reward_item1_count; //!< The count of the first item to be rewarded
|
||||||
int reward_item2; //!< The second rewarded item
|
int32_t reward_item2; //!< The second rewarded item
|
||||||
int reward_item2_count; //!< The count of the second item to be rewarded
|
int32_t reward_item2_count; //!< The count of the second item to be rewarded
|
||||||
int reward_item3; //!< The third rewarded item
|
int32_t reward_item3; //!< The third rewarded item
|
||||||
int reward_item3_count; //!< The count of the third item to be rewarded
|
int32_t reward_item3_count; //!< The count of the third item to be rewarded
|
||||||
int reward_item4; //!< The fourth rewarded item
|
int32_t reward_item4; //!< The fourth rewarded item
|
||||||
int reward_item4_count; //!< The count of the fourth item to be rewarded
|
int32_t reward_item4_count; //!< The count of the fourth item to be rewarded
|
||||||
int reward_emote; //!< The first emote to be rewarded
|
int32_t reward_emote; //!< The first emote to be rewarded
|
||||||
int reward_emote2; //!< The second emote to be rewarded
|
int32_t reward_emote2; //!< The second emote to be rewarded
|
||||||
int reward_emote3; //!< The third emote to be rewarded
|
int32_t reward_emote3; //!< The third emote to be rewarded
|
||||||
int reward_emote4; //!< The fourth emote to be rewarded
|
int32_t reward_emote4; //!< The fourth emote to be rewarded
|
||||||
int reward_maximagination; //!< The amount of max imagination to reward
|
int32_t reward_maximagination; //!< The amount of max imagination to reward
|
||||||
int reward_maxhealth; //!< The amount of max health to reward
|
int32_t reward_maxhealth; //!< The amount of max health to reward
|
||||||
int reward_maxinventory; //!< The amount of max inventory to reward
|
int32_t reward_maxinventory; //!< The amount of max inventory to reward
|
||||||
int reward_maxmodel; //!< ???
|
int32_t reward_maxmodel; //!< ???
|
||||||
int reward_maxwidget; //!< ???
|
int32_t reward_maxwidget; //!< ???
|
||||||
int reward_maxwallet; //!< ???
|
int32_t 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
|
||||||
int reward_item1_repeatable; //!< The first rewarded item
|
int32_t reward_item1_repeatable; //!< The first rewarded item
|
||||||
int reward_item1_repeat_count; //!< The count of the first item to be rewarded
|
int32_t reward_item1_repeat_count; //!< The count of the first item to be rewarded
|
||||||
int reward_item2_repeatable; //!< The second rewarded item
|
int32_t reward_item2_repeatable; //!< The second rewarded item
|
||||||
int reward_item2_repeat_count; //!< The count of the second item to be rewarded
|
int32_t reward_item2_repeat_count; //!< The count of the second item to be rewarded
|
||||||
int reward_item3_repeatable; //!< The third rewarded item
|
int32_t reward_item3_repeatable; //!< The third rewarded item
|
||||||
int reward_item3_repeat_count; //!< The count of the third item to be rewarded
|
int32_t reward_item3_repeat_count; //!< The count of the third item to be rewarded
|
||||||
int reward_item4_repeatable; //!< The fourth rewarded item
|
int32_t reward_item4_repeatable; //!< The fourth rewarded item
|
||||||
int reward_item4_repeat_count; //!< The count of the fourth item to be rewarded
|
int32_t reward_item4_repeat_count; //!< The count of the fourth item to be rewarded
|
||||||
int time_limit; //!< The time limit of the mission
|
int32_t 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?
|
||||||
int missionIconID; //!< The mission icon ID
|
int32_t 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; //!< ???
|
||||||
int UIPrereqID; //!< ???
|
int32_t 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(int locStatus); //!< ???
|
UNUSED(int32_t locStatus); //!< ???
|
||||||
int reward_bankinventory; //!< The amount of bank space this mission rewards
|
int32_t reward_bankinventory; //!< The amount of bank space this mission rewards
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDMissionsTable : public CDTable<CDMissionsTable> {
|
class CDMissionsTable : public CDTable<CDMissionsTable> {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDMovementAIComponentTable::LoadValuesFromDatabase() {
|
void CDMovementAIComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDMovementAIComponent {
|
struct CDMovementAIComponent {
|
||||||
unsigned int id;
|
uint32_t id;
|
||||||
std::string MovementType;
|
std::string MovementType;
|
||||||
float WanderChance;
|
float WanderChance;
|
||||||
float WanderDelayMin;
|
float WanderDelayMin;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDObjectSkillsTable::LoadValuesFromDatabase() {
|
void CDObjectSkillsTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDObjectSkills {
|
struct CDObjectSkills {
|
||||||
unsigned int objectTemplate; //!< The LOT of the item
|
uint32_t objectTemplate; //!< The LOT of the item
|
||||||
unsigned int skillID; //!< The Skill ID of the object
|
uint32_t skillID; //!< The Skill ID of the object
|
||||||
unsigned int castOnType; //!< ???
|
uint32_t castOnType; //!< ???
|
||||||
unsigned int AICombatWeight; //!< ???
|
uint32_t AICombatWeight; //!< ???
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable> {
|
class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable> {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
void CDObjectsTable::LoadValuesFromDatabase() {
|
void CDObjectsTable::LoadValuesFromDatabase() {
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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(unsigned int LOT) {
|
const CDObjects& CDObjectsTable::GetByID(uint32_t 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;
|
||||||
|
|||||||
@@ -4,30 +4,30 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDObjects {
|
struct CDObjects {
|
||||||
unsigned int id; //!< The LOT of the object
|
uint32_t 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(unsigned int placeable); //!< Whether or not the object is placable
|
UNUSED(uint32_t 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(unsigned int localize); //!< Whether or not the object should localize
|
UNUSED(uint32_t localize); //!< Whether or not the object should localize
|
||||||
UNUSED(unsigned int npcTemplateID); //!< Something related to NPCs...
|
UNUSED(uint32_t 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(unsigned int nametag); //!< ???
|
UNUSED(uint32_t nametag); //!< ???
|
||||||
UNUSED(std::string _internalNotes); //!< Some internal notes (rarely used)
|
UNUSED(std::string _internalNotes); //!< Some internal notes (rarely used)
|
||||||
UNUSED(unsigned int locStatus); //!< ???
|
UNUSED(uint32_t locStatus); //!< ???
|
||||||
UNUSED(std::string gate_version); //!< The gate version for the object
|
UNUSED(std::string gate_version); //!< The gate version for the object
|
||||||
UNUSED(unsigned int HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com
|
UNUSED(uint32_t 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<unsigned int, CDObjects> entries;
|
std::map<uint32_t, 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(unsigned int LOT);
|
const CDObjects& GetByID(uint32_t LOT);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDPackageComponentTable::LoadValuesFromDatabase() {
|
void CDPackageComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDPackageComponent {
|
struct CDPackageComponent {
|
||||||
unsigned int id;
|
uint32_t id;
|
||||||
unsigned int LootMatrixIndex;
|
uint32_t LootMatrixIndex;
|
||||||
unsigned int packageType;
|
uint32_t packageType;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDPackageComponentTable : public CDTable<CDPackageComponentTable> {
|
class CDPackageComponentTable : public CDTable<CDPackageComponentTable> {
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#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;
|
||||||
|
};
|
||||||
@@ -28,7 +28,7 @@ void CDPhysicsComponentTable::LoadValuesFromDatabase() {
|
|||||||
tableData.finalize();
|
tableData.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) {
|
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(uint32_t 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct CDPhysicsComponent {
|
struct CDPhysicsComponent {
|
||||||
int id;
|
int32_t 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;
|
||||||
int pcShapeType;
|
int32_t pcShapeType;
|
||||||
int collisionGroup;
|
int32_t 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(unsigned int componentID);
|
CDPhysicsComponent* GetByID(uint32_t componentID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<unsigned int, CDPhysicsComponent> m_entries;
|
std::map<uint32_t, CDPhysicsComponent> m_entries;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDProximityMonitorComponentTable::LoadValuesFromDatabase() {
|
void CDProximityMonitorComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDProximityMonitorComponent {
|
struct CDProximityMonitorComponent {
|
||||||
unsigned int id;
|
uint32_t id;
|
||||||
std::string Proximities;
|
std::string Proximities;
|
||||||
bool LoadOnClient;
|
bool LoadOnClient;
|
||||||
bool LoadOnServer;
|
bool LoadOnServer;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDRarityTableTable::LoadValuesFromDatabase() {
|
void CDRarityTableTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
struct CDRarityTable {
|
struct CDRarityTable {
|
||||||
float randmax;
|
float randmax;
|
||||||
unsigned int rarity;
|
uint32_t rarity;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<CDRarityTable> RarityTable;
|
typedef std::vector<CDRarityTable> RarityTable;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDRebuildComponentTable::LoadValuesFromDatabase() {
|
void CDRebuildComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDRebuildComponent {
|
struct CDRebuildComponent {
|
||||||
unsigned int id; //!< The component Id
|
uint32_t 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
|
||||||
unsigned int take_imagination; //!< The amount of imagination it costs
|
uint32_t 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
|
||||||
unsigned int activityID; //!< The activity ID
|
uint32_t activityID; //!< The activity ID
|
||||||
unsigned int post_imagination_cost; //!< The post imagination cost
|
uint32_t post_imagination_cost; //!< The post imagination cost
|
||||||
float time_before_smash; //!< The time before smash
|
float time_before_smash; //!< The time before smash
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDRewardCodesTable::LoadValuesFromDatabase() {
|
void CDRewardCodesTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDScriptComponentTable::LoadValuesFromDatabase() {
|
void CDScriptComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t 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(unsigned int id) {
|
const CDScriptComponent& CDScriptComponentTable::GetByID(uint32_t id) {
|
||||||
std::map<unsigned int, CDScriptComponent>::iterator it = this->entries.find(id);
|
std::map<uint32_t, CDScriptComponent>::iterator it = this->entries.find(id);
|
||||||
if (it != this->entries.end()) {
|
if (it != this->entries.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,19 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDScriptComponent {
|
struct CDScriptComponent {
|
||||||
unsigned int id; //!< The component ID
|
uint32_t id; //!< The component ID
|
||||||
std::string script_name; //!< The script name
|
std::string script_name; //!< The script name
|
||||||
std::string client_script_name; //!< The client script name
|
std::string client_script_name; //!< The client script name
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDScriptComponentTable : public CDTable<CDScriptComponentTable> {
|
class CDScriptComponentTable : public CDTable<CDScriptComponentTable> {
|
||||||
private:
|
private:
|
||||||
std::map<unsigned int, CDScriptComponent> entries;
|
std::map<uint32_t, CDScriptComponent> entries;
|
||||||
CDScriptComponent m_ToReturnWhenNoneFound;
|
CDScriptComponent m_ToReturnWhenNoneFound;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void LoadValuesFromDatabase();
|
void LoadValuesFromDatabase();
|
||||||
// Gets an entry by scriptID
|
// Gets an entry by scriptID
|
||||||
const CDScriptComponent& GetByID(unsigned int id);
|
const CDScriptComponent& GetByID(uint32_t id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ void CDSkillBehaviorTable::LoadValuesFromDatabase() {
|
|||||||
m_empty = CDSkillBehavior();
|
m_empty = CDSkillBehavior();
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t size = 0;
|
||||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM SkillBehavior");
|
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM SkillBehavior");
|
||||||
while (!tableSize.eof()) {
|
while (!tableSize.eof()) {
|
||||||
size = tableSize.getIntField(0, 0);
|
size = tableSize.getIntField(0, 0);
|
||||||
@@ -49,8 +49,8 @@ void CDSkillBehaviorTable::LoadValuesFromDatabase() {
|
|||||||
tableData.finalize();
|
tableData.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CDSkillBehavior& CDSkillBehaviorTable::GetSkillByID(unsigned int skillID) {
|
const CDSkillBehavior& CDSkillBehaviorTable::GetSkillByID(uint32_t skillID) {
|
||||||
std::map<unsigned int, CDSkillBehavior>::iterator it = this->entries.find(skillID);
|
std::map<uint32_t, CDSkillBehavior>::iterator it = this->entries.find(skillID);
|
||||||
if (it != this->entries.end()) {
|
if (it != this->entries.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,36 +4,36 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDSkillBehavior {
|
struct CDSkillBehavior {
|
||||||
unsigned int skillID; //!< The Skill ID of the skill
|
uint32_t skillID; //!< The Skill ID of the skill
|
||||||
UNUSED(unsigned int locStatus); //!< ??
|
UNUSED(uint32_t locStatus); //!< ??
|
||||||
unsigned int behaviorID; //!< The Behavior ID of the skill
|
uint32_t behaviorID; //!< The Behavior ID of the skill
|
||||||
unsigned int imaginationcost; //!< The imagination cost of the skill
|
uint32_t imaginationcost; //!< The imagination cost of the skill
|
||||||
unsigned int cooldowngroup; //!< The cooldown group ID of the skill
|
uint32_t cooldowngroup; //!< The cooldown group ID of the skill
|
||||||
float cooldown; //!< The cooldown time of the skill
|
float cooldown; //!< The cooldown time of the skill
|
||||||
UNUSED(bool isNpcEditor); //!< ???
|
UNUSED(bool isNpcEditor); //!< ???
|
||||||
UNUSED(unsigned int skillIcon); //!< The Skill Icon ID
|
UNUSED(uint32_t skillIcon); //!< The Skill Icon ID
|
||||||
UNUSED(std::string oomSkillID); //!< ???
|
UNUSED(std::string oomSkillID); //!< ???
|
||||||
UNUSED(unsigned int oomBehaviorEffectID); //!< ???
|
UNUSED(uint32_t oomBehaviorEffectID); //!< ???
|
||||||
UNUSED(unsigned int castTypeDesc); //!< The cast type description(?)
|
UNUSED(uint32_t castTypeDesc); //!< The cast type description(?)
|
||||||
UNUSED(unsigned int imBonusUI); //!< The imagination bonus of the skill
|
UNUSED(uint32_t imBonusUI); //!< The imagination bonus of the skill
|
||||||
UNUSED(nsigned int lifeBonusUI); //!< The life bonus of the skill
|
UNUSED(nint32_t lifeBonusUI); //!< The life bonus of the skill
|
||||||
UNUSED(unsigned int armorBonusUI); //!< The armor bonus of the skill
|
UNUSED(uint32_t armorBonusUI); //!< The armor bonus of the skill
|
||||||
UNUSED(unsigned int damageUI); //!< ???
|
UNUSED(uint32_t damageUI); //!< ???
|
||||||
UNUSED(bool hideIcon); //!< Whether or not to show the icon
|
UNUSED(bool hideIcon); //!< Whether or not to show the icon
|
||||||
UNUSED(bool localize); //!< ???
|
UNUSED(bool localize); //!< ???
|
||||||
UNUSED(std::string gate_version); //!< ???
|
UNUSED(std::string gate_version); //!< ???
|
||||||
UNUSED(unsigned int cancelType); //!< The cancel type (?)
|
UNUSED(uint32_t cancelType); //!< The cancel type (?)
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDSkillBehaviorTable : public CDTable<CDSkillBehaviorTable> {
|
class CDSkillBehaviorTable : public CDTable<CDSkillBehaviorTable> {
|
||||||
private:
|
private:
|
||||||
std::map<unsigned int, CDSkillBehavior> entries;
|
std::map<uint32_t, CDSkillBehavior> entries;
|
||||||
CDSkillBehavior m_empty;
|
CDSkillBehavior m_empty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void LoadValuesFromDatabase();
|
void LoadValuesFromDatabase();
|
||||||
|
|
||||||
// Gets an entry by skillID
|
// Gets an entry by skillID
|
||||||
const CDSkillBehavior& GetSkillByID(unsigned int skillID);
|
const CDSkillBehavior& GetSkillByID(uint32_t skillID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
// Enable this to skip some unused columns in some tables
|
// Enable this to skip some unused columns in some tables
|
||||||
#define UNUSED_COLUMN(v)
|
#define UNUSED_COLUMN(v)
|
||||||
|
|
||||||
|
// Use this to skip unused defaults for unused entries in some tables
|
||||||
|
#define UNUSED_ENTRY(v, x)
|
||||||
|
|
||||||
#pragma warning (disable : 4244) //Disable double to float conversion warnings
|
#pragma warning (disable : 4244) //Disable double to float conversion warnings
|
||||||
#pragma warning (disable : 4715) //Disable "not all control paths return a value"
|
#pragma warning (disable : 4715) //Disable "not all control paths return a value"
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDVendorComponentTable::LoadValuesFromDatabase() {
|
void CDVendorComponentTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t size = 0;
|
||||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM VendorComponent");
|
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM VendorComponent");
|
||||||
while (!tableSize.eof()) {
|
while (!tableSize.eof()) {
|
||||||
size = tableSize.getIntField(0, 0);
|
size = tableSize.getIntField(0, 0);
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDVendorComponent {
|
struct CDVendorComponent {
|
||||||
unsigned int id; //!< The Component ID
|
uint32_t id; //!< The Component ID
|
||||||
float buyScalar; //!< Buy Scalar (what does that mean?)
|
float buyScalar; //!< Buy Scalar (what does that mean?)
|
||||||
float sellScalar; //!< Sell Scalar (what does that mean?)
|
float sellScalar; //!< Sell Scalar (what does that mean?)
|
||||||
float refreshTimeSeconds; //!< The refresh time
|
float refreshTimeSeconds; //!< The refresh time
|
||||||
unsigned int LootMatrixIndex; //!< LootMatrixIndex of the vendor's items
|
uint32_t LootMatrixIndex; //!< LootMatrixIndex of the vendor's items
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDVendorComponentTable : public CDTable<CDVendorComponentTable> {
|
class CDVendorComponentTable : public CDTable<CDVendorComponentTable> {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void CDZoneTableTable::LoadValuesFromDatabase() {
|
void CDZoneTableTable::LoadValuesFromDatabase() {
|
||||||
|
|
||||||
// First, get the size of the table
|
// First, get the size of the table
|
||||||
unsigned int size = 0;
|
uint32_t size = 0;
|
||||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ZoneTable");
|
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ZoneTable");
|
||||||
while (!tableSize.eof()) {
|
while (!tableSize.eof()) {
|
||||||
size = tableSize.getIntField(0, 0);
|
size = tableSize.getIntField(0, 0);
|
||||||
@@ -53,7 +53,7 @@ void CDZoneTableTable::LoadValuesFromDatabase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Queries the table with a zoneID to find.
|
//! Queries the table with a zoneID to find.
|
||||||
const CDZoneTable* CDZoneTableTable::Query(unsigned int zoneID) {
|
const CDZoneTable* CDZoneTableTable::Query(uint32_t zoneID) {
|
||||||
const auto& iter = m_Entries.find(zoneID);
|
const auto& iter = m_Entries.find(zoneID);
|
||||||
|
|
||||||
if (iter != m_Entries.end()) {
|
if (iter != m_Entries.end()) {
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
#include "CDTable.h"
|
#include "CDTable.h"
|
||||||
|
|
||||||
struct CDZoneTable {
|
struct CDZoneTable {
|
||||||
unsigned int zoneID; //!< The Zone ID of the object
|
uint32_t zoneID; //!< The Zone ID of the object
|
||||||
unsigned int locStatus; //!< The Locale Status(?)
|
uint32_t locStatus; //!< The Locale Status(?)
|
||||||
std::string zoneName; //!< The name of the zone
|
std::string zoneName; //!< The name of the zone
|
||||||
unsigned int scriptID; //!< The Script ID of the zone (ScriptsTable)
|
uint32_t scriptID; //!< The Script ID of the zone (ScriptsTable)
|
||||||
float ghostdistance_min; //!< The minimum ghosting distance
|
float ghostdistance_min; //!< The minimum ghosting distance
|
||||||
float ghostdistance; //!< The ghosting distance
|
float ghostdistance; //!< The ghosting distance
|
||||||
unsigned int population_soft_cap; //!< The "soft cap" on the world population
|
uint32_t population_soft_cap; //!< The "soft cap" on the world population
|
||||||
unsigned int population_hard_cap; //!< The "hard cap" on the world population
|
uint32_t population_hard_cap; //!< The "hard cap" on the world population
|
||||||
UNUSED(std::string DisplayDescription); //!< The display description of the world
|
UNUSED(std::string DisplayDescription); //!< The display description of the world
|
||||||
UNUSED(std::string mapFolder); //!< ???
|
UNUSED(std::string mapFolder); //!< ???
|
||||||
float smashableMinDistance; //!< The minimum smashable distance?
|
float smashableMinDistance; //!< The minimum smashable distance?
|
||||||
@@ -19,9 +19,9 @@ struct CDZoneTable {
|
|||||||
UNUSED(std::string mixerProgram); //!< ???
|
UNUSED(std::string mixerProgram); //!< ???
|
||||||
UNUSED(std::string clientPhysicsFramerate); //!< The client physics framerate
|
UNUSED(std::string clientPhysicsFramerate); //!< The client physics framerate
|
||||||
std::string serverPhysicsFramerate; //!< The server physics framerate
|
std::string serverPhysicsFramerate; //!< The server physics framerate
|
||||||
unsigned int zoneControlTemplate; //!< The Zone Control template
|
uint32_t zoneControlTemplate; //!< The Zone Control template
|
||||||
unsigned int widthInChunks; //!< The width of the world in chunks
|
uint32_t widthInChunks; //!< The width of the world in chunks
|
||||||
unsigned int heightInChunks; //!< The height of the world in chunks
|
uint32_t heightInChunks; //!< The height of the world in chunks
|
||||||
bool petsAllowed; //!< Whether or not pets are allowed in the world
|
bool petsAllowed; //!< Whether or not pets are allowed in the world
|
||||||
bool localize; //!< Whether or not the world should be localized
|
bool localize; //!< Whether or not the world should be localized
|
||||||
float fZoneWeight; //!< ???
|
float fZoneWeight; //!< ???
|
||||||
@@ -35,11 +35,11 @@ struct CDZoneTable {
|
|||||||
|
|
||||||
class CDZoneTableTable : public CDTable<CDZoneTableTable> {
|
class CDZoneTableTable : public CDTable<CDZoneTableTable> {
|
||||||
private:
|
private:
|
||||||
std::map<unsigned int, CDZoneTable> m_Entries;
|
std::map<uint32_t, CDZoneTable> m_Entries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void LoadValuesFromDatabase();
|
void LoadValuesFromDatabase();
|
||||||
|
|
||||||
// Queries the table with a zoneID to find.
|
// Queries the table with a zoneID to find.
|
||||||
const CDZoneTable* Query(unsigned int zoneID);
|
const CDZoneTable* Query(uint32_t zoneID);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ set(DDATABASE_CDCLIENTDATABASE_CDCLIENTTABLES_SOURCES "CDActivitiesTable.cpp"
|
|||||||
"CDMovementAIComponentTable.cpp"
|
"CDMovementAIComponentTable.cpp"
|
||||||
"CDObjectSkillsTable.cpp"
|
"CDObjectSkillsTable.cpp"
|
||||||
"CDObjectsTable.cpp"
|
"CDObjectsTable.cpp"
|
||||||
|
"CDPetComponentTable.cpp"
|
||||||
"CDPackageComponentTable.cpp"
|
"CDPackageComponentTable.cpp"
|
||||||
"CDPhysicsComponentTable.cpp"
|
"CDPhysicsComponentTable.cpp"
|
||||||
"CDPropertyEntranceComponentTable.cpp"
|
"CDPropertyEntranceComponentTable.cpp"
|
||||||
|
|||||||
@@ -8,58 +8,27 @@ set(DGAME_SOURCES "Character.cpp"
|
|||||||
"User.cpp"
|
"User.cpp"
|
||||||
"UserManager.cpp")
|
"UserManager.cpp")
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${PROJECT_SOURCE_DIR}/dScripts
|
||||||
|
${PROJECT_SOURCE_DIR}/dGame
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(dGameBase ${DGAME_SOURCES})
|
||||||
|
target_precompile_headers(dGameBase PRIVATE ${HEADERS_DGAME})
|
||||||
|
target_link_libraries(dGameBase
|
||||||
|
PUBLIC dDatabase dPhysics
|
||||||
|
INTERFACE dComponents dEntity)
|
||||||
|
|
||||||
add_subdirectory(dBehaviors)
|
add_subdirectory(dBehaviors)
|
||||||
|
|
||||||
foreach(file ${DGAME_DBEHAVIORS_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dBehaviors/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_subdirectory(dComponents)
|
add_subdirectory(dComponents)
|
||||||
|
|
||||||
foreach(file ${DGAME_DCOMPONENTS_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dComponents/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_subdirectory(dEntity)
|
add_subdirectory(dEntity)
|
||||||
|
|
||||||
foreach(file ${DGAME_DENTITY_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dEntity/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_subdirectory(dGameMessages)
|
add_subdirectory(dGameMessages)
|
||||||
|
|
||||||
foreach(file ${DGAME_DGAMEMESSAGES_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dGameMessages/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_subdirectory(dInventory)
|
add_subdirectory(dInventory)
|
||||||
|
|
||||||
foreach(file ${DGAME_DINVENTORY_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dInventory/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_subdirectory(dMission)
|
add_subdirectory(dMission)
|
||||||
|
|
||||||
foreach(file ${DGAME_DMISSION_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dMission/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_subdirectory(dPropertyBehaviors)
|
add_subdirectory(dPropertyBehaviors)
|
||||||
|
|
||||||
foreach(file ${DGAME_DPROPERTYBEHAVIORS_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dPropertyBehaviors/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_subdirectory(dUtilities)
|
add_subdirectory(dUtilities)
|
||||||
|
|
||||||
foreach(file ${DGAME_DUTILITIES_SOURCES})
|
add_library(dGame INTERFACE)
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "dUtilities/${file}")
|
target_link_libraries(dGame INTERFACE
|
||||||
endforeach()
|
dGameBase dBehaviors dComponents dEntity dGameMessages dInventory dMission dPropertyBehaviors dUtilities dScripts
|
||||||
|
)
|
||||||
foreach(file ${DSCRIPTS_SOURCES})
|
|
||||||
set(DGAME_SOURCES ${DGAME_SOURCES} "${PROJECT_SOURCE_DIR}/dScripts/${file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_library(dGame STATIC ${DGAME_SOURCES})
|
|
||||||
|
|
||||||
target_link_libraries(dGame dDatabase Recast Detour)
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "dCommonVars.h"
|
#include "dCommonVars.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../thirdparty/tinyxml2/tinyxml2.h"
|
#include "tinyxml2.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user