Merge branch 'main' into add-sqlite

This commit is contained in:
David Markowitz 2024-12-04 00:43:43 -08:00
commit c7d01dbb82
137 changed files with 4899 additions and 3505 deletions

View File

@ -73,4 +73,4 @@ cpp_space_around_assignment_operator=insert
cpp_space_pointer_reference_alignment=left cpp_space_pointer_reference_alignment=left
cpp_space_around_ternary_operator=insert cpp_space_around_ternary_operator=insert
cpp_wrap_preserve_blocks=one_liners cpp_wrap_preserve_blocks=one_liners
cpp_indent_comment=fasle cpp_indent_comment=false

View File

@ -16,12 +16,12 @@ jobs:
os: [ windows-2022, ubuntu-22.04, macos-13 ] os: [ windows-2022, ubuntu-22.04, macos-13 ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: true submodules: true
- name: Add msbuild to PATH (Windows only) - name: Add msbuild to PATH (Windows only)
if: ${{ matrix.os == 'windows-2022' }} if: ${{ matrix.os == 'windows-2022' }}
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
with: with:
vs-version: '[17,18)' vs-version: '[17,18)'
msbuild-architecture: x64 msbuild-architecture: x64
@ -33,21 +33,19 @@ jobs:
- name: cmake - name: cmake
uses: lukka/run-cmake@v10 uses: lukka/run-cmake@v10
with: with:
configurePreset: "ci-${{matrix.os}}" workflowPreset: "ci-${{matrix.os}}"
buildPreset: "ci-${{matrix.os}}"
testPreset: "ci-${{matrix.os}}"
- name: artifacts - name: artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: build-${{matrix.os}} name: build-${{matrix.os}}
path: | path: |
build/*Server* build/*/*Server*
build/*.ini build/*/*.ini
build/*.so build/*/*.so
build/*.dll build/*/*.dll
build/vanity/ build/*/vanity/
build/navmeshes/ build/*/navmeshes/
build/migrations/ build/*/migrations/
build/*.dcf build/*/*.dcf
!build/*.pdb !build/*/*.pdb
!build/d*/ !build/*/d*/

3
.gitignore vendored
View File

@ -122,4 +122,7 @@ docker/__pycache__
docker-compose.override.yml docker-compose.override.yml
!*Test.bin !*Test.bin
# CMake scripts
!cmake/* !cmake/*
!cmake/toolchains/*

View File

@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(Darkflame) project(Darkflame
HOMEPAGE_URL "https://github.com/DarkflameUniverse/DarkflameServer"
LANGUAGES C CXX
)
# check if the path to the source directory contains a space # check if the path to the source directory contains a space
if("${CMAKE_SOURCE_DIR}" MATCHES " ") if("${CMAKE_SOURCE_DIR}" MATCHES " ")
@ -8,8 +11,10 @@ endif()
include(CTest) include(CTest)
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CXX_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Export the compile commands for debugging set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Export the compile commands for debugging
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW) # Set CMAKE visibility policy to NEW on project and subprojects set(CMAKE_POLICY_DEFAULT_CMP0063 NEW) # Set CMAKE visibility policy to NEW on project and subprojects
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) # Set C and C++ symbol visibility to hide inlined functions set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) # Set C and C++ symbol visibility to hide inlined functions
@ -61,35 +66,36 @@ set(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "" FORCE)
# Disabled no-register # Disabled no-register
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas. # Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
if(UNIX) if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wuninitialized -fPIC") add_compile_options("-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) # For all except Clang and Apple Clang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -lstdc++fs") if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options("-static-libgcc" "-lstdc++fs")
endif() endif()
if(${DYNAMIC} AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(${DYNAMIC} AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") add_link_options("-export-dynamic")
endif() endif()
if(${GGDB}) if(${GGDB})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb") add_compile_options("-ggdb")
endif() endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC")
elseif(MSVC) elseif(MSVC)
# Skip warning for invalid conversion from size_t to uint32_t for all targets below for now # Skip warning for invalid conversion from size_t to uint32_t for all targets below for now
# Also disable non-portable MSVC volatile behavior # Also disable non-portable MSVC volatile behavior
add_compile_options("/wd4267" "/utf-8" "/volatile:iso") add_compile_options("/wd4267" "/utf-8" "/volatile:iso" "/Zc:inline")
elseif(WIN32) elseif(WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif() endif()
# Our output dir # Our output dir
set(CMAKE_BINARY_DIR ${PROJECT_BINARY_DIR})
#set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) # unfortunately, forces all libraries to be built in series, which will slow down the build process #set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) # unfortunately, forces all libraries to be built in series, which will slow down the build process
# TODO make this not have to override the build type directories # TODO make this not have to override the build type directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR})
@ -109,31 +115,39 @@ make_directory(${CMAKE_BINARY_DIR}/resServer)
# Create a /logs directory # Create a /logs directory
make_directory(${CMAKE_BINARY_DIR}/logs) make_directory(${CMAKE_BINARY_DIR}/logs)
# Get DLU config directory
if(DEFINED ENV{DLU_CONFIG_DIR})
set(DLU_CONFIG_DIR $ENV{DLU_CONFIG_DIR})
else()
set(DLU_CONFIG_DIR ${PROJECT_BINARY_DIR})
endif()
message(STATUS "Variable: DLU_CONFIG_DIR = ${DLU_CONFIG_DIR}")
# Copy resource files on first build # Copy resource files on first build
set(RESOURCE_FILES "sharedconfig.ini" "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blocklist.dcf") set(RESOURCE_FILES "sharedconfig.ini" "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blocklist.dcf")
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(${DLU_CONFIG_DIR}/authconfig.ini "port" "auth_server_port")
UpdateConfigOption(${PROJECT_BINARY_DIR}/chatconfig.ini "port" "chat_server_port") UpdateConfigOption(${DLU_CONFIG_DIR}/chatconfig.ini "port" "chat_server_port")
UpdateConfigOption(${PROJECT_BINARY_DIR}/masterconfig.ini "port" "master_server_port") UpdateConfigOption(${DLU_CONFIG_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)
if(EXISTS ${PROJECT_BINARY_DIR}/${resource_file}) if(EXISTS ${DLU_CONFIG_DIR}/${resource_file})
file(SIZE ${PROJECT_BINARY_DIR}/${resource_file} file_size) file(SIZE ${DLU_CONFIG_DIR}/${resource_file} file_size)
endif() endif()
if(${file_size} EQUAL 0) if(${file_size} EQUAL 0)
configure_file( configure_file(
${CMAKE_SOURCE_DIR}/resources/${resource_file} ${PROJECT_BINARY_DIR}/${resource_file} ${CMAKE_SOURCE_DIR}/resources/${resource_file} ${DLU_CONFIG_DIR}/${resource_file}
COPYONLY COPYONLY
) )
message(STATUS "Moved " ${resource_file} " to project binary directory") message(STATUS "Moved " ${resource_file} " to DLU config directory")
elseif(resource_file MATCHES ".ini") elseif(resource_file MATCHES ".ini")
message(STATUS "Checking " ${resource_file} " for missing config options") message(STATUS "Checking " ${resource_file} " for missing config options")
file(READ ${PROJECT_BINARY_DIR}/${resource_file} current_file_contents) file(READ ${DLU_CONFIG_DIR}/${resource_file} 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})
set(parsed_current_file_contents "") set(parsed_current_file_contents "")
@ -164,10 +178,10 @@ foreach(resource_file ${RESOURCE_FILES})
set(line_to_add ${line_to_add} ${line}) set(line_to_add ${line_to_add} ${line})
foreach(line_to_append ${line_to_add}) foreach(line_to_append ${line_to_add})
file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n" ${line_to_append}) file(APPEND ${DLU_CONFIG_DIR}/${resource_file} "\n" ${line_to_append})
endforeach() endforeach()
file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n") file(APPEND ${DLU_CONFIG_DIR}/${resource_file} "\n")
endif() endif()
set(line_to_add "") set(line_to_add "")
@ -236,14 +250,15 @@ include_directories(
"tests/dGameTests" "tests/dGameTests"
"tests/dGameTests/dComponentsTests" "tests/dGameTests/dComponentsTests"
SYSTEM "thirdparty/magic_enum/include/magic_enum" SYSTEM
SYSTEM "thirdparty/raknet/Source" "thirdparty/magic_enum/include/magic_enum"
SYSTEM "thirdparty/tinyxml2" "thirdparty/raknet/Source"
SYSTEM "thirdparty/recastnavigation" "thirdparty/tinyxml2"
SYSTEM "thirdparty/SQLite" "thirdparty/recastnavigation"
SYSTEM "thirdparty/cpplinq" "thirdparty/SQLite"
SYSTEM "thirdparty/cpp-httplib" "thirdparty/cpplinq"
SYSTEM "thirdparty/MD5" "thirdparty/cpp-httplib"
"thirdparty/MD5"
) )
# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux) # Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
@ -252,10 +267,17 @@ if(APPLE)
include_directories("/usr/local/include/") include_directories("/usr/local/include/")
endif() endif()
# Add linking directories: # Set warning flags
if (UNIX) if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast -Werror") # Warning flags # add_compile_options("/W4")
# Want to enable warnings eventually, but WAY too much noise right now
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
add_compile_options("-Wuninitialized" "-Wold-style-cast")
else()
message(WARNING "Unknown compiler: '${CMAKE_CXX_COMPILER_ID}' - No warning flags enabled.")
endif() endif()
# Add linking directories:
file( file(
GLOB HEADERS_DZONEMANAGER GLOB HEADERS_DZONEMANAGER
LIST_DIRECTORIES false LIST_DIRECTORIES false

View File

@ -1,8 +1,8 @@
{ {
"version": 3, "version": 6,
"cmakeMinimumRequired": { "cmakeMinimumRequired": {
"major": 3, "major": 3,
"minor": 14, "minor": 25,
"patch": 0 "patch": 0
}, },
"configurePresets": [ "configurePresets": [
@ -11,43 +11,160 @@
"displayName": "Default configure step", "displayName": "Default configure step",
"description": "Use 'build' dir and Unix makefiles", "description": "Use 'build' dir and Unix makefiles",
"binaryDir": "${sourceDir}/build", "binaryDir": "${sourceDir}/build",
"environment": {
"DLU_CONFIG_DIR": "${sourceDir}/build"
},
"generator": "Unix Makefiles" "generator": "Unix Makefiles"
}, },
{ {
"name": "ci-ubuntu-22.04", "name": "debug-config",
"displayName": "CI configure step for Ubuntu", "hidden": true,
"description": "Same as default, Used in GitHub actions workflow", "cacheVariables": {
"inherits": "default" "CMAKE_BUILD_TYPE": "Debug"
}
}, },
{ {
"name": "ci-macos-13", "name": "relwithdebinfo-config",
"displayName": "CI configure step for MacOS", "hidden": true,
"description": "Same as default, Used in GitHub actions workflow",
"inherits": "default"
},
{
"name": "ci-windows-2022",
"displayName": "CI configure step for Windows",
"description": "Set architecture to 64-bit (b/c RakNet)",
"inherits": "default",
"generator": "Visual Studio 17 2022",
"architecture": {
"value": "x64"
},
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo" "CMAKE_BUILD_TYPE": "RelWithDebInfo"
} }
}, },
{
"name": "release-config",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "clang-config",
"hidden": true,
"toolchainFile": "${sourceDir}/cmake/toolchains/linux-clang.cmake"
},
{
"name": "gnu-config",
"hidden": true,
"toolchainFile": "${sourceDir}/cmake/toolchains/linux-gnu.cmake"
},
{
"name": "windows-msvc",
"inherits": "default",
"displayName": "[Multi] Windows (MSVC)",
"description": "Set architecture to 64-bit (b/c RakNet)",
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build/msvc",
"architecture": {
"value": "x64"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{ {
"name": "windows-default", "name": "windows-default",
"inherits": "ci-windows-2022", "inherits": "windows-msvc",
"displayName": "Windows only Configure Settings", "displayName": "Windows only Configure Settings",
"description": "Sets build and install directories", "description": "Sets build and install directories",
"generator": "Ninja", "generator": "Ninja",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"architecture": { "architecture": {
"value": "x64", "value": "x64"
"strategy": "external"
} }
},
{
"name": "linux-config",
"inherits": "default",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
},
{
"name": "linux-clang-debug",
"inherits": [
"linux-config",
"clang-config",
"debug-config"
],
"displayName": "EXPERIMENTAL - [Debug] Linux (Clang)",
"description": "Create a debug build using the Clang toolchain for Linux",
"binaryDir": "${sourceDir}/build/clang-debug"
},
{
"name": "linux-clang-relwithdebinfo",
"inherits": [
"linux-config",
"clang-config",
"relwithdebinfo-config"
],
"displayName": "EXPERIMENTAL - [RelWithDebInfo] Linux (Clang)",
"description": "Create a release build with debug info using the Clang toolchain for Linux",
"binaryDir": "${sourceDir}/build/clang-relwithdebinfo"
},
{
"name": "linux-clang-release",
"inherits": [
"linux-config",
"clang-config",
"release-config"
],
"displayName": "EXPERIMENTAL - [Release] Linux (Clang)",
"description": "Create a release build using the Clang toolchain for Linux",
"binaryDir": "${sourceDir}/build/clang-release"
},
{
"name": "linux-gnu-debug",
"inherits": [
"linux-config",
"gnu-config",
"debug-config"
],
"displayName": "[Debug] Linux (GNU)",
"description": "Create a debug build using the GNU toolchain for Linux",
"binaryDir": "${sourceDir}/build/gnu-debug"
},
{
"name": "linux-gnu-relwithdebinfo",
"inherits": [
"linux-config",
"gnu-config",
"relwithdebinfo-config"
],
"displayName": "[RelWithDebInfo] Linux (GNU)",
"description": "Create a release build with debug info using the GNU toolchain for Linux",
"binaryDir": "${sourceDir}/build/gnu-relwithdebinfo"
},
{
"name": "linux-gnu-release",
"inherits": [
"linux-config",
"gnu-config",
"release-config"
],
"displayName": "[Release] Linux (GNU)",
"description": "Create a release build using the GNU toolchain for Linux",
"binaryDir": "${sourceDir}/build/gnu-release"
},
{
"name": "macos",
"inherits": "default",
"displayName": "[Multi] MacOS",
"description": "Create a build for MacOS",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"binaryDir": "${sourceDir}/build/macos"
} }
], ],
"buildPresets": [ "buildPresets": [
@ -59,34 +176,106 @@
"jobs": 2 "jobs": 2
}, },
{ {
"name": "ci-windows-2022", "name": "windows-msvc-debug",
"configurePreset": "ci-windows-2022", "inherits": "default",
"displayName": "Windows CI Build", "configurePreset": "windows-msvc",
"description": "This preset is used by the CI build on windows", "displayName": "[Debug] Windows (MSVC)",
"configuration": "RelWithDebInfo", "description": "This preset is used to build in debug mode using the MSVC toolchain on Windows",
"jobs": 2 "configuration": "Debug"
}, },
{ {
"name": "ci-ubuntu-22.04", "name": "windows-msvc-relwithdebinfo",
"configurePreset": "ci-ubuntu-22.04", "inherits": "default",
"displayName": "Linux CI Build", "configurePreset": "windows-msvc",
"description": "This preset is used by the CI build on linux", "displayName": "[RelWithDebInfo] Windows (MSVC)",
"jobs": 2 "description": "This preset is used to build in debug mode using the MSVC toolchain on Windows",
"configuration": "RelWithDebInfo"
}, },
{ {
"name": "ci-macos-13", "name": "windows-msvc-release",
"configurePreset": "ci-macos-13", "inherits": "default",
"displayName": "MacOS CI Build", "configurePreset": "windows-msvc",
"description": "This preset is used by the CI build on MacOS", "displayName": "[Release] Windows (MSVC)",
"jobs": 2 "description": "This preset is used to build in release mode using the MSVC toolchain on Windows",
"configuration": "Release"
},
{
"name": "linux-clang-debug",
"inherits": "default",
"configurePreset": "linux-clang-debug",
"displayName": "EXPERIMENTAL - [Debug] Linux (Clang)",
"description": "This preset is used to build in debug mode using the Clang toolchain on Linux",
"configuration": "Debug"
},
{
"name": "linux-clang-relwithdebinfo",
"inherits": "default",
"configurePreset": "linux-clang-relwithdebinfo",
"displayName": "EXPERIMENTAL - [RelWithDebInfo] Linux (Clang)",
"description": "This preset is used to build in release mode with debug info using the Clang toolchain on Linux",
"configuration": "RelWithDebInfo"
},
{
"name": "linux-clang-release",
"inherits": "default",
"configurePreset": "linux-clang-release",
"displayName": "EXPERIMENTAL - [Release] Linux (Clang)",
"description": "This preset is used to build in release mode using the Clang toolchain on Linux",
"configuration": "Release"
},
{
"name": "linux-gnu-debug",
"inherits": "default",
"configurePreset": "linux-gnu-debug",
"displayName": "[Debug] Linux (GNU)",
"description": "This preset is used to build in debug mode using the GNU toolchain on Linux",
"configuration": "Debug"
},
{
"name": "linux-gnu-relwithdebinfo",
"inherits": "default",
"configurePreset": "linux-gnu-relwithdebinfo",
"displayName": "[RelWithDebInfo] Linux (GNU)",
"description": "This preset is used to build in release mode with debug info using the GNU toolchain on Linux",
"configuration": "RelWithDebInfo"
},
{
"name": "linux-gnu-release",
"inherits": "default",
"configurePreset": "linux-gnu-release",
"displayName": "[Release] Linux (GNU)",
"description": "This preset is used to build in release mode using the GNU toolchain on Linux",
"configuration": "Release"
},
{
"name": "macos-debug",
"inherits": "default",
"configurePreset": "macos",
"displayName": "[Debug] MacOS",
"description": "This preset is used to build in debug mode on MacOS",
"configuration": "Debug"
},
{
"name": "macos-relwithdebinfo",
"inherits": "default",
"configurePreset": "macos",
"displayName": "[RelWithDebInfo] MacOS",
"description": "This preset is used to build in release mode with debug info on MacOS",
"configuration": "RelWithDebInfo"
},
{
"name": "macos-release",
"inherits": "default",
"configurePreset": "macos",
"displayName": "[Release] MacOS",
"description": "This preset is used to build in release mode on MacOS",
"configuration": "Release"
} }
], ],
"testPresets": [ "testPresets": [
{ {
"name": "ci-ubuntu-22.04", "name": "default",
"configurePreset": "ci-ubuntu-22.04", "configurePreset": "default",
"displayName": "CI Tests on Linux",
"description": "Runs all tests on a linux configuration",
"execution": { "execution": {
"jobs": 2 "jobs": 2
}, },
@ -95,34 +284,358 @@
} }
}, },
{ {
"name": "ci-macos-13", "name": "windows-msvc-test",
"configurePreset": "ci-macos-13", "inherits": "default",
"displayName": "CI Tests on MacOS", "configurePreset": "windows-msvc",
"description": "Runs all tests on a Mac configuration", "hidden": true,
"execution": {
"jobs": 2
},
"output": {
"outputOnFailure": true
}
},
{
"name": "ci-windows-2022",
"configurePreset": "ci-windows-2022",
"displayName": "CI Tests on windows",
"description": "Runs all tests on a windows configuration",
"configuration": "RelWithDebInfo",
"execution": {
"jobs": 2
},
"output": {
"outputOnFailure": true
},
"filter": { "filter": {
"exclude": { "exclude": {
"name": "((example)|(minigzip))+" "name": "((example)|(minigzip))+"
} }
} }
},
{
"name": "windows-msvc-debug",
"inherits": "windows-msvc-test",
"configurePreset": "windows-msvc",
"displayName": "[Debug] Windows (MSVC)",
"description": "Runs all tests on a Windows configuration",
"configuration": "Debug"
},
{
"name": "windows-msvc-relwithdebinfo",
"inherits": "windows-msvc-test",
"configurePreset": "windows-msvc",
"displayName": "[RelWithDebInfo] Windows (MSVC)",
"description": "Runs all tests on a Windows configuration",
"configuration": "RelWithDebInfo"
},
{
"name": "windows-msvc-release",
"inherits": "windows-msvc-test",
"configurePreset": "windows-msvc",
"displayName": "[Release] Windows (MSVC)",
"description": "Runs all tests on a Windows configuration",
"configuration": "Release"
},
{
"name": "linux-clang-debug",
"inherits": "default",
"configurePreset": "linux-clang-debug",
"displayName": "EXPERIMENTAL - [Debug] Linux (Clang)",
"description": "Runs all tests on a Linux Clang configuration",
"configuration": "Release"
},
{
"name": "linux-clang-relwithdebinfo",
"inherits": "default",
"configurePreset": "linux-clang-relwithdebinfo",
"displayName": "EXPERIMENTAL - [RelWithDebInfo] Linux (Clang)",
"description": "Runs all tests on a Linux Clang configuration",
"configuration": "RelWithDebInfo"
},
{
"name": "linux-clang-release",
"inherits": "default",
"configurePreset": "linux-clang-release",
"displayName": "EXPERIMENTAL - [Release] Linux (Clang)",
"description": "Runs all tests on a Linux Clang configuration",
"configuration": "Release"
},
{
"name": "linux-gnu-debug",
"inherits": "default",
"configurePreset": "linux-gnu-debug",
"displayName": "[Debug] Linux (GNU)",
"description": "Runs all tests on a Linux GNU configuration",
"configuration": "Release"
},
{
"name": "linux-gnu-relwithdebinfo",
"inherits": "default",
"configurePreset": "linux-gnu-relwithdebinfo",
"displayName": "[RelWithDebInfo] Linux (GNU)",
"description": "Runs all tests on a Linux GNU configuration",
"configuration": "RelWithDebInfo"
},
{
"name": "linux-gnu-release",
"inherits": "default",
"configurePreset": "linux-gnu-release",
"displayName": "[Release] Linux (GNU)",
"description": "Runs all tests on a Linux GNU configuration",
"configuration": "Release"
},
{
"name": "macos-debug",
"inherits": "default",
"configurePreset": "macos",
"displayName": "[Debug] MacOS",
"description": "Runs all tests on a MacOS configuration",
"configuration": "Debug"
},
{
"name": "macos-relwithdebinfo",
"inherits": "default",
"configurePreset": "macos",
"displayName": "[RelWithDebInfo] MacOS",
"description": "Runs all tests on a MacOS configuration",
"configuration": "RelWithDebInfo"
},
{
"name": "macos-release",
"inherits": "default",
"configurePreset": "macos",
"displayName": "[Release] MacOS",
"description": "Runs all tests on a MacOS configuration",
"configuration": "Release"
}
],
"workflowPresets": [
{
"name": "default",
"steps": [
{
"type": "configure",
"name": "default"
},
{
"type": "build",
"name": "default"
},
{
"type": "test",
"name": "default"
}
]
},
{
"name": "windows-msvc-debug",
"displayName": "[Debug] Windows (MSVC)",
"description": "MSVC debug workflow preset for Windows",
"steps": [
{
"type": "configure",
"name": "windows-msvc"
},
{
"type": "build",
"name": "windows-msvc-debug"
},
{
"type": "test",
"name": "windows-msvc-debug"
}
]
},
{
"name": "windows-msvc-relwithdebinfo",
"displayName": "[RelWithDebInfo] Windows (MSVC)",
"description": "MSVC release with debug info workflow preset for Windows",
"steps": [
{
"type": "configure",
"name": "windows-msvc"
},
{
"type": "build",
"name": "windows-msvc-relwithdebinfo"
},
{
"type": "test",
"name": "windows-msvc-relwithdebinfo"
}
]
},
{
"name": "ci-windows-2022",
"displayName": "[Release] Windows (MSVC)",
"description": "CI workflow preset for Windows",
"steps": [
{
"type": "configure",
"name": "windows-msvc"
},
{
"type": "build",
"name": "windows-msvc-release"
},
{
"type": "test",
"name": "windows-msvc-release"
}
]
},
{
"name": "linux-gnu-debug",
"displayName": "[Debug] Linux (GNU)",
"description": "GNU debug workflow preset for Linux",
"steps": [
{
"type": "configure",
"name": "linux-gnu-debug"
},
{
"type": "build",
"name": "linux-gnu-debug"
},
{
"type": "test",
"name": "linux-gnu-debug"
}
]
},
{
"name": "linux-gnu-relwithdebinfo",
"displayName": "[RelWithDebInfo] Linux (GNU)",
"description": "GNU release with debug info workflow preset for Linux",
"steps": [
{
"type": "configure",
"name": "linux-gnu-relwithdebinfo"
},
{
"type": "build",
"name": "linux-gnu-relwithdebinfo"
},
{
"type": "test",
"name": "linux-gnu-relwithdebinfo"
}
]
},
{
"name": "ci-ubuntu-22.04",
"displayName": "[Release] Linux (GNU)",
"description": "CI workflow preset for Ubuntu",
"steps": [
{
"type": "configure",
"name": "linux-gnu-release"
},
{
"type": "build",
"name": "linux-gnu-release"
},
{
"type": "test",
"name": "linux-gnu-release"
}
]
},
{
"name": "linux-clang-debug",
"displayName": "EXPERIMENTAL - [Debug] Linux (Clang)",
"description": "Clang debug workflow preset for Linux",
"steps": [
{
"type": "configure",
"name": "linux-clang-debug"
},
{
"type": "build",
"name": "linux-clang-debug"
},
{
"type": "test",
"name": "linux-clang-debug"
}
]
},
{
"name": "linux-clang-relwithdebinfo",
"displayName": "EXPERIMENTAL - [RelWithDebInfo] Linux (Clang)",
"description": "Clang release with debug info workflow preset for Linux",
"steps": [
{
"type": "configure",
"name": "linux-clang-relwithdebinfo"
},
{
"type": "build",
"name": "linux-clang-relwithdebinfo"
},
{
"type": "test",
"name": "linux-clang-relwithdebinfo"
}
]
},
{
"name": "linux-clang-release",
"displayName": "EXPERIMENTAL - [Release] Linux (Clang)",
"description": "Clang release workflow preset for Linux",
"steps": [
{
"type": "configure",
"name": "linux-clang-release"
},
{
"type": "build",
"name": "linux-clang-release"
},
{
"type": "test",
"name": "linux-clang-release"
}
]
},
{
"name": "macos-debug",
"displayName": "[Debug] MacOS",
"description": "Release workflow preset for MacOS",
"steps": [
{
"type": "configure",
"name": "macos"
},
{
"type": "build",
"name": "macos-debug"
},
{
"type": "test",
"name": "macos-debug"
}
]
},
{
"name": "macos-relwithdebinfo",
"displayName": "[RelWithDebInfo] MacOS",
"description": "Release with debug info workflow preset for MacOS",
"steps": [
{
"type": "configure",
"name": "macos"
},
{
"type": "build",
"name": "macos-relwithdebinfo"
},
{
"type": "test",
"name": "macos-relwithdebinfo"
}
]
},
{
"name": "ci-macos-13",
"displayName": "[Release] MacOS",
"description": "CI workflow preset for MacOS",
"steps": [
{
"type": "configure",
"name": "macos"
},
{
"type": "build",
"name": "macos-release"
},
{
"type": "test",
"name": "macos-release"
} }
] ]
} }
]
}

View File

@ -6,8 +6,7 @@ mkdir -p build
cd build cd build
# Run cmake to generate make files # Run cmake to generate make files
cmake .. cmake -DCMAKE_BUILD_TYPE="Release" ..
# To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8' # To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8'
cmake --build . --config Release $1 cmake --build . --config Release $1

View File

@ -0,0 +1,14 @@
# Try and find a clang-16 install, falling back to a generic clang install otherwise
find_program(CLANG_C_COMPILER clang-16 | clang REQUIRED)
find_program(CLANG_CXX_COMPILER clang++-16 | clang++ REQUIRED)
# Debug messages
message(DEBUG "CLANG_C_COMPILER = ${CLANG_C_COMPILER}")
message(DEBUG "CLANG_CXX_COMPILER = ${CLANG_CXX_COMPILER}")
# Set compilers to clang (need to cache for VSCode tools to work correctly)
set(CMAKE_C_COMPILER ${CLANG_C_COMPILER} CACHE STRING "Set C compiler")
set(CMAKE_CXX_COMPILER ${CLANG_CXX_COMPILER} CACHE STRING "Set C++ compiler")
# Set linker to lld
add_link_options("-fuse-ld=lld")

View File

@ -0,0 +1,11 @@
# Try and find a gcc/g++ install
find_program(GNU_C_COMPILER cc | gcc REQUIRED)
find_program(GNU_CXX_COMPILER c++ | g++ REQUIRED)
# Debug messages
message(DEBUG "GNU_C_COMPILER = ${GNU_C_COMPILER}")
message(DEBUG "GNU_CXX_COMPILER = ${GNU_CXX_COMPILER}")
# Set compilers to GNU (need to cache for VSCode tools to work correctly)
set(CMAKE_C_COMPILER ${GNU_C_COMPILER} CACHE STRING "Set C compiler")
set(CMAKE_CXX_COMPILER ${GNU_CXX_COMPILER} CACHE STRING "Set C++ compiler")

View File

@ -21,8 +21,8 @@
//Auth includes: //Auth includes:
#include "AuthPackets.h" #include "AuthPackets.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eServerMessageType.h" #include "MessageType/Server.h"
#include "eAuthMessageType.h" #include "MessageType/Auth.h"
#include "Game.h" #include "Game.h"
#include "Server.h" #include "Server.h"
@ -166,11 +166,11 @@ void HandlePacket(Packet* packet) {
if (packet->data[0] == ID_USER_PACKET_ENUM) { if (packet->data[0] == ID_USER_PACKET_ENUM) {
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::SERVER) { if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::SERVER) {
if (static_cast<eServerMessageType>(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) { if (static_cast<MessageType::Server>(packet->data[3]) == MessageType::Server::VERSION_CONFIRM) {
AuthPackets::HandleHandshake(Game::server, packet); AuthPackets::HandleHandshake(Game::server, packet);
} }
} else if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::AUTH) { } else if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::AUTH) {
if (static_cast<eAuthMessageType>(packet->data[3]) == eAuthMessageType::LOGIN_REQUEST) { if (static_cast<MessageType::Auth>(packet->data[3]) == MessageType::Auth::LOGIN_REQUEST) {
AuthPackets::HandleLoginRequest(Game::server, packet); AuthPackets::HandleLoginRequest(Game::server, packet);
} }
} }

View File

@ -1,6 +1,6 @@
#include "ChatIgnoreList.h" #include "ChatIgnoreList.h"
#include "PlayerContainer.h" #include "PlayerContainer.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "Logger.h"
@ -13,7 +13,7 @@
// The only thing not auto-handled is instance activities force joining the team on the server. // The only thing not auto-handled is instance activities force joining the team on the server.
void WriteOutgoingReplyHeader(RakNet::BitStream& bitStream, const LWOOBJID& receivingPlayer, const ChatIgnoreList::Response type) { void WriteOutgoingReplyHeader(RakNet::BitStream& bitStream, const LWOOBJID& receivingPlayer, const ChatIgnoreList::Response type) {
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receivingPlayer); bitStream.Write(receivingPlayer);
//portion that will get routed: //portion that will get routed:

View File

@ -13,9 +13,9 @@
#include "dConfig.h" #include "dConfig.h"
#include "eObjectBits.h" #include "eObjectBits.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
#include "eClientMessageType.h" #include "MessageType/Client.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
#include "StringifiedEnum.h" #include "StringifiedEnum.h"
#include "eGameMasterLevel.h" #include "eGameMasterLevel.h"
#include "ChatPackets.h" #include "ChatPackets.h"
@ -60,11 +60,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
//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:
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(playerID); bitStream.Write(playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::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());
@ -368,10 +368,10 @@ void ChatPacketHandler::HandleWho(Packet* packet) {
bool online = player; bool online = player;
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor); bitStream.Write(request.requestor);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::WHO_RESPONSE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::WHO_RESPONSE);
bitStream.Write<uint8_t>(online); bitStream.Write<uint8_t>(online);
bitStream.Write(player.zoneID.GetMapID()); bitStream.Write(player.zoneID.GetMapID());
bitStream.Write(player.zoneID.GetInstanceID()); bitStream.Write(player.zoneID.GetInstanceID());
@ -391,10 +391,10 @@ void ChatPacketHandler::HandleShowAll(Packet* packet) {
if (!sender) return; if (!sender) return;
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor); bitStream.Write(request.requestor);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SHOW_ALL_RESPONSE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::SHOW_ALL_RESPONSE);
bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers); bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers);
bitStream.Write(Game::playerContainer.GetPlayerCount()); bitStream.Write(Game::playerContainer.GetPlayerCount());
bitStream.Write(Game::playerContainer.GetSimCount()); bitStream.Write(Game::playerContainer.GetSimCount());
@ -515,10 +515,10 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
void ChatPacketHandler::SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode) { void ChatPacketHandler::SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(routeTo.playerID); bitStream.Write(routeTo.playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::PRIVATE_CHAT_MESSAGE);
bitStream.Write(sender.playerID); bitStream.Write(sender.playerID);
bitStream.Write(channel); bitStream.Write(channel);
bitStream.Write<uint32_t>(0); // not used bitStream.Write<uint32_t>(0); // not used
@ -757,11 +757,11 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) {
void ChatPacketHandler::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) { void ChatPacketHandler::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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, MessageType::Client::TEAM_INVITE);
bitStream.Write(LUWString(sender.playerName.c_str())); bitStream.Write(LUWString(sender.playerName.c_str()));
bitStream.Write(sender.playerID); bitStream.Write(sender.playerID);
@ -772,14 +772,14 @@ void ChatPacketHandler::SendTeamInvite(const PlayerData& receiver, const PlayerD
void ChatPacketHandler::SendTeamInviteConfirm(const 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, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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(MessageType::Game::TEAM_INVITE_CONFIRM);
bitStream.Write(bLeaderIsFreeTrial); bitStream.Write(bLeaderIsFreeTrial);
bitStream.Write(i64LeaderID); bitStream.Write(i64LeaderID);
@ -799,14 +799,14 @@ void ChatPacketHandler::SendTeamInviteConfirm(const PlayerData& receiver, bool b
void ChatPacketHandler::SendTeamStatus(const 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, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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(MessageType::Game::TEAM_GET_STATUS_RESPONSE);
bitStream.Write(i64LeaderID); bitStream.Write(i64LeaderID);
bitStream.Write(i64LeaderZoneID); bitStream.Write(i64LeaderZoneID);
@ -824,14 +824,14 @@ void ChatPacketHandler::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64L
void ChatPacketHandler::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) { void ChatPacketHandler::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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(MessageType::Game::TEAM_SET_LEADER);
bitStream.Write(i64PlayerID); bitStream.Write(i64PlayerID);
@ -841,14 +841,14 @@ void ChatPacketHandler::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i
void ChatPacketHandler::SendTeamAddPlayer(const 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, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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(MessageType::Game::TEAM_ADD_PLAYER);
bitStream.Write(bIsFreeTrial); bitStream.Write(bIsFreeTrial);
bitStream.Write(bLocal); bitStream.Write(bLocal);
@ -870,14 +870,14 @@ void ChatPacketHandler::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFr
void ChatPacketHandler::SendTeamRemovePlayer(const 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, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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(MessageType::Game::TEAM_REMOVE_PLAYER);
bitStream.Write(bDisband); bitStream.Write(bDisband);
bitStream.Write(bIsKicked); bitStream.Write(bIsKicked);
@ -896,14 +896,14 @@ void ChatPacketHandler::SendTeamRemovePlayer(const PlayerData& receiver, bool bD
void ChatPacketHandler::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) { void ChatPacketHandler::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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(MessageType::Game::TEAM_SET_OFF_WORLD_FLAG);
bitStream.Write(i64PlayerID); bitStream.Write(i64PlayerID);
if (receiver.zoneID.GetCloneID() == zoneID.GetCloneID()) { if (receiver.zoneID.GetCloneID() == zoneID.GetCloneID()) {
@ -930,11 +930,11 @@ void ChatPacketHandler::SendFriendUpdate(const PlayerData& friendData, const Pla
[bool] - is FTP*/ [bool] - is FTP*/
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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, MessageType::Client::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();
@ -967,11 +967,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
} }
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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, MessageType::Client::ADD_FRIEND_REQUEST);
bitStream.Write(LUWString(sender.playerName)); 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.
@ -981,11 +981,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const 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) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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, MessageType::Client::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);
@ -1004,11 +1004,11 @@ void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const Pla
void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) { void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
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, MessageType::Client::REMOVE_FRIEND_RESPONSE);
bitStream.Write<uint8_t>(isSuccessful); //isOnline bitStream.Write<uint8_t>(isSuccessful); //isOnline
bitStream.Write(LUWString(personToRemove)); bitStream.Write(LUWString(personToRemove));

View File

@ -16,8 +16,8 @@
#include "eConnectionType.h" #include "eConnectionType.h"
#include "PlayerContainer.h" #include "PlayerContainer.h"
#include "ChatPacketHandler.h" #include "ChatPacketHandler.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
#include "eWorldMessageType.h" #include "MessageType/World.h"
#include "ChatIgnoreList.h" #include "ChatIgnoreList.h"
#include "StringifiedEnum.h" #include "StringifiedEnum.h"
@ -190,154 +190,154 @@ void HandlePacket(Packet* packet) {
inStream.SetReadOffset(BYTES_TO_BITS(1)); inStream.SetReadOffset(BYTES_TO_BITS(1));
eConnectionType connection; eConnectionType connection;
eChatMessageType chatMessageID; MessageType::Chat chatMessageID;
inStream.Read(connection); inStream.Read(connection);
if (connection != eConnectionType::CHAT) return; if (connection != eConnectionType::CHAT) return;
inStream.Read(chatMessageID); inStream.Read(chatMessageID);
switch (chatMessageID) { switch (chatMessageID) {
case eChatMessageType::GM_MUTE: case MessageType::Chat::GM_MUTE:
Game::playerContainer.MuteUpdate(packet); Game::playerContainer.MuteUpdate(packet);
break; break;
case eChatMessageType::CREATE_TEAM: case MessageType::Chat::CREATE_TEAM:
Game::playerContainer.CreateTeamServer(packet); Game::playerContainer.CreateTeamServer(packet);
break; break;
case eChatMessageType::GET_FRIENDS_LIST: case MessageType::Chat::GET_FRIENDS_LIST:
ChatPacketHandler::HandleFriendlistRequest(packet); ChatPacketHandler::HandleFriendlistRequest(packet);
break; break;
case eChatMessageType::GET_IGNORE_LIST: case MessageType::Chat::GET_IGNORE_LIST:
ChatIgnoreList::GetIgnoreList(packet); ChatIgnoreList::GetIgnoreList(packet);
break; break;
case eChatMessageType::ADD_IGNORE: case MessageType::Chat::ADD_IGNORE:
ChatIgnoreList::AddIgnore(packet); ChatIgnoreList::AddIgnore(packet);
break; break;
case eChatMessageType::REMOVE_IGNORE: case MessageType::Chat::REMOVE_IGNORE:
ChatIgnoreList::RemoveIgnore(packet); ChatIgnoreList::RemoveIgnore(packet);
break; break;
case eChatMessageType::TEAM_GET_STATUS: case MessageType::Chat::TEAM_GET_STATUS:
ChatPacketHandler::HandleTeamStatusRequest(packet); ChatPacketHandler::HandleTeamStatusRequest(packet);
break; break;
case eChatMessageType::ADD_FRIEND_REQUEST: case MessageType::Chat::ADD_FRIEND_REQUEST:
//this involves someone sending the initial request, the response is below, response as in from the other player. //this involves someone sending the initial request, the response is below, response as in from the other player.
//We basically just check to see if this player is online or not and route the packet. //We basically just check to see if this player is online or not and route the packet.
ChatPacketHandler::HandleFriendRequest(packet); ChatPacketHandler::HandleFriendRequest(packet);
break; break;
case eChatMessageType::ADD_FRIEND_RESPONSE: case MessageType::Chat::ADD_FRIEND_RESPONSE:
//This isn't the response a server sent, rather it is a player's response to a received request. //This isn't the response a server sent, rather it is a player's response to a received request.
//Here, we'll actually have to add them to eachother's friend lists depending on the response code. //Here, we'll actually have to add them to eachother's friend lists depending on the response code.
ChatPacketHandler::HandleFriendResponse(packet); ChatPacketHandler::HandleFriendResponse(packet);
break; break;
case eChatMessageType::REMOVE_FRIEND: case MessageType::Chat::REMOVE_FRIEND:
ChatPacketHandler::HandleRemoveFriend(packet); ChatPacketHandler::HandleRemoveFriend(packet);
break; break;
case eChatMessageType::GENERAL_CHAT_MESSAGE: case MessageType::Chat::GENERAL_CHAT_MESSAGE:
ChatPacketHandler::HandleChatMessage(packet); ChatPacketHandler::HandleChatMessage(packet);
break; break;
case eChatMessageType::PRIVATE_CHAT_MESSAGE: case MessageType::Chat::PRIVATE_CHAT_MESSAGE:
//This message is supposed to be echo'd to both the sender and the receiver //This message is supposed to be echo'd to both the sender and the receiver
//BUT: they have to have different responseCodes, so we'll do some of the ol hacky wacky to fix that right up. //BUT: they have to have different responseCodes, so we'll do some of the ol hacky wacky to fix that right up.
ChatPacketHandler::HandlePrivateChatMessage(packet); ChatPacketHandler::HandlePrivateChatMessage(packet);
break; break;
case eChatMessageType::TEAM_INVITE: case MessageType::Chat::TEAM_INVITE:
ChatPacketHandler::HandleTeamInvite(packet); ChatPacketHandler::HandleTeamInvite(packet);
break; break;
case eChatMessageType::TEAM_INVITE_RESPONSE: case MessageType::Chat::TEAM_INVITE_RESPONSE:
ChatPacketHandler::HandleTeamInviteResponse(packet); ChatPacketHandler::HandleTeamInviteResponse(packet);
break; break;
case eChatMessageType::TEAM_LEAVE: case MessageType::Chat::TEAM_LEAVE:
ChatPacketHandler::HandleTeamLeave(packet); ChatPacketHandler::HandleTeamLeave(packet);
break; break;
case eChatMessageType::TEAM_SET_LEADER: case MessageType::Chat::TEAM_SET_LEADER:
ChatPacketHandler::HandleTeamPromote(packet); ChatPacketHandler::HandleTeamPromote(packet);
break; break;
case eChatMessageType::TEAM_KICK: case MessageType::Chat::TEAM_KICK:
ChatPacketHandler::HandleTeamKick(packet); ChatPacketHandler::HandleTeamKick(packet);
break; break;
case eChatMessageType::TEAM_SET_LOOT: case MessageType::Chat::TEAM_SET_LOOT:
ChatPacketHandler::HandleTeamLootOption(packet); ChatPacketHandler::HandleTeamLootOption(packet);
break; break;
case eChatMessageType::GMLEVEL_UPDATE: case MessageType::Chat::GMLEVEL_UPDATE:
ChatPacketHandler::HandleGMLevelUpdate(packet); ChatPacketHandler::HandleGMLevelUpdate(packet);
break; break;
case eChatMessageType::LOGIN_SESSION_NOTIFY: case MessageType::Chat::LOGIN_SESSION_NOTIFY:
Game::playerContainer.InsertPlayer(packet); Game::playerContainer.InsertPlayer(packet);
break; break;
case eChatMessageType::GM_ANNOUNCE:{ case MessageType::Chat::GM_ANNOUNCE:{
// we just forward this packet to every connected server // we just forward this packet to every connected server
inStream.ResetReadPointer(); inStream.ResetReadPointer();
Game::server->Send(inStream, packet->systemAddress, true); // send to everyone except origin Game::server->Send(inStream, packet->systemAddress, true); // send to everyone except origin
} }
break; break;
case eChatMessageType::UNEXPECTED_DISCONNECT: case MessageType::Chat::UNEXPECTED_DISCONNECT:
Game::playerContainer.RemovePlayer(packet); Game::playerContainer.RemovePlayer(packet);
break; break;
case eChatMessageType::WHO: case MessageType::Chat::WHO:
ChatPacketHandler::HandleWho(packet); ChatPacketHandler::HandleWho(packet);
break; break;
case eChatMessageType::SHOW_ALL: case MessageType::Chat::SHOW_ALL:
ChatPacketHandler::HandleShowAll(packet); ChatPacketHandler::HandleShowAll(packet);
break; break;
case eChatMessageType::USER_CHANNEL_CHAT_MESSAGE: case MessageType::Chat::USER_CHANNEL_CHAT_MESSAGE:
case eChatMessageType::WORLD_DISCONNECT_REQUEST: case MessageType::Chat::WORLD_DISCONNECT_REQUEST:
case eChatMessageType::WORLD_PROXIMITY_RESPONSE: case MessageType::Chat::WORLD_PROXIMITY_RESPONSE:
case eChatMessageType::WORLD_PARCEL_RESPONSE: case MessageType::Chat::WORLD_PARCEL_RESPONSE:
case eChatMessageType::TEAM_MISSED_INVITE_CHECK: case MessageType::Chat::TEAM_MISSED_INVITE_CHECK:
case eChatMessageType::GUILD_CREATE: case MessageType::Chat::GUILD_CREATE:
case eChatMessageType::GUILD_INVITE: case MessageType::Chat::GUILD_INVITE:
case eChatMessageType::GUILD_INVITE_RESPONSE: case MessageType::Chat::GUILD_INVITE_RESPONSE:
case eChatMessageType::GUILD_LEAVE: case MessageType::Chat::GUILD_LEAVE:
case eChatMessageType::GUILD_KICK: case MessageType::Chat::GUILD_KICK:
case eChatMessageType::GUILD_GET_STATUS: case MessageType::Chat::GUILD_GET_STATUS:
case eChatMessageType::GUILD_GET_ALL: case MessageType::Chat::GUILD_GET_ALL:
case eChatMessageType::BLUEPRINT_MODERATED: case MessageType::Chat::BLUEPRINT_MODERATED:
case eChatMessageType::BLUEPRINT_MODEL_READY: case MessageType::Chat::BLUEPRINT_MODEL_READY:
case eChatMessageType::PROPERTY_READY_FOR_APPROVAL: case MessageType::Chat::PROPERTY_READY_FOR_APPROVAL:
case eChatMessageType::PROPERTY_MODERATION_CHANGED: case MessageType::Chat::PROPERTY_MODERATION_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED: case MessageType::Chat::PROPERTY_BUILDMODE_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED_REPORT: case MessageType::Chat::PROPERTY_BUILDMODE_CHANGED_REPORT:
case eChatMessageType::MAIL: case MessageType::Chat::MAIL:
case eChatMessageType::WORLD_INSTANCE_LOCATION_REQUEST: case MessageType::Chat::WORLD_INSTANCE_LOCATION_REQUEST:
case eChatMessageType::REPUTATION_UPDATE: case MessageType::Chat::REPUTATION_UPDATE:
case eChatMessageType::SEND_CANNED_TEXT: case MessageType::Chat::SEND_CANNED_TEXT:
case eChatMessageType::CHARACTER_NAME_CHANGE_REQUEST: case MessageType::Chat::CHARACTER_NAME_CHANGE_REQUEST:
case eChatMessageType::CSR_REQUEST: case MessageType::Chat::CSR_REQUEST:
case eChatMessageType::CSR_REPLY: case MessageType::Chat::CSR_REPLY:
case eChatMessageType::GM_KICK: case MessageType::Chat::GM_KICK:
case eChatMessageType::WORLD_ROUTE_PACKET: case MessageType::Chat::WORLD_ROUTE_PACKET:
case eChatMessageType::GET_ZONE_POPULATIONS: case MessageType::Chat::GET_ZONE_POPULATIONS:
case eChatMessageType::REQUEST_MINIMUM_CHAT_MODE: case MessageType::Chat::REQUEST_MINIMUM_CHAT_MODE:
case eChatMessageType::MATCH_REQUEST: case MessageType::Chat::MATCH_REQUEST:
case eChatMessageType::UGCMANIFEST_REPORT_MISSING_FILE: case MessageType::Chat::UGCMANIFEST_REPORT_MISSING_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_FILE: case MessageType::Chat::UGCMANIFEST_REPORT_DONE_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_BLUEPRINT: case MessageType::Chat::UGCMANIFEST_REPORT_DONE_BLUEPRINT:
case eChatMessageType::UGCC_REQUEST: case MessageType::Chat::UGCC_REQUEST:
case eChatMessageType::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE: case MessageType::Chat::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE:
case eChatMessageType::ACHIEVEMENT_NOTIFY: case MessageType::Chat::ACHIEVEMENT_NOTIFY:
case eChatMessageType::GM_CLOSE_PRIVATE_CHAT_WINDOW: case MessageType::Chat::GM_CLOSE_PRIVATE_CHAT_WINDOW:
case eChatMessageType::PLAYER_READY: case MessageType::Chat::PLAYER_READY:
case eChatMessageType::GET_DONATION_TOTAL: case MessageType::Chat::GET_DONATION_TOTAL:
case eChatMessageType::UPDATE_DONATION: case MessageType::Chat::UPDATE_DONATION:
case eChatMessageType::PRG_CSR_COMMAND: case MessageType::Chat::PRG_CSR_COMMAND:
case eChatMessageType::HEARTBEAT_REQUEST_FROM_WORLD: case MessageType::Chat::HEARTBEAT_REQUEST_FROM_WORLD:
case eChatMessageType::UPDATE_FREE_TRIAL_STATUS: case MessageType::Chat::UPDATE_FREE_TRIAL_STATUS:
LOG("Unhandled CHAT Message id: %s (%i)", StringifiedEnum::ToString(chatMessageID).data(), chatMessageID); LOG("Unhandled CHAT Message id: %s (%i)", StringifiedEnum::ToString(chatMessageID).data(), chatMessageID);
break; break;
default: default:

View File

@ -11,7 +11,7 @@
#include "eConnectionType.h" #include "eConnectionType.h"
#include "ChatPackets.h" #include "ChatPackets.h"
#include "dConfig.h" #include "dConfig.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
void PlayerContainer::Initialize() { void PlayerContainer::Initialize() {
m_MaxNumberOfBestFriends = m_MaxNumberOfBestFriends =
@ -148,14 +148,13 @@ void PlayerContainer::CreateTeamServer(Packet* packet) {
if (team != nullptr) { if (team != nullptr) {
team->zoneId = zoneId; team->zoneId = zoneId;
}
UpdateTeamsOnWorld(team, false); UpdateTeamsOnWorld(team, false);
}
} }
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) { void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GM_MUTE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_MUTE);
bitStream.Write(player); bitStream.Write(player);
bitStream.Write(time); bitStream.Write(time);
@ -362,7 +361,7 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) {
void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) { void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::TEAM_GET_STATUS); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::TEAM_GET_STATUS);
bitStream.Write(team->teamID); bitStream.Write(team->teamID);
bitStream.Write(deleteTeam); bitStream.Write(deleteTeam);

View File

@ -9,73 +9,54 @@
* AMF3 Deserializer written by EmosewaMC * AMF3 Deserializer written by EmosewaMC
*/ */
AMFBaseValue* AMFDeserialize::Read(RakNet::BitStream& inStream) { std::unique_ptr<AMFBaseValue> AMFDeserialize::Read(RakNet::BitStream& inStream) {
AMFBaseValue* returnValue = nullptr;
// Read in the value type from the bitStream // Read in the value type from the bitStream
eAmf marker; eAmf marker;
inStream.Read(marker); inStream.Read(marker);
// Based on the typing, create the value associated with that and return the base value class // Based on the typing, create the value associated with that and return the base value class
switch (marker) { switch (marker) {
case eAmf::Undefined: { case eAmf::Undefined:
returnValue = new AMFBaseValue(); return std::make_unique<AMFBaseValue>();
break; case eAmf::Null:
} return std::make_unique<AMFNullValue>();
case eAmf::False:
case eAmf::Null: { return std::make_unique<AMFBoolValue>(false);
returnValue = new AMFNullValue(); case eAmf::True:
break; return std::make_unique<AMFBoolValue>(true);
} case eAmf::Integer:
return ReadAmfInteger(inStream);
case eAmf::False: { case eAmf::Double:
returnValue = new AMFBoolValue(false); return ReadAmfDouble(inStream);
break; case eAmf::String:
} return ReadAmfString(inStream);
case eAmf::Array:
case eAmf::True: { return ReadAmfArray(inStream);
returnValue = new AMFBoolValue(true);
break;
}
case eAmf::Integer: {
returnValue = ReadAmfInteger(inStream);
break;
}
case eAmf::Double: {
returnValue = ReadAmfDouble(inStream);
break;
}
case eAmf::String: {
returnValue = ReadAmfString(inStream);
break;
}
case eAmf::Array: {
returnValue = ReadAmfArray(inStream);
break;
}
// These values are unimplemented in the live client and will remain unimplemented // These values are unimplemented in the live client and will remain unimplemented
// unless someone modifies the client to allow serializing of these values. // unless someone modifies the client to allow serializing of these values.
case eAmf::XMLDoc: case eAmf::XMLDoc:
[[fallthrough]];
case eAmf::Date: case eAmf::Date:
[[fallthrough]];
case eAmf::Object: case eAmf::Object:
[[fallthrough]];
case eAmf::XML: case eAmf::XML:
[[fallthrough]];
case eAmf::ByteArray: case eAmf::ByteArray:
[[fallthrough]];
case eAmf::VectorInt: case eAmf::VectorInt:
[[fallthrough]];
case eAmf::VectorUInt: case eAmf::VectorUInt:
[[fallthrough]];
case eAmf::VectorDouble: case eAmf::VectorDouble:
[[fallthrough]];
case eAmf::VectorObject: case eAmf::VectorObject:
case eAmf::Dictionary: { [[fallthrough]];
case eAmf::Dictionary:
throw marker; throw marker;
break;
}
default: default:
throw std::invalid_argument("Invalid AMF3 marker" + std::to_string(static_cast<int32_t>(marker))); throw std::invalid_argument("Invalid AMF3 marker" + std::to_string(static_cast<int32_t>(marker)));
break;
} }
return returnValue;
} }
uint32_t AMFDeserialize::ReadU29(RakNet::BitStream& inStream) { uint32_t AMFDeserialize::ReadU29(RakNet::BitStream& inStream) {
@ -118,14 +99,14 @@ const std::string AMFDeserialize::ReadString(RakNet::BitStream& inStream) {
} }
} }
AMFBaseValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream& inStream) { std::unique_ptr<AMFDoubleValue> AMFDeserialize::ReadAmfDouble(RakNet::BitStream& inStream) {
double value; double value;
inStream.Read<double>(value); inStream.Read<double>(value);
return new AMFDoubleValue(value); return std::make_unique<AMFDoubleValue>(value);
} }
AMFBaseValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream& inStream) { std::unique_ptr<AMFArrayValue> AMFDeserialize::ReadAmfArray(RakNet::BitStream& inStream) {
auto arrayValue = new AMFArrayValue(); auto arrayValue = std::make_unique<AMFArrayValue>();
// Read size of dense array // Read size of dense array
const auto sizeOfDenseArray = (ReadU29(inStream) >> 1); const auto sizeOfDenseArray = (ReadU29(inStream) >> 1);
@ -143,10 +124,10 @@ AMFBaseValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream& inStream) {
return arrayValue; return arrayValue;
} }
AMFBaseValue* AMFDeserialize::ReadAmfString(RakNet::BitStream& inStream) { std::unique_ptr<AMFStringValue> AMFDeserialize::ReadAmfString(RakNet::BitStream& inStream) {
return new AMFStringValue(ReadString(inStream)); return std::make_unique<AMFStringValue>(ReadString(inStream));
} }
AMFBaseValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream& inStream) { std::unique_ptr<AMFIntValue> AMFDeserialize::ReadAmfInteger(RakNet::BitStream& inStream) {
return new AMFIntValue(ReadU29(inStream)); return std::make_unique<AMFIntValue>(ReadU29(inStream)); // NOTE: NARROWING CONVERSION FROM UINT TO INT. IS THIS INTENDED?
} }

View File

@ -1,12 +1,12 @@
#pragma once #pragma once
#include "Amf3.h"
#include "BitStream.h" #include "BitStream.h"
#include <memory>
#include <vector> #include <vector>
#include <string> #include <string>
class AMFBaseValue;
class AMFDeserialize { class AMFDeserialize {
public: public:
/** /**
@ -15,7 +15,7 @@ public:
* @param inStream inStream to read value from. * @param inStream inStream to read value from.
* @return Returns an AMFValue with all the information from the bitStream in it. * @return Returns an AMFValue with all the information from the bitStream in it.
*/ */
AMFBaseValue* Read(RakNet::BitStream& inStream); std::unique_ptr<AMFBaseValue> Read(RakNet::BitStream& inStream);
private: private:
/** /**
* @brief Private method to read a U29 integer from a bitstream * @brief Private method to read a U29 integer from a bitstream
@ -39,7 +39,7 @@ private:
* @param inStream bitStream to read data from * @param inStream bitStream to read data from
* @return Double value represented as an AMFValue * @return Double value represented as an AMFValue
*/ */
AMFBaseValue* ReadAmfDouble(RakNet::BitStream& inStream); static std::unique_ptr<AMFDoubleValue> ReadAmfDouble(RakNet::BitStream& inStream);
/** /**
* @brief Read an AMFArray from a bitStream * @brief Read an AMFArray from a bitStream
@ -47,7 +47,7 @@ private:
* @param inStream bitStream to read data from * @param inStream bitStream to read data from
* @return Array value represented as an AMFValue * @return Array value represented as an AMFValue
*/ */
AMFBaseValue* ReadAmfArray(RakNet::BitStream& inStream); std::unique_ptr<AMFArrayValue> ReadAmfArray(RakNet::BitStream& inStream);
/** /**
* @brief Read an AMFString from a bitStream * @brief Read an AMFString from a bitStream
@ -55,7 +55,7 @@ private:
* @param inStream bitStream to read data from * @param inStream bitStream to read data from
* @return String value represented as an AMFValue * @return String value represented as an AMFValue
*/ */
AMFBaseValue* ReadAmfString(RakNet::BitStream& inStream); std::unique_ptr<AMFStringValue> ReadAmfString(RakNet::BitStream& inStream);
/** /**
* @brief Read an AMFInteger from a bitStream * @brief Read an AMFInteger from a bitStream
@ -63,7 +63,7 @@ private:
* @param inStream bitStream to read data from * @param inStream bitStream to read data from
* @return Integer value represented as an AMFValue * @return Integer value represented as an AMFValue
*/ */
AMFBaseValue* ReadAmfInteger(RakNet::BitStream& inStream); static std::unique_ptr<AMFIntValue> ReadAmfInteger(RakNet::BitStream& inStream);
/** /**
* List of strings read so far saved to be read by reference. * List of strings read so far saved to be read by reference.

View File

@ -105,27 +105,14 @@ using AMFDoubleValue = AMFValue<double>;
* and are not to be deleted by a caller. * and are not to be deleted by a caller.
*/ */
class AMFArrayValue : public AMFBaseValue { class AMFArrayValue : public AMFBaseValue {
using AMFAssociative = std::unordered_map<std::string, AMFBaseValue*>; using AMFAssociative =
using AMFDense = std::vector<AMFBaseValue*>; std::unordered_map<std::string, std::unique_ptr<AMFBaseValue>, GeneralUtils::transparent_string_hash, std::equal_to<>>;
using AMFDense = std::vector<std::unique_ptr<AMFBaseValue>>;
public: public:
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::Array; } [[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::Array; }
~AMFArrayValue() override {
for (const auto* valueToDelete : GetDense()) {
if (valueToDelete) {
delete valueToDelete;
valueToDelete = nullptr;
}
}
for (auto valueToDelete : GetAssociative()) {
if (valueToDelete.second) {
delete valueToDelete.second;
valueToDelete.second = nullptr;
}
}
}
/** /**
* Returns the Associative portion of the object * Returns the Associative portion of the object
*/ */
@ -151,30 +138,32 @@ public:
* or nullptr if a key existed and was not the same type * or nullptr if a key existed and was not the same type
*/ */
template <typename ValueType> template <typename ValueType>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, const ValueType value) { [[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const std::string_view key, const ValueType value) {
const auto element = m_Associative.find(key); const auto element = m_Associative.find(key);
AMFValue<ValueType>* val = nullptr; AMFValue<ValueType>* val = nullptr;
bool found = true; bool found = true;
if (element == m_Associative.cend()) { if (element == m_Associative.cend()) {
val = new AMFValue<ValueType>(value); auto newVal = std::make_unique<AMFValue<ValueType>>(value);
m_Associative.emplace(key, val); val = newVal.get();
m_Associative.emplace(key, std::move(newVal));
} else { } else {
val = dynamic_cast<AMFValue<ValueType>*>(element->second); val = dynamic_cast<AMFValue<ValueType>*>(element->second.get());
found = false; found = false;
} }
return std::make_pair(val, found); return std::make_pair(val, found);
} }
// Associates an array with a string key // Associates an array with a string key
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const std::string& key) { [[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const std::string_view key) {
const auto element = m_Associative.find(key); const auto element = m_Associative.find(key);
AMFArrayValue* val = nullptr; AMFArrayValue* val = nullptr;
bool found = true; bool found = true;
if (element == m_Associative.cend()) { if (element == m_Associative.cend()) {
val = new AMFArrayValue(); auto newVal = std::make_unique<AMFArrayValue>();
m_Associative.emplace(key, val); val = newVal.get();
m_Associative.emplace(key, std::move(newVal));
} else { } else {
val = dynamic_cast<AMFArrayValue*>(element->second); val = dynamic_cast<AMFArrayValue*>(element->second.get());
found = false; found = false;
} }
return std::make_pair(val, found); return std::make_pair(val, found);
@ -182,15 +171,13 @@ public:
// Associates an array with an integer key // Associates an array with an integer key
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const size_t index) { [[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const size_t index) {
AMFArrayValue* val = nullptr;
bool inserted = false; bool inserted = false;
if (index >= m_Dense.size()) { if (index >= m_Dense.size()) {
m_Dense.resize(index + 1); m_Dense.resize(index + 1);
val = new AMFArrayValue(); m_Dense.at(index) = std::make_unique<AMFArrayValue>();
m_Dense.at(index) = val;
inserted = true; inserted = true;
} }
return std::make_pair(dynamic_cast<AMFArrayValue*>(m_Dense.at(index)), inserted); return std::make_pair(dynamic_cast<AMFArrayValue*>(m_Dense.at(index).get()), inserted);
} }
/** /**
@ -205,15 +192,13 @@ public:
*/ */
template <typename ValueType> template <typename ValueType>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const size_t index, const ValueType value) { [[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const size_t index, const ValueType value) {
AMFValue<ValueType>* val = nullptr;
bool inserted = false; bool inserted = false;
if (index >= m_Dense.size()) { if (index >= m_Dense.size()) {
m_Dense.resize(index + 1); m_Dense.resize(index + 1);
val = new AMFValue<ValueType>(value); m_Dense.at(index) = std::make_unique<AMFValue<ValueType>>(value);
m_Dense.at(index) = val;
inserted = true; inserted = true;
} }
return std::make_pair(dynamic_cast<AMFValue<ValueType>*>(m_Dense.at(index)), inserted); return std::make_pair(dynamic_cast<AMFValue<ValueType>*>(m_Dense.at(index).get()), inserted);
} }
/** /**
@ -225,13 +210,12 @@ public:
* @param key The key to associate with the value * @param key The key to associate with the value
* @param value The value to insert * @param value The value to insert
*/ */
void Insert(const std::string& key, AMFBaseValue* const value) { void Insert(const std::string_view key, std::unique_ptr<AMFBaseValue> value) {
const auto element = m_Associative.find(key); const auto element = m_Associative.find(key);
if (element != m_Associative.cend() && element->second) { if (element != m_Associative.cend() && element->second) {
delete element->second; element->second = std::move(value);
element->second = value;
} else { } else {
m_Associative.emplace(key, value); m_Associative.emplace(key, std::move(value));
} }
} }
@ -244,14 +228,11 @@ public:
* @param key The key to associate with the value * @param key The key to associate with the value
* @param value The value to insert * @param value The value to insert
*/ */
void Insert(const size_t index, AMFBaseValue* const value) { void Insert(const size_t index, std::unique_ptr<AMFBaseValue> value) {
if (index < m_Dense.size()) { if (index >= m_Dense.size()) {
const AMFDense::const_iterator itr = m_Dense.cbegin() + index;
if (*itr) delete m_Dense.at(index);
} else {
m_Dense.resize(index + 1); m_Dense.resize(index + 1);
} }
m_Dense.at(index) = value; m_Dense.at(index) = std::move(value);
} }
/** /**
@ -279,8 +260,7 @@ public:
void Remove(const std::string& key, const bool deleteValue = true) { void Remove(const std::string& key, const bool deleteValue = true) {
const AMFAssociative::const_iterator it = m_Associative.find(key); const AMFAssociative::const_iterator it = m_Associative.find(key);
if (it != m_Associative.cend()) { if (it != m_Associative.cend()) {
if (deleteValue) delete it->second; if (deleteValue) m_Associative.erase(it);
m_Associative.erase(it);
} }
} }
@ -290,7 +270,6 @@ public:
void Remove(const size_t index) { void Remove(const size_t index) {
if (!m_Dense.empty() && index < m_Dense.size()) { if (!m_Dense.empty() && index < m_Dense.size()) {
const auto itr = m_Dense.cbegin() + index; const auto itr = m_Dense.cbegin() + index;
if (*itr) delete (*itr);
m_Dense.erase(itr); m_Dense.erase(itr);
} }
} }
@ -299,16 +278,16 @@ public:
if (!m_Dense.empty()) Remove(m_Dense.size() - 1); if (!m_Dense.empty()) Remove(m_Dense.size() - 1);
} }
[[nodiscard]] AMFArrayValue* GetArray(const std::string& key) const { [[nodiscard]] AMFArrayValue* GetArray(const std::string_view key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key); const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ? dynamic_cast<AMFArrayValue*>(it->second) : nullptr; return it != m_Associative.cend() ? dynamic_cast<AMFArrayValue*>(it->second.get()) : nullptr;
} }
[[nodiscard]] AMFArrayValue* GetArray(const size_t index) const { [[nodiscard]] AMFArrayValue* GetArray(const size_t index) const {
return index < m_Dense.size() ? dynamic_cast<AMFArrayValue*>(m_Dense.at(index)) : nullptr; return index < m_Dense.size() ? dynamic_cast<AMFArrayValue*>(m_Dense.at(index).get()) : nullptr;
} }
[[maybe_unused]] inline AMFArrayValue* InsertArray(const std::string& key) { [[maybe_unused]] inline AMFArrayValue* InsertArray(const std::string_view key) {
return static_cast<AMFArrayValue*>(Insert(key).first); return static_cast<AMFArrayValue*>(Insert(key).first);
} }
@ -330,17 +309,17 @@ public:
* @return The AMFValue * @return The AMFValue
*/ */
template <typename AmfType> template <typename AmfType>
[[nodiscard]] AMFValue<AmfType>* Get(const std::string& key) const { [[nodiscard]] AMFValue<AmfType>* Get(const std::string_view key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key); const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ? return it != m_Associative.cend() ?
dynamic_cast<AMFValue<AmfType>*>(it->second) : dynamic_cast<AMFValue<AmfType>*>(it->second.get()) :
nullptr; nullptr;
} }
// Get from the array but dont cast it // Get from the array but dont cast it
[[nodiscard]] AMFBaseValue* Get(const std::string& key) const { [[nodiscard]] AMFBaseValue* Get(const std::string_view key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key); const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ? it->second : nullptr; return it != m_Associative.cend() ? it->second.get() : nullptr;
} }
/** /**
@ -355,13 +334,13 @@ public:
template <typename AmfType> template <typename AmfType>
[[nodiscard]] AMFValue<AmfType>* Get(const size_t index) const { [[nodiscard]] AMFValue<AmfType>* Get(const size_t index) const {
return index < m_Dense.size() ? return index < m_Dense.size() ?
dynamic_cast<AMFValue<AmfType>*>(m_Dense.at(index)) : dynamic_cast<AMFValue<AmfType>*>(m_Dense.at(index).get()) :
nullptr; nullptr;
} }
// Get from the dense but dont cast it // Get from the dense but dont cast it
[[nodiscard]] AMFBaseValue* Get(const size_t index) const { [[nodiscard]] AMFBaseValue* Get(const size_t index) const {
return index < m_Dense.size() ? m_Dense.at(index) : nullptr; return index < m_Dense.size() ? m_Dense.at(index).get() : nullptr;
} }
private: private:

View File

@ -129,6 +129,29 @@ namespace GeneralUtils {
std::vector<std::string> GetSqlFileNamesFromFolder(const std::string_view folder); std::vector<std::string> GetSqlFileNamesFromFolder(const std::string_view folder);
/**
* Transparent string hasher - used to allow string_view key lookups for maps storing std::string keys
* https://www.reddit.com/r/cpp_questions/comments/12xw3sn/find_stdstring_view_in_unordered_map_with/jhki225/
* https://godbolt.org/z/789xv8Eeq
*/
template <typename... Bases>
struct overload : Bases... {
using is_transparent = void;
using Bases::operator() ... ;
};
struct char_pointer_hash {
auto operator()(const char* const ptr) const noexcept {
return std::hash<std::string_view>{}(ptr);
}
};
using transparent_string_hash = overload<
std::hash<std::string>,
std::hash<std::string_view>,
char_pointer_hash
>;
// Concept constraining to enum types // Concept constraining to enum types
template <typename T> template <typename T>
concept Enum = std::is_enum_v<T>; concept Enum = std::is_enum_v<T>;

92
dCommon/Implementation.h Normal file
View File

@ -0,0 +1,92 @@
#ifndef __IMPLEMENTATION_H__
#define __IMPLEMENTATION_H__
#include <functional>
#include <optional>
/**
* @brief A way to defer the implementation of an action.
*
* @tparam R The result of the action.
* @tparam T The types of the arguments that the implementation requires.
*/
template <typename R, typename... T>
class Implementation {
public:
typedef std::function<std::optional<R>(T...)> ImplementationFunction;
/**
* @brief Sets the implementation of the action.
*
* @param implementation The implementation of the action.
*/
void SetImplementation(const ImplementationFunction& implementation) {
this->implementation = implementation;
}
/**
* @brief Clears the implementation of the action.
*/
void ClearImplementation() {
implementation.reset();
}
/**
* @brief Checks if the implementation is set.
*
* @return true If the implementation is set.
* @return false If the implementation is not set.
*/
bool IsSet() const {
return implementation.has_value();
}
/**
* @brief Executes the implementation if it is set.
*
* @param args The arguments to pass to the implementation.
* @return std::optional<R> The optional result of the implementation. If the result is not set, it indicates that the default action should be taken.
*/
std::optional<R> Execute(T... args) const {
return IsSet() ? implementation.value()(args...) : std::nullopt;
}
/**
* @brief Exectues the implementation if it is set, otherwise returns a default value.
*
* @param args The arguments to pass to the implementation.
* @param defaultValue The default value to return if the implementation is not set or should not be deferred.
*/
R ExecuteWithDefault(T... args, const R& defaultValue) const {
return Execute(args...).value_or(defaultValue);
}
/**
* = operator overload.
*/
Implementation& operator=(const Implementation& other) {
implementation = other.implementation;
return *this;
}
/**
* = operator overload.
*/
Implementation& operator=(const ImplementationFunction& implementation) {
this->implementation = implementation;
return *this;
}
/**
* () operator overload.
*/
std::optional<R> operator()(T... args) {
return !IsSet() ? std::nullopt : implementation(args...);
}
private:
std::optional<ImplementationFunction> implementation;
};
#endif //!__IMPLEMENTATION_H__

73
dCommon/Observable.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef __OBSERVABLE_H__
#define __OBSERVABLE_H__
#include <vector>
#include <functional>
/**
* @brief An event which can be observed by multiple observers.
*
* @tparam T The types of the arguments to be passed to the observers.
*/
template <typename... T>
class Observable {
public:
typedef std::function<void(T...)> Observer;
/**
* @brief Adds an observer to the event.
*
* @param observer The observer to add.
*/
void AddObserver(const Observer& observer) {
observers.push_back(observer);
}
/**
* @brief Removes an observer from the event.
*
* @param observer The observer to remove.
*/
void RemoveObserver(const Observer& observer) {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
/**
* @brief Notifies all observers of the event.
*
* @param args The arguments to pass to the observers.
*/
void Notify(T... args) {
for (const auto& observer : observers) {
observer(args...);
}
}
/**
* += operator overload.
*/
Observable& operator+=(const Observer& observer) {
AddObserver(observer);
return *this;
}
/**
* -= operator overload.
*/
Observable& operator-=(const Observer& observer) {
RemoveObserver(observer);
return *this;
}
/**
* () operator overload.
*/
void operator()(T... args) {
Notify(args...);
}
private:
std::vector<Observer> observers;
};
#endif //!__OBSERVABLE_H__

View File

@ -0,0 +1,13 @@
#pragma once
#include <cstdint>
namespace MessageType {
enum class Auth : uint32_t {
LOGIN_REQUEST = 0,
LOGOUT_REQUEST,
CREATE_NEW_ACCOUNT_REQUEST,
LEGOINTERFACE_AUTH_RESPONSE,
SESSIONKEY_RECEIVED_CONFIRM,
RUNTIME_CONFIG
};
}

View File

@ -0,0 +1,78 @@
#pragma once
#include <cstdint>
namespace MessageType {
//! The Internal Chat Packet Identifiers
enum class Chat : uint32_t {
LOGIN_SESSION_NOTIFY = 0,
GENERAL_CHAT_MESSAGE,
PRIVATE_CHAT_MESSAGE,
USER_CHANNEL_CHAT_MESSAGE,
WORLD_DISCONNECT_REQUEST,
WORLD_PROXIMITY_RESPONSE,
WORLD_PARCEL_RESPONSE,
ADD_FRIEND_REQUEST,
ADD_FRIEND_RESPONSE,
REMOVE_FRIEND,
GET_FRIENDS_LIST,
ADD_IGNORE,
REMOVE_IGNORE,
GET_IGNORE_LIST,
TEAM_MISSED_INVITE_CHECK,
TEAM_INVITE,
TEAM_INVITE_RESPONSE,
TEAM_KICK,
TEAM_LEAVE,
TEAM_SET_LOOT,
TEAM_SET_LEADER,
TEAM_GET_STATUS,
GUILD_CREATE,
GUILD_INVITE,
GUILD_INVITE_RESPONSE,
GUILD_LEAVE,
GUILD_KICK,
GUILD_GET_STATUS,
GUILD_GET_ALL,
SHOW_ALL,
BLUEPRINT_MODERATED,
BLUEPRINT_MODEL_READY,
PROPERTY_READY_FOR_APPROVAL,
PROPERTY_MODERATION_CHANGED,
PROPERTY_BUILDMODE_CHANGED,
PROPERTY_BUILDMODE_CHANGED_REPORT,
MAIL,
WORLD_INSTANCE_LOCATION_REQUEST,
REPUTATION_UPDATE,
SEND_CANNED_TEXT,
GMLEVEL_UPDATE,
CHARACTER_NAME_CHANGE_REQUEST,
CSR_REQUEST,
CSR_REPLY,
GM_KICK,
GM_ANNOUNCE,
GM_MUTE,
ACTIVITY_UPDATE,
WORLD_ROUTE_PACKET,
GET_ZONE_POPULATIONS,
REQUEST_MINIMUM_CHAT_MODE,
REQUEST_MINIMUM_CHAT_MODE_PRIVATE,
MATCH_REQUEST,
UGCMANIFEST_REPORT_MISSING_FILE,
UGCMANIFEST_REPORT_DONE_FILE,
UGCMANIFEST_REPORT_DONE_BLUEPRINT,
UGCC_REQUEST,
WHO,
WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE,
ACHIEVEMENT_NOTIFY,
GM_CLOSE_PRIVATE_CHAT_WINDOW,
UNEXPECTED_DISCONNECT,
PLAYER_READY,
GET_DONATION_TOTAL,
UPDATE_DONATION,
PRG_CSR_COMMAND,
HEARTBEAT_REQUEST_FROM_WORLD,
UPDATE_FREE_TRIAL_STATUS,
// CUSTOM DLU MESSAGE ID FOR INTERNAL USE
CREATE_TEAM,
};
}

View File

@ -0,0 +1,74 @@
#pragma once
#include <cstdint>
namespace MessageType {
enum class Client : uint32_t {
LOGIN_RESPONSE = 0,
LOGOUT_RESPONSE,
LOAD_STATIC_ZONE,
CREATE_OBJECT,
CREATE_CHARACTER,
CREATE_CHARACTER_EXTENDED,
CHARACTER_LIST_RESPONSE,
CHARACTER_CREATE_RESPONSE,
CHARACTER_RENAME_RESPONSE,
CHAT_CONNECT_RESPONSE,
AUTH_ACCOUNT_CREATE_RESPONSE,
DELETE_CHARACTER_RESPONSE,
GAME_MSG,
CONNECT_CHAT,
TRANSFER_TO_WORLD,
IMPENDING_RELOAD_NOTIFY,
MAKE_GM_RESPONSE,
HTTP_MONITOR_INFO_RESPONSE,
SLASH_PUSH_MAP_RESPONSE,
SLASH_PULL_MAP_RESPONSE,
SLASH_LOCK_MAP_RESPONSE,
BLUEPRINT_SAVE_RESPONSE,
BLUEPRINT_LUP_SAVE_RESPONSE,
BLUEPRINT_LOAD_RESPONSE_ITEMID,
BLUEPRINT_GET_ALL_DATA_RESPONSE,
MODEL_INSTANTIATE_RESPONSE,
DEBUG_OUTPUT,
ADD_FRIEND_REQUEST,
ADD_FRIEND_RESPONSE,
REMOVE_FRIEND_RESPONSE,
GET_FRIENDS_LIST_RESPONSE,
UPDATE_FRIEND_NOTIFY,
ADD_IGNORE_RESPONSE,
REMOVE_IGNORE_RESPONSE,
GET_IGNORE_LIST_RESPONSE,
TEAM_INVITE,
TEAM_INVITE_INITIAL_RESPONSE,
GUILD_CREATE_RESPONSE,
GUILD_GET_STATUS_RESPONSE,
GUILD_INVITE,
GUILD_INVITE_INITIAL_RESPONSE,
GUILD_INVITE_FINAL_RESPONSE,
GUILD_INVITE_CONFIRM,
GUILD_ADD_PLAYER,
GUILD_REMOVE_PLAYER,
GUILD_LOGIN_LOGOUT,
GUILD_RANK_CHANGE,
GUILD_DATA,
GUILD_STATUS,
MAIL,
DB_PROXY_RESULT,
SHOW_ALL_RESPONSE,
WHO_RESPONSE,
SEND_CANNED_TEXT,
UPDATE_CHARACTER_NAME,
SET_NETWORK_SIMULATOR,
INVALID_CHAT_MESSAGE,
MINIMUM_CHAT_MODE_RESPONSE,
MINIMUM_CHAT_MODE_RESPONSE_PRIVATE,
CHAT_MODERATION_STRING,
UGC_MANIFEST_RESPONSE,
IN_LOGIN_QUEUE,
SERVER_STATES,
GM_CLOSE_TARGET_CHAT_WINDOW,
GENERAL_TEXT_FOR_LOCALIZATION,
UPDATE_FREE_TRIAL_STATUS,
UGC_DOWNLOAD_FAILED = 120
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
namespace MessageType {
enum class Master : uint32_t {
REQUEST_PERSISTENT_ID = 1,
REQUEST_PERSISTENT_ID_RESPONSE,
REQUEST_ZONE_TRANSFER,
REQUEST_ZONE_TRANSFER_RESPONSE,
SERVER_INFO,
REQUEST_SESSION_KEY,
SET_SESSION_KEY,
SESSION_KEY_RESPONSE,
PLAYER_ADDED,
PLAYER_REMOVED,
CREATE_PRIVATE_ZONE,
REQUEST_PRIVATE_ZONE,
WORLD_READY,
PREP_ZONE,
SHUTDOWN,
SHUTDOWN_RESPONSE,
SHUTDOWN_IMMEDIATE,
SHUTDOWN_UNIVERSE,
AFFIRM_TRANSFER_REQUEST,
AFFIRM_TRANSFER_RESPONSE,
NEW_SESSION_ALERT
};
}

View File

@ -0,0 +1,11 @@
#pragma once
#include <cstdint>
namespace MessageType {
//! The Internal Server Packet Identifiers
enum class Server : uint32_t {
VERSION_CONFIRM = 0,
DISCONNECT_NOTIFY,
GENERAL_NOTIFY
};
}

View File

@ -0,0 +1,49 @@
#pragma once
#include <cstdint>
#include "magic_enum.hpp"
namespace MessageType {
enum class World : uint32_t {
VALIDATION = 1, // Session info
CHARACTER_LIST_REQUEST,
CHARACTER_CREATE_REQUEST,
LOGIN_REQUEST, // Character selected
GAME_MSG,
CHARACTER_DELETE_REQUEST,
CHARACTER_RENAME_REQUEST,
HAPPY_FLOWER_MODE_NOTIFY,
SLASH_RELOAD_MAP, // Reload map cmp
SLASH_PUSH_MAP_REQUEST, // Push map req cmd
SLASH_PUSH_MAP, // Push map cmd
SLASH_PULL_MAP, // Pull map cmd
LOCK_MAP_REQUEST,
GENERAL_CHAT_MESSAGE, // General chat message
HTTP_MONITOR_INFO_REQUEST,
SLASH_DEBUG_SCRIPTS, // Debug scripts cmd
MODELS_CLEAR,
EXHIBIT_INSERT_MODEL,
LEVEL_LOAD_COMPLETE, // Character data request
TMP_GUILD_CREATE,
ROUTE_PACKET, // Social?
POSITION_UPDATE,
MAIL,
WORD_CHECK, // AllowList word check
STRING_CHECK, // AllowList string check
GET_PLAYERS_IN_ZONE,
REQUEST_UGC_MANIFEST_INFO,
BLUEPRINT_GET_ALL_DATA_REQUEST,
CANCEL_MAP_QUEUE,
HANDLE_FUNNESS,
FAKE_PRG_CSR_MESSAGE,
REQUEST_FREE_TRIAL_REFRESH,
GM_SET_FREE_TRIAL_STATUS,
UI_HELP_TOP_5 = 91
};
}
template <>
struct magic_enum::customize::enum_range<MessageType::World> {
static constexpr int min = 0;
static constexpr int max = 91;
};

View File

@ -8,7 +8,7 @@
#include <set> #include <set>
#include "BitStream.h" #include "BitStream.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eClientMessageType.h" #include "MessageType/Client.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#pragma warning (disable:4251) //Disables SQL warnings #pragma warning (disable:4251) //Disables SQL warnings
@ -33,7 +33,7 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
#define CBITSTREAM RakNet::BitStream bitStream; #define CBITSTREAM RakNet::BitStream bitStream;
#define CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false); #define CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false);
#define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits()); #define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits());
#define CMSGHEADER BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); #define CMSGHEADER BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
#define SEND_PACKET Game::server->Send(bitStream, sysAddr, false); #define SEND_PACKET Game::server->Send(bitStream, sysAddr, false);
#define SEND_PACKET_BROADCAST Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true); #define SEND_PACKET_BROADCAST Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);

View File

@ -1,15 +0,0 @@
#ifndef __EAUTHMESSAGETYPE__H__
#define __EAUTHMESSAGETYPE__H__
#include <cstdint>
enum class eAuthMessageType : uint32_t {
LOGIN_REQUEST = 0,
LOGOUT_REQUEST,
CREATE_NEW_ACCOUNT_REQUEST,
LEGOINTERFACE_AUTH_RESPONSE,
SESSIONKEY_RECEIVED_CONFIRM,
RUNTIME_CONFIG
};
#endif //!__EAUTHMESSAGETYPE__H__

View File

@ -15,7 +15,8 @@ enum class eCharacterVersion : uint32_t {
// Fixes vault size value // Fixes vault size value
VAULT_SIZE, VAULT_SIZE,
// Fixes speed base value in level component // Fixes speed base value in level component
UP_TO_DATE, // will become SPEED_BASE SPEED_BASE,
UP_TO_DATE, // will become NJ_JAYMISSIONS
}; };
#endif //!__ECHARACTERVERSION__H__ #endif //!__ECHARACTERVERSION__H__

View File

@ -1,80 +0,0 @@
#ifndef __ECHATMESSAGETYPE__H__
#define __ECHATMESSAGETYPE__H__
#include <cstdint>
//! The Internal Chat Packet Identifiers
enum class eChatMessageType :uint32_t {
LOGIN_SESSION_NOTIFY = 0,
GENERAL_CHAT_MESSAGE,
PRIVATE_CHAT_MESSAGE,
USER_CHANNEL_CHAT_MESSAGE,
WORLD_DISCONNECT_REQUEST,
WORLD_PROXIMITY_RESPONSE,
WORLD_PARCEL_RESPONSE,
ADD_FRIEND_REQUEST,
ADD_FRIEND_RESPONSE,
REMOVE_FRIEND,
GET_FRIENDS_LIST,
ADD_IGNORE,
REMOVE_IGNORE,
GET_IGNORE_LIST,
TEAM_MISSED_INVITE_CHECK,
TEAM_INVITE,
TEAM_INVITE_RESPONSE,
TEAM_KICK,
TEAM_LEAVE,
TEAM_SET_LOOT,
TEAM_SET_LEADER,
TEAM_GET_STATUS,
GUILD_CREATE,
GUILD_INVITE,
GUILD_INVITE_RESPONSE,
GUILD_LEAVE,
GUILD_KICK,
GUILD_GET_STATUS,
GUILD_GET_ALL,
SHOW_ALL,
BLUEPRINT_MODERATED,
BLUEPRINT_MODEL_READY,
PROPERTY_READY_FOR_APPROVAL,
PROPERTY_MODERATION_CHANGED,
PROPERTY_BUILDMODE_CHANGED,
PROPERTY_BUILDMODE_CHANGED_REPORT,
MAIL,
WORLD_INSTANCE_LOCATION_REQUEST,
REPUTATION_UPDATE,
SEND_CANNED_TEXT,
GMLEVEL_UPDATE,
CHARACTER_NAME_CHANGE_REQUEST,
CSR_REQUEST,
CSR_REPLY,
GM_KICK,
GM_ANNOUNCE,
GM_MUTE,
ACTIVITY_UPDATE,
WORLD_ROUTE_PACKET,
GET_ZONE_POPULATIONS,
REQUEST_MINIMUM_CHAT_MODE,
REQUEST_MINIMUM_CHAT_MODE_PRIVATE,
MATCH_REQUEST,
UGCMANIFEST_REPORT_MISSING_FILE,
UGCMANIFEST_REPORT_DONE_FILE,
UGCMANIFEST_REPORT_DONE_BLUEPRINT,
UGCC_REQUEST,
WHO,
WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE,
ACHIEVEMENT_NOTIFY,
GM_CLOSE_PRIVATE_CHAT_WINDOW,
UNEXPECTED_DISCONNECT,
PLAYER_READY,
GET_DONATION_TOTAL,
UPDATE_DONATION,
PRG_CSR_COMMAND,
HEARTBEAT_REQUEST_FROM_WORLD,
UPDATE_FREE_TRIAL_STATUS,
// CUSTOM DLU MESSAGE ID FOR INTERNAL USE
CREATE_TEAM,
};
#endif //!__ECHATMESSAGETYPE__H__

View File

@ -1,76 +0,0 @@
#ifndef __ECLIENTMESSAGETYPE__H__
#define __ECLIENTMESSAGETYPE__H__
#include <cstdint>
enum class eClientMessageType : uint32_t {
LOGIN_RESPONSE = 0,
LOGOUT_RESPONSE,
LOAD_STATIC_ZONE,
CREATE_OBJECT,
CREATE_CHARACTER,
CREATE_CHARACTER_EXTENDED,
CHARACTER_LIST_RESPONSE,
CHARACTER_CREATE_RESPONSE,
CHARACTER_RENAME_RESPONSE,
CHAT_CONNECT_RESPONSE,
AUTH_ACCOUNT_CREATE_RESPONSE,
DELETE_CHARACTER_RESPONSE,
GAME_MSG,
CONNECT_CHAT,
TRANSFER_TO_WORLD,
IMPENDING_RELOAD_NOTIFY,
MAKE_GM_RESPONSE,
HTTP_MONITOR_INFO_RESPONSE,
SLASH_PUSH_MAP_RESPONSE,
SLASH_PULL_MAP_RESPONSE,
SLASH_LOCK_MAP_RESPONSE,
BLUEPRINT_SAVE_RESPONSE,
BLUEPRINT_LUP_SAVE_RESPONSE,
BLUEPRINT_LOAD_RESPONSE_ITEMID,
BLUEPRINT_GET_ALL_DATA_RESPONSE,
MODEL_INSTANTIATE_RESPONSE,
DEBUG_OUTPUT,
ADD_FRIEND_REQUEST,
ADD_FRIEND_RESPONSE,
REMOVE_FRIEND_RESPONSE,
GET_FRIENDS_LIST_RESPONSE,
UPDATE_FRIEND_NOTIFY,
ADD_IGNORE_RESPONSE,
REMOVE_IGNORE_RESPONSE,
GET_IGNORE_LIST_RESPONSE,
TEAM_INVITE,
TEAM_INVITE_INITIAL_RESPONSE,
GUILD_CREATE_RESPONSE,
GUILD_GET_STATUS_RESPONSE,
GUILD_INVITE,
GUILD_INVITE_INITIAL_RESPONSE,
GUILD_INVITE_FINAL_RESPONSE,
GUILD_INVITE_CONFIRM,
GUILD_ADD_PLAYER,
GUILD_REMOVE_PLAYER,
GUILD_LOGIN_LOGOUT,
GUILD_RANK_CHANGE,
GUILD_DATA,
GUILD_STATUS,
MAIL,
DB_PROXY_RESULT,
SHOW_ALL_RESPONSE,
WHO_RESPONSE,
SEND_CANNED_TEXT,
UPDATE_CHARACTER_NAME,
SET_NETWORK_SIMULATOR,
INVALID_CHAT_MESSAGE,
MINIMUM_CHAT_MODE_RESPONSE,
MINIMUM_CHAT_MODE_RESPONSE_PRIVATE,
CHAT_MODERATION_STRING,
UGC_MANIFEST_RESPONSE,
IN_LOGIN_QUEUE,
SERVER_STATES,
GM_CLOSE_TARGET_CHAT_WINDOW,
GENERAL_TEXT_FOR_LOCALIZATION,
UPDATE_FREE_TRIAL_STATUS,
UGC_DOWNLOAD_FAILED = 120
};
#endif //!__ECLIENTMESSAGETYPE__H__

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +0,0 @@
#ifndef __EMASTERMESSAGETYPE__H__
#define __EMASTERMESSAGETYPE__H__
#include <cstdint>
enum class eMasterMessageType : uint32_t {
REQUEST_PERSISTENT_ID = 1,
REQUEST_PERSISTENT_ID_RESPONSE,
REQUEST_ZONE_TRANSFER,
REQUEST_ZONE_TRANSFER_RESPONSE,
SERVER_INFO,
REQUEST_SESSION_KEY,
SET_SESSION_KEY,
SESSION_KEY_RESPONSE,
PLAYER_ADDED,
PLAYER_REMOVED,
CREATE_PRIVATE_ZONE,
REQUEST_PRIVATE_ZONE,
WORLD_READY,
PREP_ZONE,
SHUTDOWN,
SHUTDOWN_RESPONSE,
SHUTDOWN_IMMEDIATE,
SHUTDOWN_UNIVERSE,
AFFIRM_TRANSFER_REQUEST,
AFFIRM_TRANSFER_RESPONSE,
NEW_SESSION_ALERT
};
#endif //!__EMASTERMESSAGETYPE__H__

View File

@ -0,0 +1,11 @@
#ifndef EPROPERTYSORTTYPE_H
#define EPROPERTYSORTTYPE_H
enum ePropertySortType : int32_t {
SORT_TYPE_FRIENDS = 0,
SORT_TYPE_REPUTATION = 1,
SORT_TYPE_RECENT = 3,
SORT_TYPE_FEATURED = 5
};
#endif //!EPROPERTYSORTTYPE_H

View File

@ -1,12 +0,0 @@
#ifndef __ESERVERMESSAGETYPE__H__
#define __ESERVERMESSAGETYPE__H__
#include <cstdint>
//! The Internal Server Packet Identifiers
enum class eServerMessageType : uint32_t {
VERSION_CONFIRM = 0,
DISCONNECT_NOTIFY,
GENERAL_NOTIFY
};
#endif //!__ESERVERMESSAGETYPE__H__

View File

@ -1,51 +0,0 @@
#ifndef __EWORLDMESSAGETYPE__H__
#define __EWORLDMESSAGETYPE__H__
#include <cstdint>
#include "magic_enum.hpp"
enum class eWorldMessageType : uint32_t {
VALIDATION = 1, // Session info
CHARACTER_LIST_REQUEST,
CHARACTER_CREATE_REQUEST,
LOGIN_REQUEST, // Character selected
GAME_MSG,
CHARACTER_DELETE_REQUEST,
CHARACTER_RENAME_REQUEST,
HAPPY_FLOWER_MODE_NOTIFY,
SLASH_RELOAD_MAP, // Reload map cmp
SLASH_PUSH_MAP_REQUEST, // Push map req cmd
SLASH_PUSH_MAP, // Push map cmd
SLASH_PULL_MAP, // Pull map cmd
LOCK_MAP_REQUEST,
GENERAL_CHAT_MESSAGE, // General chat message
HTTP_MONITOR_INFO_REQUEST,
SLASH_DEBUG_SCRIPTS, // Debug scripts cmd
MODELS_CLEAR,
EXHIBIT_INSERT_MODEL,
LEVEL_LOAD_COMPLETE, // Character data request
TMP_GUILD_CREATE,
ROUTE_PACKET, // Social?
POSITION_UPDATE,
MAIL,
WORD_CHECK, // AllowList word check
STRING_CHECK, // AllowList string check
GET_PLAYERS_IN_ZONE,
REQUEST_UGC_MANIFEST_INFO,
BLUEPRINT_GET_ALL_DATA_REQUEST,
CANCEL_MAP_QUEUE,
HANDLE_FUNNESS,
FAKE_PRG_CSR_MESSAGE,
REQUEST_FREE_TRIAL_REFRESH,
GM_SET_FREE_TRIAL_STATUS,
UI_HELP_TOP_5 = 91
};
template <>
struct magic_enum::customize::enum_range<eWorldMessageType> {
static constexpr int min = 0;
static constexpr int max = 91;
};
#endif //!__EWORLDMESSAGETYPE__H__

View File

@ -8,9 +8,15 @@ foreach(file ${DDATABSE_DATABSES_MYSQL_SOURCES})
set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "MySQL/${file}") set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "MySQL/${file}")
endforeach() endforeach()
add_subdirectory(TestSQL)
foreach(file ${DDATABSE_DATABSES_TEST_SQL_SOURCES})
set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "TestSQL/${file}")
endforeach()
add_library(dDatabaseGame STATIC ${DDATABASE_GAMEDATABASE_SOURCES}) add_library(dDatabaseGame STATIC ${DDATABASE_GAMEDATABASE_SOURCES})
target_include_directories(dDatabaseGame PUBLIC "." target_include_directories(dDatabaseGame PUBLIC "."
"ITables" PRIVATE "MySQL" "ITables" PRIVATE "MySQL" "TestSQL"
"${PROJECT_SOURCE_DIR}/dCommon" "${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums" "${PROJECT_SOURCE_DIR}/dCommon/dEnums"
) )

View File

@ -38,3 +38,8 @@ void Database::Destroy(std::string source) {
LOG("Trying to destroy database when it's not connected!"); LOG("Trying to destroy database when it's not connected!");
} }
} }
void Database::_setDatabase(GameDatabase* const db) {
if (database) delete database;
database = db;
}

View File

@ -9,4 +9,8 @@ namespace Database {
void Connect(); void Connect();
GameDatabase* Get(); GameDatabase* Get();
void Destroy(std::string source = ""); void Destroy(std::string source = "");
// Used for assigning a test database as the handler for database logic.
// Do not use in production code.
void _setDatabase(GameDatabase* const db);
}; };

View File

@ -4,6 +4,8 @@
#include <cstdint> #include <cstdint>
#include <optional> #include <optional>
enum ePropertySortType : int32_t;
class IProperty { class IProperty {
public: public:
struct Info { struct Info {
@ -18,11 +20,33 @@ public:
uint32_t lastUpdatedTime{}; uint32_t lastUpdatedTime{};
uint32_t claimedTime{}; uint32_t claimedTime{};
uint32_t reputation{}; uint32_t reputation{};
float performanceCost{};
};
struct PropertyLookup {
uint32_t mapId{};
std::string searchString;
ePropertySortType sortChoice{};
uint32_t playerId{};
uint32_t numResults{};
uint32_t startIndex{};
uint32_t playerSort{};
};
struct PropertyEntranceResult {
int32_t totalEntriesMatchingQuery{};
// The entries that match the query. This should only contain up to 12 entries.
std::vector<IProperty::Info> entries;
}; };
// Get the property info for the given property id. // Get the property info for the given property id.
virtual std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) = 0; virtual std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) = 0;
// Get the properties for the given property lookup params.
// This is expected to return a result set of up to 12 properties
// so as not to transfer too much data at once.
virtual std::optional<IProperty::PropertyEntranceResult> GetProperties(const PropertyLookup& params) = 0;
// Update the property moderation info for the given property id. // Update the property moderation info for the given property id.
virtual void UpdatePropertyModerationInfo(const IProperty::Info& info) = 0; virtual void UpdatePropertyModerationInfo(const IProperty::Info& info) = 0;

View File

@ -112,6 +112,7 @@ public:
std::string GetBehavior(const int32_t behaviorId) override; std::string GetBehavior(const int32_t behaviorId) override;
void RemoveBehavior(const int32_t characterId) override; void RemoveBehavior(const int32_t characterId) override;
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override; void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override;
private: private:
// Generic query functions that can be used for any query. // Generic query functions that can be used for any query.

View File

@ -1,8 +1,140 @@
#include "MySQLDatabase.h" #include "MySQLDatabase.h"
#include "ePropertySortType.h"
std::optional<IProperty::PropertyEntranceResult> MySQLDatabase::GetProperties(const IProperty::PropertyLookup& params) {
std::optional<IProperty::PropertyEntranceResult> result;
std::string query;
std::unique_ptr<sql::ResultSet> properties;
if (params.sortChoice == SORT_TYPE_FEATURED || params.sortChoice == SORT_TYPE_FRIENDS) {
query = R"QUERY(
FROM properties as p
JOIN charinfo as ci
ON ci.prop_clone_id = p.clone_id
where p.zone_id = ?
AND (
p.description LIKE ?
OR p.name LIKE ?
OR ci.name LIKE ?
)
AND p.privacy_option >= ?
AND p.owner_id IN (
SELECT fr.requested_player AS player FROM (
SELECT CASE
WHEN player_id = ? THEN friend_id
WHEN friend_id = ? THEN player_id
END AS requested_player FROM friends
) AS fr
JOIN charinfo AS ci ON ci.id = fr.requested_player
WHERE fr.requested_player IS NOT NULL AND fr.requested_player != ?
) ORDER BY ci.name ASC
)QUERY";
const auto completeQuery = "SELECT p.* " + query + " LIMIT ? OFFSET ?;";
properties = ExecuteSelect(
completeQuery,
params.mapId,
"%" + params.searchString + "%",
"%" + params.searchString + "%",
"%" + params.searchString + "%",
params.playerSort,
params.playerId,
params.playerId,
params.playerId,
params.numResults,
params.startIndex
);
const auto countQuery = "SELECT COUNT(*) as count" + query + ";";
auto count = ExecuteSelect(
countQuery,
params.mapId,
"%" + params.searchString + "%",
"%" + params.searchString + "%",
"%" + params.searchString + "%",
params.playerSort,
params.playerId,
params.playerId,
params.playerId
);
if (count->next()) {
result->totalEntriesMatchingQuery = count->getUInt("count");
}
} else {
if (params.sortChoice == SORT_TYPE_REPUTATION) {
query = R"QUERY(
FROM properties as p
JOIN charinfo as ci
ON ci.prop_clone_id = p.clone_id
where p.zone_id = ?
AND (
p.description LIKE ?
OR p.name LIKE ?
OR ci.name LIKE ?
)
AND p.privacy_option >= ?
ORDER BY p.reputation DESC, p.last_updated DESC
)QUERY";
} else {
query = R"QUERY(
FROM properties as p
JOIN charinfo as ci
ON ci.prop_clone_id = p.clone_id
where p.zone_id = ?
AND (
p.description LIKE ?
OR p.name LIKE ?
OR ci.name LIKE ?
)
AND p.privacy_option >= ?
ORDER BY p.last_updated DESC
)QUERY";
}
const auto completeQuery = "SELECT p.* " + query + " LIMIT ? OFFSET ?;";
properties = ExecuteSelect(
completeQuery,
params.mapId,
"%" + params.searchString + "%",
"%" + params.searchString + "%",
"%" + params.searchString + "%",
params.playerSort,
params.numResults,
params.startIndex
);
const auto countQuery = "SELECT COUNT(*) as count" + query + ";";
auto count = ExecuteSelect(
countQuery,
params.mapId,
"%" + params.searchString + "%",
"%" + params.searchString + "%",
"%" + params.searchString + "%",
params.playerSort
);
if (count->next()) {
result->totalEntriesMatchingQuery = count->getUInt("count");
}
}
while (properties->next()) {
auto& entry = result->entries.emplace_back();
entry.id = properties->getUInt64("id");
entry.ownerId = properties->getUInt64("owner_id");
entry.cloneId = properties->getUInt64("clone_id");
entry.name = properties->getString("name").c_str();
entry.description = properties->getString("description").c_str();
entry.privacyOption = properties->getInt("privacy_option");
entry.rejectionReason = properties->getString("rejection_reason").c_str();
entry.lastUpdatedTime = properties->getUInt("last_updated");
entry.claimedTime = properties->getUInt("time_claimed");
entry.reputation = properties->getUInt("reputation");
entry.modApproved = properties->getUInt("mod_approved");
entry.performanceCost = properties->getFloat("performance_cost");
}
return result;
}
std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) { std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) {
auto propertyEntry = ExecuteSelect( auto propertyEntry = ExecuteSelect(
"SELECT id, owner_id, clone_id, name, description, privacy_option, rejection_reason, last_updated, time_claimed, reputation, mod_approved " "SELECT id, owner_id, clone_id, name, description, privacy_option, rejection_reason, last_updated, time_claimed, reputation, mod_approved, performance_cost "
"FROM properties WHERE zone_id = ? AND clone_id = ?;", mapId, cloneId); "FROM properties WHERE zone_id = ? AND clone_id = ?;", mapId, cloneId);
if (!propertyEntry->next()) { if (!propertyEntry->next()) {
@ -21,6 +153,7 @@ std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOMAPID map
toReturn.claimedTime = propertyEntry->getUInt("time_claimed"); toReturn.claimedTime = propertyEntry->getUInt("time_claimed");
toReturn.reputation = propertyEntry->getUInt("reputation"); toReturn.reputation = propertyEntry->getUInt("reputation");
toReturn.modApproved = propertyEntry->getUInt("mod_approved"); toReturn.modApproved = propertyEntry->getUInt("mod_approved");
toReturn.performanceCost = propertyEntry->getFloat("performance_cost");
return toReturn; return toReturn;
} }

View File

@ -0,0 +1,4 @@
SET(DDATABSE_DATABSES_TEST_SQL_SOURCES
"TestSQLDatabase.cpp"
PARENT_SCOPE
)

View File

@ -0,0 +1,306 @@
#include "TestSQLDatabase.h"
void TestSQLDatabase::Connect() {
}
void TestSQLDatabase::Destroy(std::string source) {
}
sql::PreparedStatement* TestSQLDatabase::CreatePreppedStmt(const std::string& query) {
return nullptr;
}
void TestSQLDatabase::Commit() {
}
bool TestSQLDatabase::GetAutoCommit() {
return {};
}
void TestSQLDatabase::SetAutoCommit(bool value) {
}
void TestSQLDatabase::ExecuteCustomQuery(const std::string_view query) {
}
std::optional<IServers::MasterInfo> TestSQLDatabase::GetMasterInfo() {
return {};
}
std::vector<std::string> TestSQLDatabase::GetApprovedCharacterNames() {
return {};
}
std::vector<FriendData> TestSQLDatabase::GetFriendsList(uint32_t charID) {
return {};
}
std::optional<IFriends::BestFriendStatus> TestSQLDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
return {};
}
void TestSQLDatabase::SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) {
}
void TestSQLDatabase::AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) {
}
void TestSQLDatabase::RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) {
}
void TestSQLDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) {
}
void TestSQLDatabase::DeleteUgcModelData(const LWOOBJID& modelId) {
}
void TestSQLDatabase::UpdateUgcModelData(const LWOOBJID& modelId, std::istringstream& lxfml) {
}
std::vector<IUgc::Model> TestSQLDatabase::GetAllUgcModels() {
return {};
}
void TestSQLDatabase::CreateMigrationHistoryTable() {
}
bool TestSQLDatabase::IsMigrationRun(const std::string_view str) {
return {};
}
void TestSQLDatabase::InsertMigration(const std::string_view str) {
}
std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const uint32_t charId) {
return {};
}
std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const std::string_view charId) {
return {};
}
std::string TestSQLDatabase::GetCharacterXml(const uint32_t accountId) {
return {};
}
void TestSQLDatabase::UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) {
}
std::optional<IAccounts::Info> TestSQLDatabase::GetAccountInfo(const std::string_view username) {
return {};
}
void TestSQLDatabase::InsertNewCharacter(const ICharInfo::Info info) {
}
void TestSQLDatabase::InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) {
}
std::vector<uint32_t> TestSQLDatabase::GetAccountCharacterIds(uint32_t accountId) {
return {};
}
void TestSQLDatabase::DeleteCharacter(const uint32_t characterId) {
}
void TestSQLDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) {
}
void TestSQLDatabase::SetPendingCharacterName(const uint32_t characterId, const std::string_view name) {
}
void TestSQLDatabase::UpdateLastLoggedInCharacter(const uint32_t characterId) {
}
void TestSQLDatabase::SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) {
}
std::optional<IPetNames::Info> TestSQLDatabase::GetPetNameInfo(const LWOOBJID& petId) {
return {};
}
std::optional<IProperty::Info> TestSQLDatabase::GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) {
return {};
}
void TestSQLDatabase::UpdatePropertyModerationInfo(const IProperty::Info& info) {
}
void TestSQLDatabase::UpdatePropertyDetails(const IProperty::Info& info) {
}
void TestSQLDatabase::InsertNewProperty(const IProperty::Info& info, const uint32_t templateId, const LWOZONEID& zoneId) {
}
std::vector<IPropertyContents::Model> TestSQLDatabase::GetPropertyModels(const LWOOBJID& propertyId) {
return {};
}
void TestSQLDatabase::RemoveUnreferencedUgcModels() {
}
void TestSQLDatabase::InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) {
}
void TestSQLDatabase::UpdateModel(const LWOOBJID& propertyId, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) {
}
void TestSQLDatabase::RemoveModel(const LWOOBJID& modelId) {
}
void TestSQLDatabase::UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) {
}
void TestSQLDatabase::InsertNewBugReport(const IBugReports::Info& info) {
}
void TestSQLDatabase::InsertCheatDetection(const IPlayerCheatDetections::Info& info) {
}
void TestSQLDatabase::InsertNewMail(const IMail::MailInfo& mail) {
}
void TestSQLDatabase::InsertNewUgcModel(std::istringstream& sd0Data, const uint32_t blueprintId, const uint32_t accountId, const uint32_t characterId) {
}
std::vector<IMail::MailInfo> TestSQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
return {};
}
std::optional<IMail::MailInfo> TestSQLDatabase::GetMail(const uint64_t mailId) {
return {};
}
uint32_t TestSQLDatabase::GetUnreadMailCount(const uint32_t characterId) {
return {};
}
void TestSQLDatabase::MarkMailRead(const uint64_t mailId) {
}
void TestSQLDatabase::DeleteMail(const uint64_t mailId) {
}
void TestSQLDatabase::ClaimMailItem(const uint64_t mailId) {
}
void TestSQLDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) {
}
void TestSQLDatabase::UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) {
}
void TestSQLDatabase::UpdateAccountBan(const uint32_t accountId, const bool banned) {
}
void TestSQLDatabase::UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) {
}
void TestSQLDatabase::InsertNewAccount(const std::string_view username, const std::string_view bcryptpassword) {
}
void TestSQLDatabase::SetMasterIp(const std::string_view ip, const uint32_t port) {
}
std::optional<uint32_t> TestSQLDatabase::GetCurrentPersistentId() {
return {};
}
void TestSQLDatabase::InsertDefaultPersistentId() {
}
void TestSQLDatabase::UpdatePersistentId(const uint32_t id) {
}
std::optional<uint32_t> TestSQLDatabase::GetDonationTotal(const uint32_t activityId) {
return {};
}
std::optional<bool> TestSQLDatabase::IsPlaykeyActive(const int32_t playkeyId) {
return {};
}
std::vector<IUgc::Model> TestSQLDatabase::GetUgcModels(const LWOOBJID& propertyId) {
return {};
}
void TestSQLDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
}
void TestSQLDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
}
std::vector<IIgnoreList::Info> TestSQLDatabase::GetIgnoreList(const uint32_t playerId) {
return {};
}
void TestSQLDatabase::InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) {
}
std::vector<uint32_t> TestSQLDatabase::GetRewardCodesByAccountID(const uint32_t account_id) {
return {};
}
void TestSQLDatabase::AddBehavior(const IBehaviors::Info& info) {
}
std::string TestSQLDatabase::GetBehavior(const int32_t behaviorId) {
return {};
}
void TestSQLDatabase::RemoveBehavior(const int32_t behaviorId) {
}
void TestSQLDatabase::UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) {
}

View File

@ -0,0 +1,96 @@
#ifndef TESTSQLDATABASE_H
#define TESTSQLDATABASE_H
#include "GameDatabase.h"
class TestSQLDatabase : public GameDatabase {
void Connect() override;
void Destroy(std::string source = "") override;
sql::PreparedStatement* CreatePreppedStmt(const std::string& query) override;
void Commit() override;
bool GetAutoCommit() override;
void SetAutoCommit(bool value) override;
void ExecuteCustomQuery(const std::string_view query) override;
// Overloaded queries
std::optional<IServers::MasterInfo> GetMasterInfo() override;
std::vector<std::string> GetApprovedCharacterNames() override;
std::vector<FriendData> GetFriendsList(uint32_t charID) override;
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override;
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override;
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override;
void DeleteUgcModelData(const LWOOBJID& modelId) override;
void UpdateUgcModelData(const LWOOBJID& modelId, std::istringstream& lxfml) override;
std::vector<IUgc::Model> GetAllUgcModels() override;
void CreateMigrationHistoryTable() override;
bool IsMigrationRun(const std::string_view str) override;
void InsertMigration(const std::string_view str) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
std::string GetCharacterXml(const uint32_t accountId) override;
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override;
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
void InsertNewCharacter(const ICharInfo::Info info) override;
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override;
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override;
void DeleteCharacter(const uint32_t characterId) override;
void SetCharacterName(const uint32_t characterId, const std::string_view name) override;
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override;
void UpdateLastLoggedInCharacter(const uint32_t characterId) override;
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
void UpdatePropertyModerationInfo(const IProperty::Info& info) override;
void UpdatePropertyDetails(const IProperty::Info& info) override;
void InsertNewProperty(const IProperty::Info& info, const uint32_t templateId, const LWOZONEID& zoneId) override;
std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) override;
void RemoveUnreferencedUgcModels() override;
void InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) override;
void UpdateModel(const LWOOBJID& propertyId, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) override;
void RemoveModel(const LWOOBJID& modelId) override;
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
void InsertNewBugReport(const IBugReports::Info& info) override;
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
void InsertNewMail(const IMail::MailInfo& mail) override;
void InsertNewUgcModel(
std::istringstream& sd0Data,
const uint32_t blueprintId,
const uint32_t accountId,
const uint32_t characterId) override;
std::vector<IMail::MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
std::optional<IMail::MailInfo> GetMail(const uint64_t mailId) override;
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
void MarkMailRead(const uint64_t mailId) override;
void DeleteMail(const uint64_t mailId) override;
void ClaimMailItem(const uint64_t mailId) override;
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override;
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
void InsertNewAccount(const std::string_view username, const std::string_view bcryptpassword) override;
void SetMasterIp(const std::string_view ip, const uint32_t port) override;
std::optional<uint32_t> GetCurrentPersistentId() override;
void InsertDefaultPersistentId() override;
void UpdatePersistentId(const uint32_t id) override;
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override;
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
void AddBehavior(const IBehaviors::Info& info) override;
std::string GetBehavior(const int32_t behaviorId) override;
void RemoveBehavior(const int32_t behaviorId) override;
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override { return {}; };
};
#endif //!TESTSQLDATABASE_H

View File

@ -76,7 +76,7 @@ void Character::DoQuickXMLDataParse() {
if (m_Doc.Parse(m_XMLData.c_str(), m_XMLData.size()) == 0) { if (m_Doc.Parse(m_XMLData.c_str(), m_XMLData.size()) == 0) {
LOG("Loaded xmlData for character %s (%i)!", m_Name.c_str(), m_ID); LOG("Loaded xmlData for character %s (%i)!", m_Name.c_str(), m_ID);
} else { } else {
LOG("Failed to load xmlData!"); LOG("Failed to load xmlData (%i) (%s) (%s)!", m_Doc.ErrorID(), m_Doc.ErrorIDToName(m_Doc.ErrorID()), m_Doc.ErrorStr());
//Server::rakServer->CloseConnection(m_ParentUser->GetSystemAddress(), true); //Server::rakServer->CloseConnection(m_ParentUser->GetSystemAddress(), true);
return; return;
} }

View File

@ -38,6 +38,7 @@ public:
const std::string& GetXMLData() const { return m_XMLData; } const std::string& GetXMLData() const { return m_XMLData; }
const tinyxml2::XMLDocument& GetXMLDoc() const { return m_Doc; } const tinyxml2::XMLDocument& GetXMLDoc() const { return m_Doc; }
void _setXmlDoc(tinyxml2::XMLDocument& doc) { doc.DeepCopy(&m_Doc); }
/** /**
* Out of abundance of safety and clarity of what this saves, this is its own function. * Out of abundance of safety and clarity of what this saves, this is its own function.
@ -459,6 +460,10 @@ public:
User* GetParentUser() const { return m_ParentUser; } User* GetParentUser() const { return m_ParentUser; }
void _doQuickXMLDataParse() { DoQuickXMLDataParse(); }
void _setXmlData(const std::string& xmlData) { m_XMLData = xmlData; }
private: private:
void UpdateInfoFromDatabase(); void UpdateInfoFromDatabase();
/** /**

View File

@ -24,7 +24,7 @@
#include "eTriggerEventType.h" #include "eTriggerEventType.h"
#include "eObjectBits.h" #include "eObjectBits.h"
#include "PositionUpdate.h" #include "PositionUpdate.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
#include "PlayerManager.h" #include "PlayerManager.h"
//Component includes: //Component includes:
@ -96,6 +96,8 @@
#include "CDSkillBehaviorTable.h" #include "CDSkillBehaviorTable.h"
#include "CDZoneTableTable.h" #include "CDZoneTableTable.h"
Observable<Entity*, const PositionUpdate&> Entity::OnPlayerPositionUpdate;
Entity::Entity(const LWOOBJID& objectID, EntityInfo info, User* parentUser, Entity* parentEntity) { Entity::Entity(const LWOOBJID& objectID, EntityInfo info, User* parentUser, Entity* parentEntity) {
m_ObjectID = objectID; m_ObjectID = objectID;
m_TemplateID = info.lot; m_TemplateID = info.lot;
@ -881,7 +883,7 @@ void Entity::SetGMLevel(eGameMasterLevel value) {
// Update the chat server of our GM Level // Update the chat server of our GM Level
{ {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GMLEVEL_UPDATE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GMLEVEL_UPDATE);
bitStream.Write(m_ObjectID); bitStream.Write(m_ObjectID);
bitStream.Write(m_GMLevel); bitStream.Write(m_GMLevel);
@ -1349,11 +1351,6 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) {
callback(other); callback(other);
} }
SwitchComponent* switchComp = GetComponent<SwitchComponent>();
if (switchComp) {
switchComp->EntityEnter(other);
}
TriggerEvent(eTriggerEventType::ENTER, other); TriggerEvent(eTriggerEventType::ENTER, other);
// POI system // POI system
@ -2133,6 +2130,8 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) {
Game::entityManager->QueueGhostUpdate(GetObjectID()); Game::entityManager->QueueGhostUpdate(GetObjectID());
if (updateChar) Game::entityManager->SerializeEntity(this); if (updateChar) Game::entityManager->SerializeEntity(this);
OnPlayerPositionUpdate.Notify(this, update);
} }
const SystemAddress& Entity::GetSystemAddress() const { const SystemAddress& Entity::GetSystemAddress() const {

View File

@ -11,6 +11,7 @@
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include "LDFFormat.h" #include "LDFFormat.h"
#include "eKillType.h" #include "eKillType.h"
#include "Observable.h"
namespace Loot { namespace Loot {
class Info; class Info;
@ -299,6 +300,11 @@ public:
// Scale will only be communicated to the client when the construction packet is sent // Scale will only be communicated to the client when the construction packet is sent
void SetScale(const float scale) { m_Scale = scale; }; void SetScale(const float scale) { m_Scale = scale; };
/**
* @brief The observable for player entity position updates.
*/
static Observable<Entity*, const PositionUpdate&> OnPlayerPositionUpdate;
protected: protected:
LWOOBJID m_ObjectID; LWOOBJID m_ObjectID;

View File

@ -25,7 +25,7 @@ public:
User& operator=(const User& other); User& operator=(const User& other);
bool operator==(const User& other) const; bool operator==(const User& other) const;
uint32_t GetAccountID() { return m_AccountID; } uint32_t GetAccountID() const noexcept { return m_AccountID; }
std::string& GetUsername() { return m_Username; } std::string& GetUsername() { return m_Username; }
std::string& GetSessionKey() { return m_SessionKey; } std::string& GetSessionKey() { return m_SessionKey; }
SystemAddress& GetSystemAddress() { return m_SystemAddress; } SystemAddress& GetSystemAddress() { return m_SystemAddress; }

View File

@ -26,7 +26,7 @@
#include "eCharacterCreationResponse.h" #include "eCharacterCreationResponse.h"
#include "eRenameResponse.h" #include "eRenameResponse.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#include "CheatDetection.h" #include "CheatDetection.h"
@ -216,7 +216,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) {
} }
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CHARACTER_LIST_RESPONSE);
std::vector<Character*> characters = u->GetCharacters(); std::vector<Character*> characters = u->GetCharacters();
bitStream.Write<uint8_t>(characters.size()); bitStream.Write<uint8_t>(characters.size());
@ -422,7 +422,7 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
Database::Get()->DeleteCharacter(charID); Database::Get()->DeleteCharacter(charID);
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::UNEXPECTED_DISCONNECT); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
bitStream.Write(objectID); bitStream.Write(objectID);
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);

View File

@ -212,7 +212,7 @@ void BehaviorContext::UpdatePlayerSyncs(float deltaTime) {
echo.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed()); echo.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed());
RakNet::BitStream message; RakNet::BitStream message;
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
message.Write(this->originator); message.Write(this->originator);
echo.Serialize(message); echo.Serialize(message);
@ -285,7 +285,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
// Write message // Write message
RakNet::BitStream message; RakNet::BitStream message;
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
message.Write(this->originator); message.Write(this->originator);
echo.Serialize(message); echo.Serialize(message);

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "Behavior.h" #include "Behavior.h"
#include "eAninmationFlags.h" #include "eAnimationFlags.h"
class ChangeIdleFlagsBehavior final : public Behavior { class ChangeIdleFlagsBehavior final : public Behavior {
public: public:

View File

@ -21,7 +21,7 @@
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eMatchUpdate.h" #include "eMatchUpdate.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
#include "CDCurrencyTableTable.h" #include "CDCurrencyTableTable.h"
#include "CDActivityRewardsTable.h" #include "CDActivityRewardsTable.h"
@ -501,7 +501,7 @@ void ActivityInstance::StartZone() {
// only make a team if we have more than one participant // only make a team if we have more than one participant
if (participants.size() > 1) { if (participants.size() > 1) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::CREATE_TEAM); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::CREATE_TEAM);
bitStream.Write(leader->GetObjectID()); bitStream.Write(leader->GetObjectID());
bitStream.Write(m_Participants.size()); bitStream.Write(m_Participants.size());

View File

@ -25,6 +25,8 @@ struct ZoneStatistics {
uint64_t m_CoinsCollected; uint64_t m_CoinsCollected;
uint64_t m_EnemiesSmashed; uint64_t m_EnemiesSmashed;
uint64_t m_QuickBuildsCompleted; uint64_t m_QuickBuildsCompleted;
bool operator==(const ZoneStatistics& rhs) const = default;
}; };
/** /**
@ -279,9 +281,9 @@ public:
*/ */
void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const; void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const;
void SetCurrentInteracting(LWOOBJID objectID) {m_CurrentInteracting = objectID;}; void SetCurrentInteracting(LWOOBJID objectID) { m_CurrentInteracting = objectID; };
LWOOBJID GetCurrentInteracting() {return m_CurrentInteracting;}; LWOOBJID GetCurrentInteracting() { return m_CurrentInteracting; };
/** /**
* Sends a player to another zone with an optional clone ID * Sends a player to another zone with an optional clone ID
@ -307,6 +309,14 @@ public:
void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; }; void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; };
const std::array<uint64_t, 4>& GetClaimCodes() const { return m_ClaimCodes; };
const std::map<LWOMAPID, ZoneStatistics>& GetZoneStatistics() const { return m_ZoneStatistics; };
const std::u16string& GetLastRocketConfig() const { return m_LastRocketConfig; };
uint64_t GetTotalTimePlayed() const { return m_TotalTimePlayed; };
/** /**
* Character info regarding this character, including clothing styles, etc. * Character info regarding this character, including clothing styles, etc.
*/ */

View File

@ -38,6 +38,9 @@
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
Implementation<bool, const Entity*> DestroyableComponent::IsEnemyImplentation;
Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation;
DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
m_iArmor = 0; m_iArmor = 0;
m_fMaxArmor = 0.0f; m_fMaxArmor = 0.0f;
@ -418,6 +421,7 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore
} }
bool DestroyableComponent::IsEnemy(const Entity* other) const { bool DestroyableComponent::IsEnemy(const Entity* other) const {
if (IsEnemyImplentation.ExecuteWithDefault(other, false)) return true;
if (m_Parent->IsPlayer() && other->IsPlayer()) { if (m_Parent->IsPlayer() && other->IsPlayer()) {
auto* thisCharacterComponent = m_Parent->GetComponent<CharacterComponent>(); auto* thisCharacterComponent = m_Parent->GetComponent<CharacterComponent>();
if (!thisCharacterComponent) return false; if (!thisCharacterComponent) return false;
@ -440,6 +444,7 @@ bool DestroyableComponent::IsEnemy(const Entity* other) const {
} }
bool DestroyableComponent::IsFriend(const Entity* other) const { bool DestroyableComponent::IsFriend(const Entity* other) const {
if (IsFriendImplentation.ExecuteWithDefault(other, false)) return true;
const auto* otherDestroyableComponent = other->GetComponent<DestroyableComponent>(); const auto* otherDestroyableComponent = other->GetComponent<DestroyableComponent>();
if (otherDestroyableComponent != nullptr) { if (otherDestroyableComponent != nullptr) {
for (const auto enemyFaction : m_EnemyFactionIDs) { for (const auto enemyFaction : m_EnemyFactionIDs) {

View File

@ -7,6 +7,7 @@
#include "Entity.h" #include "Entity.h"
#include "Component.h" #include "Component.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "Implementation.h"
namespace CppScripts { namespace CppScripts {
class Script; class Script;
@ -463,6 +464,9 @@ public:
// handle hardcode mode drops // handle hardcode mode drops
void DoHardcoreModeDrops(const LWOOBJID source); void DoHardcoreModeDrops(const LWOOBJID source);
static Implementation<bool, const Entity*> IsEnemyImplentation;
static Implementation<bool, const Entity*> IsFriendImplentation;
private: private:
/** /**
* Whether or not the health should be serialized * Whether or not the health should be serialized

View File

@ -7,6 +7,7 @@
#include "BehaviorStates.h" #include "BehaviorStates.h"
#include "ControlBehaviorMsgs.h" #include "ControlBehaviorMsgs.h"
#include "tinyxml2.h" #include "tinyxml2.h"
#include "SimplePhysicsComponent.h"
#include "Database.h" #include "Database.h"
@ -95,12 +96,24 @@ void ModelComponent::AddBehavior(AddMessage& msg) {
for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == msg.GetBehaviorId()) return; for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == msg.GetBehaviorId()) return;
m_Behaviors.insert(m_Behaviors.begin() + msg.GetBehaviorIndex(), PropertyBehavior()); m_Behaviors.insert(m_Behaviors.begin() + msg.GetBehaviorIndex(), PropertyBehavior());
m_Behaviors.at(msg.GetBehaviorIndex()).HandleMsg(msg); m_Behaviors.at(msg.GetBehaviorIndex()).HandleMsg(msg);
auto* const simplePhysComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
if (simplePhysComponent) {
simplePhysComponent->SetPhysicsMotionState(1);
Game::entityManager->SerializeEntity(m_Parent);
}
} }
void ModelComponent::MoveToInventory(MoveToInventoryMessage& msg) { void ModelComponent::MoveToInventory(MoveToInventoryMessage& msg) {
if (msg.GetBehaviorIndex() >= m_Behaviors.size() || m_Behaviors.at(msg.GetBehaviorIndex()).GetBehaviorId() != msg.GetBehaviorId()) return; if (msg.GetBehaviorIndex() >= m_Behaviors.size() || m_Behaviors.at(msg.GetBehaviorIndex()).GetBehaviorId() != msg.GetBehaviorId()) return;
m_Behaviors.erase(m_Behaviors.begin() + msg.GetBehaviorIndex()); m_Behaviors.erase(m_Behaviors.begin() + msg.GetBehaviorIndex());
// TODO move to the inventory // TODO move to the inventory
if (m_Behaviors.empty()) {
auto* const simplePhysComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
if (simplePhysComponent) {
simplePhysComponent->SetPhysicsMotionState(4);
Game::entityManager->SerializeEntity(m_Parent);
}
}
} }
std::array<std::pair<int32_t, std::string>, 5> ModelComponent::GetBehaviorsForSave() const { std::array<std::pair<int32_t, std::string>, 5> ModelComponent::GetBehaviorsForSave() const {

View File

@ -66,8 +66,8 @@ public:
template<typename Msg> template<typename Msg>
void HandleControlBehaviorsMsg(const AMFArrayValue& args) { void HandleControlBehaviorsMsg(const AMFArrayValue& args) {
static_assert(std::is_base_of_v<BehaviorMessageBase, Msg>, "Msg must be a BehaviorMessageBase"); static_assert(std::is_base_of_v<BehaviorMessageBase, Msg>, "Msg must be a BehaviorMessageBase");
Msg msg(args); Msg msg{ args };
for (auto& behavior : m_Behaviors) { for (auto&& behavior : m_Behaviors) {
if (behavior.GetBehaviorId() == msg.GetBehaviorId()) { if (behavior.GetBehaviorId() == msg.GetBehaviorId()) {
behavior.HandleMsg(msg); behavior.HandleMsg(msg);
return; return;

View File

@ -88,7 +88,7 @@ PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Compone
m_Ability = ePetAbilityType::Invalid; m_Ability = ePetAbilityType::Invalid;
m_StartPosition = NiPoint3Constant::ZERO; m_StartPosition = NiPoint3Constant::ZERO;
m_MovementAI = nullptr; m_MovementAI = nullptr;
m_TresureTime = 0; m_TreasureTime = 0;
std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parentEntity->GetVar<std::u16string>(u"CheckPrecondition")); std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parentEntity->GetVar<std::u16string>(u"CheckPrecondition"));
@ -319,27 +319,27 @@ void PetComponent::Update(float deltaTime) {
return; return;
} }
if (m_TresureTime > 0) { if (m_TreasureTime > 0) {
auto* tresure = Game::entityManager->GetEntity(m_Interaction); auto* treasure = Game::entityManager->GetEntity(m_Interaction);
if (tresure == nullptr) { if (treasure == nullptr) {
m_TresureTime = 0; m_TreasureTime = 0;
return; return;
} }
m_TresureTime -= deltaTime; m_TreasureTime -= deltaTime;
m_MovementAI->Stop(); m_MovementAI->Stop();
if (m_TresureTime <= 0) { if (m_TreasureTime <= 0) {
m_Parent->SetOwnerOverride(m_Owner); m_Parent->SetOwnerOverride(m_Owner);
tresure->Smash(m_Parent->GetObjectID()); treasure->Smash(m_Parent->GetObjectID());
m_Interaction = LWOOBJID_EMPTY; m_Interaction = LWOOBJID_EMPTY;
m_TresureTime = 0; m_TreasureTime = 0;
} }
return; return;
@ -381,7 +381,7 @@ void PetComponent::Update(float deltaTime) {
float distance = Vector3::DistanceSquared(position, switchPosition); float distance = Vector3::DistanceSquared(position, switchPosition);
if (distance < 3 * 3) { if (distance < 3 * 3) {
m_Interaction = closestSwitch->GetParentEntity()->GetObjectID(); m_Interaction = closestSwitch->GetParentEntity()->GetObjectID();
closestSwitch->EntityEnter(m_Parent); closestSwitch->OnUse(m_Parent);
} else if (distance < 20 * 20) { } else if (distance < 20 * 20) {
haltDistance = 1; haltDistance = 1;
@ -396,30 +396,30 @@ void PetComponent::Update(float deltaTime) {
// Determine if the "Lost Tags" mission has been completed and digging has been unlocked // Determine if the "Lost Tags" mission has been completed and digging has been unlocked
const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE; const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE;
Entity* closestTresure = PetDigServer::GetClosestTresure(position); Entity* closestTreasure = PetDigServer::GetClosestTreasure(position);
if (closestTresure != nullptr && digUnlocked) { if (closestTreasure != nullptr && digUnlocked) {
// Skeleton Dragon Pat special case for bone digging // Skeleton Dragon Pat special case for bone digging
if (closestTresure->GetLOT() == 12192 && m_Parent->GetLOT() != 13067) { if (closestTreasure->GetLOT() == 12192 && m_Parent->GetLOT() != 13067) {
goto skipTresure; goto skipTreasure;
} }
NiPoint3 tresurePosition = closestTresure->GetPosition(); NiPoint3 treasurePosition = closestTreasure->GetPosition();
float distance = Vector3::DistanceSquared(position, tresurePosition); float distance = Vector3::DistanceSquared(position, treasurePosition);
if (distance < 5 * 5) { if (distance < 5 * 5) {
m_Interaction = closestTresure->GetObjectID(); m_Interaction = closestTreasure->GetObjectID();
Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, 202, true); Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, 202, true);
m_TresureTime = 2; m_TreasureTime = 2;
} else if (distance < 10 * 10) { } else if (distance < 10 * 10) {
haltDistance = 1; haltDistance = 1;
destination = tresurePosition; destination = treasurePosition;
} }
} }
skipTresure: skipTreasure:
m_MovementAI->SetHaltDistance(haltDistance); m_MovementAI->SetHaltDistance(haltDistance);

View File

@ -329,7 +329,7 @@ private:
* Timer that tracks how long a pet has been digging up some treasure, required to spawn the treasure contents * Timer that tracks how long a pet has been digging up some treasure, required to spawn the treasure contents
* on time * on time
*/ */
float m_TresureTime; float m_TreasureTime;
/** /**
* The position that this pet was spawned at * The position that this pet was spawned at

View File

@ -5,7 +5,7 @@
#include "Component.h" #include "Component.h"
#include "Item.h" #include "Item.h"
#include "PossessorComponent.h" #include "PossessorComponent.h"
#include "eAninmationFlags.h" #include "eAnimationFlags.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
/** /**

View File

@ -14,6 +14,8 @@
#include "Amf3.h" #include "Amf3.h"
#include "eObjectBits.h" #include "eObjectBits.h"
#include "eGameMasterLevel.h" #include "eGameMasterLevel.h"
#include "ePropertySortType.h"
#include "User.h"
PropertyEntranceComponent::PropertyEntranceComponent(Entity* parent, uint32_t componentID) : Component(parent) { PropertyEntranceComponent::PropertyEntranceComponent(Entity* parent, uint32_t componentID) : Component(parent) {
this->propertyQueries = {}; this->propertyQueries = {};
@ -74,261 +76,103 @@ void PropertyEntranceComponent::OnEnterProperty(Entity* entity, uint32_t index,
launcher->Launch(entity, launcher->GetTargetZone(), cloneId); launcher->Launch(entity, launcher->GetTargetZone(), cloneId);
} }
PropertySelectQueryProperty PropertyEntranceComponent::SetPropertyValues(PropertySelectQueryProperty property, LWOCLONEID cloneId, std::string ownerName, std::string propertyName, std::string propertyDescription, float reputation, bool isBFF, bool isFriend, bool isModeratorApproved, bool isAlt, bool isOwned, uint32_t privacyOption, uint32_t timeLastUpdated, float performanceCost) {
property.CloneId = cloneId;
property.OwnerName = ownerName;
property.Name = propertyName;
property.Description = propertyDescription;
property.Reputation = reputation;
property.IsBestFriend = isBFF;
property.IsFriend = isFriend;
property.IsModeratorApproved = isModeratorApproved;
property.IsAlt = isAlt;
property.IsOwned = isOwned;
property.AccessType = privacyOption;
property.DateLastPublished = timeLastUpdated;
property.PerformanceCost = performanceCost;
return property;
}
std::string PropertyEntranceComponent::BuildQuery(Entity* entity, int32_t sortMethod, Character* character, std::string customQuery, bool wantLimits) {
std::string base;
if (customQuery == "") {
base = baseQueryForProperties;
} else {
base = customQuery;
}
std::string orderBy = "";
if (sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS) {
std::string friendsList = " AND p.owner_id IN (";
auto friendsListQuery = Database::Get()->CreatePreppedStmt("SELECT * FROM (SELECT CASE WHEN player_id = ? THEN friend_id WHEN friend_id = ? THEN player_id END AS requested_player FROM friends ) AS fr WHERE requested_player IS NOT NULL ORDER BY requested_player DESC;");
friendsListQuery->setUInt(1, character->GetID());
friendsListQuery->setUInt(2, character->GetID());
auto friendsListQueryResult = friendsListQuery->executeQuery();
while (friendsListQueryResult->next()) {
auto playerIDToConvert = friendsListQueryResult->getInt(1);
friendsList = friendsList + std::to_string(playerIDToConvert) + ",";
}
// Replace trailing comma with the closing parenthesis.
if (friendsList.at(friendsList.size() - 1) == ',') friendsList.erase(friendsList.size() - 1, 1);
friendsList += ") ";
// If we have no friends then use a -1 for the query.
if (friendsList.find("()") != std::string::npos) friendsList = " AND p.owner_id IN (-1) ";
orderBy += friendsList + "ORDER BY ci.name ASC ";
delete friendsListQueryResult;
friendsListQueryResult = nullptr;
delete friendsListQuery;
friendsListQuery = nullptr;
} else if (sortMethod == SORT_TYPE_RECENT) {
orderBy = "ORDER BY p.last_updated DESC ";
} else if (sortMethod == SORT_TYPE_REPUTATION) {
orderBy = "ORDER BY p.reputation DESC, p.last_updated DESC ";
} else {
orderBy = "ORDER BY p.last_updated DESC ";
}
return base + orderBy + (wantLimits ? "LIMIT ? OFFSET ?;" : ";");
}
void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool includeNullAddress, bool includeNullDescription, bool playerOwn, bool updateUi, int32_t numResults, int32_t lReputationTime, int32_t sortMethod, int32_t startIndex, std::string filterText, const SystemAddress& sysAddr) { void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool includeNullAddress, bool includeNullDescription, bool playerOwn, bool updateUi, int32_t numResults, int32_t lReputationTime, int32_t sortMethod, int32_t startIndex, std::string filterText, const SystemAddress& sysAddr) {
const auto* const character = entity->GetCharacter();
std::vector<PropertySelectQueryProperty> entries{};
PropertySelectQueryProperty playerEntry{};
auto character = entity->GetCharacter();
if (!character) return; if (!character) return;
const auto* const user = character->GetParentUser();
if (!user) return;
auto& entries = propertyQueries[entity->GetObjectID()];
entries.clear();
// Player property goes in index 1 of the vector. This is how the client expects it. // Player property goes in index 1 of the vector. This is how the client expects it.
auto playerPropertyLookup = Database::Get()->CreatePreppedStmt("SELECT * FROM properties WHERE owner_id = ? AND zone_id = ?"); const auto playerProperty = Database::Get()->GetPropertyInfo(m_MapID, character->GetPropertyCloneID());
playerPropertyLookup->setInt(1, character->GetID());
playerPropertyLookup->setInt(2, this->m_MapID);
auto playerPropertyLookupResults = playerPropertyLookup->executeQuery();
// If the player has a property this query will have a single result. // If the player has a property this query will have a single result.
if (playerPropertyLookupResults->next()) { auto& playerEntry = entries.emplace_back();
const auto cloneId = playerPropertyLookupResults->getUInt64(4); if (playerProperty.has_value()) {
const auto propertyName = std::string(playerPropertyLookupResults->getString(5).c_str()); playerEntry.OwnerName = character->GetName();
const auto propertyDescription = std::string(playerPropertyLookupResults->getString(6).c_str()); playerEntry.IsBestFriend = true;
const auto privacyOption = playerPropertyLookupResults->getInt(9); playerEntry.IsFriend = true;
const auto modApproved = playerPropertyLookupResults->getBoolean(10); playerEntry.IsAlt = true;
const auto dateLastUpdated = playerPropertyLookupResults->getInt64(11); playerEntry.IsOwned = true;
const auto reputation = playerPropertyLookupResults->getUInt(14); playerEntry.CloneId = playerProperty->cloneId;
const auto performanceCost = playerPropertyLookupResults->getFloat(16); playerEntry.Name = playerProperty->name;
playerEntry.Description = playerProperty->description;
playerEntry = SetPropertyValues(playerEntry, cloneId, character->GetName(), propertyName, propertyDescription, reputation, true, true, modApproved, true, true, privacyOption, dateLastUpdated, performanceCost); playerEntry.AccessType = playerProperty->privacyOption;
playerEntry.IsModeratorApproved = playerProperty->modApproved;
playerEntry.DateLastPublished = playerProperty->lastUpdatedTime;
playerEntry.Reputation = playerProperty->reputation;
playerEntry.PerformanceCost = playerProperty->performanceCost;
auto& entry = playerEntry;
} else { } else {
playerEntry = SetPropertyValues(playerEntry, character->GetPropertyCloneID(), character->GetName(), "", "", 0, true, true); playerEntry.OwnerName = character->GetName();
playerEntry.IsBestFriend = true;
playerEntry.IsFriend = true;
playerEntry.IsAlt = false;
playerEntry.IsOwned = false;
playerEntry.CloneId = character->GetPropertyCloneID();
playerEntry.Name = "";
playerEntry.Description = "";
playerEntry.AccessType = 0;
playerEntry.IsModeratorApproved = false;
playerEntry.DateLastPublished = 0;
playerEntry.Reputation = 0;
playerEntry.PerformanceCost = 0.0f;
} }
delete playerPropertyLookupResults; IProperty::PropertyLookup propertyLookup;
playerPropertyLookupResults = nullptr; propertyLookup.mapId = m_MapID;
propertyLookup.searchString = filterText;
propertyLookup.sortChoice = static_cast<ePropertySortType>(sortMethod);
propertyLookup.playerSort = static_cast<uint32_t>(sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS ? PropertyPrivacyOption::Friends : PropertyPrivacyOption::Public);
propertyLookup.playerId = character->GetID();
propertyLookup.numResults = numResults;
propertyLookup.startIndex = startIndex;
delete playerPropertyLookup; const auto lookupResult = Database::Get()->GetProperties(propertyLookup);
playerPropertyLookup = nullptr;
entries.push_back(playerEntry);
const auto query = BuildQuery(entity, sortMethod, character);
auto propertyLookup = Database::Get()->CreatePreppedStmt(query);
const auto searchString = "%" + filterText + "%";
propertyLookup->setUInt(1, this->m_MapID);
propertyLookup->setString(2, searchString.c_str());
propertyLookup->setString(3, searchString.c_str());
propertyLookup->setString(4, searchString.c_str());
propertyLookup->setInt(5, sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS ? static_cast<uint32_t>(PropertyPrivacyOption::Friends) : static_cast<uint32_t>(PropertyPrivacyOption::Public));
propertyLookup->setInt(6, numResults);
propertyLookup->setInt(7, startIndex);
auto propertyEntry = propertyLookup->executeQuery();
while (propertyEntry->next()) {
const auto propertyId = propertyEntry->getUInt64(1);
const auto owner = propertyEntry->getInt(2);
const auto cloneId = propertyEntry->getUInt64(4);
const auto propertyNameFromDb = std::string(propertyEntry->getString(5).c_str());
const auto propertyDescriptionFromDb = std::string(propertyEntry->getString(6).c_str());
const auto privacyOption = propertyEntry->getInt(9);
const auto modApproved = propertyEntry->getBoolean(10);
const auto dateLastUpdated = propertyEntry->getInt(11);
const float reputation = propertyEntry->getInt(14);
const auto performanceCost = propertyEntry->getFloat(16);
PropertySelectQueryProperty entry{};
std::string ownerName = "";
bool isOwned = true;
auto nameLookup = Database::Get()->CreatePreppedStmt("SELECT name FROM charinfo WHERE prop_clone_id = ?;");
nameLookup->setUInt64(1, cloneId);
auto nameResult = nameLookup->executeQuery();
if (!nameResult->next()) {
delete nameLookup;
nameLookup = nullptr;
LOG("Failed to find property owner name for %llu!", cloneId);
for (const auto& propertyEntry : lookupResult->entries) {
const auto owner = propertyEntry.ownerId;
const auto otherCharacter = Database::Get()->GetCharacterInfo(owner);
if (!otherCharacter.has_value()) {
LOG("Failed to find property owner name for %u!", owner);
continue; continue;
} else {
isOwned = cloneId == character->GetPropertyCloneID();
ownerName = std::string(nameResult->getString(1).c_str());
} }
auto& entry = entries.emplace_back();
delete nameResult; entry.IsOwned = entry.CloneId == otherCharacter->cloneId;
nameResult = nullptr; entry.OwnerName = otherCharacter->name;
entry.CloneId = propertyEntry.cloneId;
delete nameLookup; entry.Name = propertyEntry.name;
nameLookup = nullptr; entry.Description = propertyEntry.description;
entry.AccessType = propertyEntry.privacyOption;
std::string propertyName = propertyNameFromDb; entry.IsModeratorApproved = propertyEntry.modApproved;
std::string propertyDescription = propertyDescriptionFromDb; entry.DateLastPublished = propertyEntry.lastUpdatedTime;
entry.Reputation = propertyEntry.reputation;
bool isBestFriend = false; entry.PerformanceCost = propertyEntry.performanceCost;
bool isFriend = false; entry.IsBestFriend = false;
entry.IsFriend = false;
// Convert owner char id to LWOOBJID
LWOOBJID ownerObjId = owner;
GeneralUtils::SetBit(ownerObjId, eObjectBits::CHARACTER);
GeneralUtils::SetBit(ownerObjId, eObjectBits::PERSISTENT);
// Query to get friend and best friend fields // Query to get friend and best friend fields
auto friendCheck = Database::Get()->CreatePreppedStmt("SELECT best_friend FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?)"); const auto friendCheck = Database::Get()->GetBestFriendStatus(character->GetID(), owner);
friendCheck->setUInt(1, character->GetID());
friendCheck->setUInt(2, ownerObjId);
friendCheck->setUInt(3, ownerObjId);
friendCheck->setUInt(4, character->GetID());
auto friendResult = friendCheck->executeQuery();
// If we got a result than the two players are friends. // If we got a result than the two players are friends.
if (friendResult->next()) { if (friendCheck.has_value()) {
isFriend = true; entry.IsFriend = true;
if (friendResult->getInt(1) == 3) { entry.IsBestFriend = friendCheck->bestFriendStatus == 3;
isBestFriend = true;
}
} }
delete friendCheck; if (!entry.IsModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) {
friendCheck = nullptr; entry.Name = "[AWAITING APPROVAL]";
entry.Description = "[AWAITING APPROVAL]";
delete friendResult; entry.IsModeratorApproved = true;
friendResult = nullptr;
bool isModeratorApproved = propertyEntry->getBoolean(10);
if (!isModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) {
propertyName = "[AWAITING APPROVAL]";
propertyDescription = "[AWAITING APPROVAL]";
isModeratorApproved = true;
} }
bool isAlt = false;
// Query to determine whether this property is an alt character of the entity. // Query to determine whether this property is an alt character of the entity.
auto isAltQuery = Database::Get()->CreatePreppedStmt("SELECT id FROM charinfo where account_id in (SELECT account_id from charinfo WHERE id = ?) AND id = ?;"); for (const auto charid : Database::Get()->GetAccountCharacterIds(user->GetAccountID())) {
entry.IsAlt = charid == owner;
isAltQuery->setInt(1, character->GetID()); if (entry.IsAlt) break;
isAltQuery->setInt(2, owner);
auto isAltQueryResults = isAltQuery->executeQuery();
if (isAltQueryResults->next()) {
isAlt = true;
} }
delete isAltQueryResults;
isAltQueryResults = nullptr;
delete isAltQuery;
isAltQuery = nullptr;
entry = SetPropertyValues(entry, cloneId, ownerName, propertyName, propertyDescription, reputation, isBestFriend, isFriend, isModeratorApproved, isAlt, isOwned, privacyOption, dateLastUpdated, performanceCost);
entries.push_back(entry);
} }
delete propertyEntry;
propertyEntry = nullptr;
delete propertyLookup;
propertyLookup = nullptr;
propertyQueries[entity->GetObjectID()] = entries;
// Query here is to figure out whether or not to display the button to go to the next page or not. // Query here is to figure out whether or not to display the button to go to the next page or not.
int32_t numberOfProperties = 0; GameMessages::SendPropertySelectQuery(m_Parent->GetObjectID(), startIndex, lookupResult->totalEntriesMatchingQuery - (startIndex + numResults) > 0, character->GetPropertyCloneID(), false, true, entries, sysAddr);
auto buttonQuery = BuildQuery(entity, sortMethod, character, "SELECT COUNT(*) FROM properties as p JOIN charinfo as ci ON ci.prop_clone_id = p.clone_id where p.zone_id = ? AND (p.description LIKE ? OR p.name LIKE ? OR ci.name LIKE ?) AND p.privacy_option >= ? ", false);
auto propertiesLeft = Database::Get()->CreatePreppedStmt(buttonQuery);
propertiesLeft->setUInt(1, this->m_MapID);
propertiesLeft->setString(2, searchString.c_str());
propertiesLeft->setString(3, searchString.c_str());
propertiesLeft->setString(4, searchString.c_str());
propertiesLeft->setInt(5, sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS ? 1 : 2);
auto result = propertiesLeft->executeQuery();
result->next();
numberOfProperties = result->getInt(1);
delete result;
result = nullptr;
delete propertiesLeft;
propertiesLeft = nullptr;
GameMessages::SendPropertySelectQuery(m_Parent->GetObjectID(), startIndex, numberOfProperties - (startIndex + numResults) > 0, character->GetPropertyCloneID(), false, true, entries, sysAddr);
} }

View File

@ -57,11 +57,7 @@ public:
* Returns the map ID for this property * Returns the map ID for this property
* @return the map ID for this property * @return the map ID for this property
*/ */
[[nodiscard]] LWOMAPID GetMapID() const { return m_MapID; }; [[nodiscard]] LWOMAPID GetMapID() const noexcept { return m_MapID; };
PropertySelectQueryProperty SetPropertyValues(PropertySelectQueryProperty property, LWOCLONEID cloneId = LWOCLONEID_INVALID, std::string ownerName = "", std::string propertyName = "", std::string propertyDescription = "", float reputation = 0, bool isBFF = false, bool isFriend = false, bool isModeratorApproved = false, bool isAlt = false, bool isOwned = false, uint32_t privacyOption = 0, uint32_t timeLastUpdated = 0, float performanceCost = 0.0f);
std::string BuildQuery(Entity* entity, int32_t sortMethod, Character* character, std::string customQuery = "", bool wantLimits = true);
private: private:
/** /**
@ -78,13 +74,4 @@ private:
* The base map ID for this property (Avant Grove, etc). * The base map ID for this property (Avant Grove, etc).
*/ */
LWOMAPID m_MapID; LWOMAPID m_MapID;
enum ePropertySortType : int32_t {
SORT_TYPE_FRIENDS = 0,
SORT_TYPE_REPUTATION = 1,
SORT_TYPE_RECENT = 3,
SORT_TYPE_FEATURED = 5
};
std::string baseQueryForProperties = "SELECT p.* FROM properties as p JOIN charinfo as ci ON ci.prop_clone_id = p.clone_id where p.zone_id = ? AND (p.description LIKE ? OR p.name LIKE ? OR ci.name LIKE ?) AND p.privacy_option >= ? ";
}; };

View File

@ -18,7 +18,7 @@
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#include "eObjectWorldState.h" #include "eObjectWorldState.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eMasterMessageType.h" #include "MessageType/Master.h"
RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) { RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) {
auto query = CDClientDatabase::CreatePreppedStmt( auto query = CDClientDatabase::CreatePreppedStmt(
@ -137,7 +137,7 @@ LWOCLONEID RocketLaunchpadControlComponent::GetSelectedCloneId(LWOOBJID player)
void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) { void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PREP_ZONE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::PREP_ZONE);
bitStream.Write(zoneID); bitStream.Write(zoneID);
Game::server->SendToMaster(bitStream); Game::server->SendToMaster(bitStream);
} }

View File

@ -27,6 +27,7 @@ SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, uint32_t componen
} else { } else {
SetClimbableType(eClimbableType::CLIMBABLE_TYPE_NOT); SetClimbableType(eClimbableType::CLIMBABLE_TYPE_NOT);
} }
m_PhysicsMotionState = m_Parent->GetVarAs<uint32_t>(u"motionType");
} }
SimplePhysicsComponent::~SimplePhysicsComponent() { SimplePhysicsComponent::~SimplePhysicsComponent() {
@ -47,11 +48,10 @@ void SimplePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIs
} }
// Physics motion state // Physics motion state
if (m_PhysicsMotionState != 0) { outBitStream.Write(m_DirtyPhysicsMotionState || bIsInitialUpdate);
outBitStream.Write1(); if (m_DirtyPhysicsMotionState || bIsInitialUpdate) {
outBitStream.Write<uint32_t>(m_PhysicsMotionState); outBitStream.Write<uint32_t>(m_PhysicsMotionState);
} else { m_DirtyPhysicsMotionState = false;
outBitStream.Write0();
} }
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate); PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
} }
@ -61,5 +61,6 @@ uint32_t SimplePhysicsComponent::GetPhysicsMotionState() const {
} }
void SimplePhysicsComponent::SetPhysicsMotionState(uint32_t value) { void SimplePhysicsComponent::SetPhysicsMotionState(uint32_t value) {
m_DirtyPhysicsMotionState = m_PhysicsMotionState != value;
m_PhysicsMotionState = value; m_PhysicsMotionState = value;
} }

View File

@ -102,7 +102,9 @@ private:
/** /**
* The current physics motion state * The current physics motion state
*/ */
uint32_t m_PhysicsMotionState = 0; uint32_t m_PhysicsMotionState = 5;
bool m_DirtyPhysicsMotionState = true;
/** /**
* Whether or not the entity is climbable * Whether or not the entity is climbable

View File

@ -24,7 +24,7 @@
#include "CDClientManager.h" #include "CDClientManager.h"
#include "CDSkillBehaviorTable.h" #include "CDSkillBehaviorTable.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eClientMessageType.h" #include "MessageType/Client.h"
ProjectileSyncEntry::ProjectileSyncEntry() { ProjectileSyncEntry::ProjectileSyncEntry() {
} }
@ -320,7 +320,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(
// Write message // Write message
RakNet::BitStream message; RakNet::BitStream message;
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
message.Write(this->m_Parent->GetObjectID()); message.Write(this->m_Parent->GetObjectID());
start.Serialize(message); start.Serialize(message);
@ -451,7 +451,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
RakNet::BitStream message; RakNet::BitStream message;
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
message.Write(this->m_Parent->GetObjectID()); message.Write(this->m_Parent->GetObjectID());
projectileImpact.Serialize(message); projectileImpact.Serialize(message);

View File

@ -2,6 +2,7 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "eTriggerEventType.h" #include "eTriggerEventType.h"
#include "RenderComponent.h" #include "RenderComponent.h"
#include "DestroyableComponent.h"
std::vector<SwitchComponent*> SwitchComponent::petSwitches; std::vector<SwitchComponent*> SwitchComponent::petSwitches;
@ -11,6 +12,13 @@ SwitchComponent::SwitchComponent(Entity* parent) : Component(parent) {
m_ResetTime = m_Parent->GetVarAs<int32_t>(u"switch_reset_time"); m_ResetTime = m_Parent->GetVarAs<int32_t>(u"switch_reset_time");
m_QuickBuild = m_Parent->GetComponent<QuickBuildComponent>(); m_QuickBuild = m_Parent->GetComponent<QuickBuildComponent>();
const auto factions = GeneralUtils::SplitString(m_Parent->GetVar<std::u16string>(u"respond_to_faction"), u':');
for (const auto& faction : factions) {
auto factionID = GeneralUtils::TryParse<int32_t>(GeneralUtils::UTF16ToWTF8(faction));
if (!factionID) continue;
m_FactionsToRespondTo.push_back(factionID.value());
}
} }
SwitchComponent::~SwitchComponent() { SwitchComponent::~SwitchComponent() {
@ -25,6 +33,17 @@ void SwitchComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitial
outBitStream.Write(m_Active); outBitStream.Write(m_Active);
} }
void SwitchComponent::OnUse(Entity* originator) {
const auto* const destroyableComponent = originator->GetComponent<DestroyableComponent>();
if (!destroyableComponent) return;
for (const auto faction : m_FactionsToRespondTo) {
if (destroyableComponent->HasFaction(faction)) {
EntityEnter(originator);
break;
}
}
}
void SwitchComponent::SetActive(bool active) { void SwitchComponent::SetActive(bool active) {
m_Active = active; m_Active = active;
@ -63,6 +82,7 @@ void SwitchComponent::EntityEnter(Entity* entity) {
RenderComponent::PlayAnimation(m_Parent, u"engaged"); RenderComponent::PlayAnimation(m_Parent, u"engaged");
m_PetBouncer->SetPetBouncerEnabled(true); m_PetBouncer->SetPetBouncerEnabled(true);
} else { } else {
GameMessages::SendKnockback(entity->GetObjectID(), m_Parent->GetObjectID(), m_Parent->GetObjectID(), 0.0f, NiPoint3(0.0f, 17.0f, 0.0f));
Game::entityManager->SerializeEntity(m_Parent); Game::entityManager->SerializeEntity(m_Parent);
} }

View File

@ -22,6 +22,7 @@ public:
~SwitchComponent() override; ~SwitchComponent() override;
void Update(float deltaTime) override; void Update(float deltaTime) override;
void OnUse(Entity* originator) override;
Entity* GetParentEntity() const; Entity* GetParentEntity() const;
@ -101,6 +102,8 @@ private:
* Attached pet bouncer * Attached pet bouncer
*/ */
BouncerComponent* m_PetBouncer = nullptr; BouncerComponent* m_PetBouncer = nullptr;
std::vector<int32_t> m_FactionsToRespondTo{};
}; };
#endif // SWITCHCOMPONENT_H #endif // SWITCHCOMPONENT_H

View File

@ -27,7 +27,7 @@ public:
} }
void Serialize(RakNet::BitStream& stream) { void Serialize(RakNet::BitStream& stream) {
stream.Write(eGameMessageType::DO_CLIENT_PROJECTILE_IMPACT); stream.Write(MessageType::Game::DO_CLIENT_PROJECTILE_IMPACT);
stream.Write(i64OrgID != LWOOBJID_EMPTY); stream.Write(i64OrgID != LWOOBJID_EMPTY);
if (i64OrgID != LWOOBJID_EMPTY) stream.Write(i64OrgID); if (i64OrgID != LWOOBJID_EMPTY) stream.Write(i64OrgID);

View File

@ -4,7 +4,7 @@
#include "dCommonVars.h" #include "dCommonVars.h"
#include "NiPoint3.h" #include "NiPoint3.h"
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
/* Same as start skill but with different network options. An echo down to other clients that need to play the skill. */ /* Same as start skill but with different network options. An echo down to other clients that need to play the skill. */
class EchoStartSkill { class EchoStartSkill {
@ -40,7 +40,7 @@ public:
} }
void Serialize(RakNet::BitStream& stream) { void Serialize(RakNet::BitStream& stream) {
stream.Write(eGameMessageType::ECHO_START_SKILL); stream.Write(MessageType::Game::ECHO_START_SKILL);
stream.Write(bUsedMouse); stream.Write(bUsedMouse);

View File

@ -4,7 +4,7 @@
#include <string> #include <string>
#include "BitStream.h" #include "BitStream.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
/* Message to synchronize a skill cast */ /* Message to synchronize a skill cast */
@ -29,7 +29,7 @@ public:
} }
void Serialize(RakNet::BitStream& stream) { void Serialize(RakNet::BitStream& stream) {
stream.Write(eGameMessageType::ECHO_SYNC_SKILL); stream.Write(MessageType::Game::ECHO_SYNC_SKILL);
stream.Write(bDone); stream.Write(bDone);
uint32_t sBitStreamLength = sBitStream.length(); uint32_t sBitStreamLength = sBitStream.length();

View File

@ -33,13 +33,13 @@
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
#include "ePlayerFlag.h" #include "ePlayerFlag.h"
#include "dConfig.h" #include "dConfig.h"
#include "GhostComponent.h" #include "GhostComponent.h"
#include "StringifiedEnum.h" #include "StringifiedEnum.h"
void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID) { void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const SystemAddress& sysAddr, LWOOBJID objectID, MessageType::Game messageID) {
CBITSTREAM; CBITSTREAM;
@ -53,58 +53,58 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
return; return;
} }
if (messageID != eGameMessageType::READY_FOR_UPDATES) LOG_DEBUG("Received GM with ID and name: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data()); if (messageID != MessageType::Game::READY_FOR_UPDATES) LOG_DEBUG("Received GM with ID and name: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
switch (messageID) { switch (messageID) {
case eGameMessageType::UN_USE_BBB_MODEL: { case MessageType::Game::UN_USE_BBB_MODEL: {
GameMessages::HandleUnUseModel(inStream, entity, sysAddr); GameMessages::HandleUnUseModel(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::PLAY_EMOTE: { case MessageType::Game::PLAY_EMOTE: {
GameMessages::HandlePlayEmote(inStream, entity); GameMessages::HandlePlayEmote(inStream, entity);
break; break;
} }
case eGameMessageType::MOVE_ITEM_IN_INVENTORY: { case MessageType::Game::MOVE_ITEM_IN_INVENTORY: {
GameMessages::HandleMoveItemInInventory(inStream, entity); GameMessages::HandleMoveItemInInventory(inStream, entity);
break; break;
} }
case eGameMessageType::REMOVE_ITEM_FROM_INVENTORY: { case MessageType::Game::REMOVE_ITEM_FROM_INVENTORY: {
GameMessages::HandleRemoveItemFromInventory(inStream, entity, sysAddr); GameMessages::HandleRemoveItemFromInventory(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::EQUIP_INVENTORY: case MessageType::Game::EQUIP_INVENTORY:
GameMessages::HandleEquipItem(inStream, entity); GameMessages::HandleEquipItem(inStream, entity);
break; break;
case eGameMessageType::UN_EQUIP_INVENTORY: case MessageType::Game::UN_EQUIP_INVENTORY:
GameMessages::HandleUnequipItem(inStream, entity); GameMessages::HandleUnequipItem(inStream, entity);
break; break;
case eGameMessageType::RESPOND_TO_MISSION: { case MessageType::Game::RESPOND_TO_MISSION: {
GameMessages::HandleRespondToMission(inStream, entity); GameMessages::HandleRespondToMission(inStream, entity);
break; break;
} }
case eGameMessageType::REQUEST_USE: { case MessageType::Game::REQUEST_USE: {
GameMessages::HandleRequestUse(inStream, entity, sysAddr); GameMessages::HandleRequestUse(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::SET_FLAG: { case MessageType::Game::SET_FLAG: {
GameMessages::HandleSetFlag(inStream, entity); GameMessages::HandleSetFlag(inStream, entity);
break; break;
} }
case eGameMessageType::HAS_BEEN_COLLECTED: { case MessageType::Game::HAS_BEEN_COLLECTED: {
GameMessages::HandleHasBeenCollected(inStream, entity); GameMessages::HandleHasBeenCollected(inStream, entity);
break; break;
} }
case eGameMessageType::PLAYER_LOADED: { case MessageType::Game::PLAYER_LOADED: {
GameMessages::SendRestoreToPostLoadStats(entity, sysAddr); GameMessages::SendRestoreToPostLoadStats(entity, sysAddr);
entity->SetPlayerReadyForUpdates(); entity->SetPlayerReadyForUpdates();
@ -183,82 +183,82 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
break; break;
} }
case eGameMessageType::REQUEST_LINKED_MISSION: { case MessageType::Game::REQUEST_LINKED_MISSION: {
GameMessages::HandleRequestLinkedMission(inStream, entity); GameMessages::HandleRequestLinkedMission(inStream, entity);
break; break;
} }
case eGameMessageType::MISSION_DIALOGUE_OK: { case MessageType::Game::MISSION_DIALOGUE_OK: {
GameMessages::HandleMissionDialogOK(inStream, entity); GameMessages::HandleMissionDialogOK(inStream, entity);
break; break;
} }
case eGameMessageType::MISSION_DIALOGUE_CANCELLED: { case MessageType::Game::MISSION_DIALOGUE_CANCELLED: {
// This message is pointless for our implementation, as the client just carries on after // This message is pointless for our implementation, as the client just carries on after
// rejecting a mission offer. We dont need to do anything. This is just here to remove a warning in our logs :) // rejecting a mission offer. We dont need to do anything. This is just here to remove a warning in our logs :)
break; break;
} }
case eGameMessageType::REQUEST_PLATFORM_RESYNC: { case MessageType::Game::REQUEST_PLATFORM_RESYNC: {
GameMessages::HandleRequestPlatformResync(inStream, entity, sysAddr); GameMessages::HandleRequestPlatformResync(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::FIRE_EVENT_SERVER_SIDE: { case MessageType::Game::FIRE_EVENT_SERVER_SIDE: {
GameMessages::HandleFireEventServerSide(inStream, entity, sysAddr); GameMessages::HandleFireEventServerSide(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA: { case MessageType::Game::SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA: {
GameMessages::HandleActivitySummaryLeaderboardData(inStream, entity, sysAddr); GameMessages::HandleActivitySummaryLeaderboardData(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::REQUEST_ACTIVITY_SUMMARY_LEADERBOARD_DATA: { case MessageType::Game::REQUEST_ACTIVITY_SUMMARY_LEADERBOARD_DATA: {
GameMessages::HandleRequestActivitySummaryLeaderboardData(inStream, entity, sysAddr); GameMessages::HandleRequestActivitySummaryLeaderboardData(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::ACTIVITY_STATE_CHANGE_REQUEST: { case MessageType::Game::ACTIVITY_STATE_CHANGE_REQUEST: {
GameMessages::HandleActivityStateChangeRequest(inStream, entity); GameMessages::HandleActivityStateChangeRequest(inStream, entity);
break; break;
} }
case eGameMessageType::PARSE_CHAT_MESSAGE: { case MessageType::Game::PARSE_CHAT_MESSAGE: {
GameMessages::HandleParseChatMessage(inStream, entity, sysAddr); GameMessages::HandleParseChatMessage(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::NOTIFY_SERVER_LEVEL_PROCESSING_COMPLETE: { case MessageType::Game::NOTIFY_SERVER_LEVEL_PROCESSING_COMPLETE: {
GameMessages::HandleNotifyServerLevelProcessingComplete(inStream, entity); GameMessages::HandleNotifyServerLevelProcessingComplete(inStream, entity);
break; break;
} }
case eGameMessageType::PICKUP_CURRENCY: { case MessageType::Game::PICKUP_CURRENCY: {
GameMessages::HandlePickupCurrency(inStream, entity); GameMessages::HandlePickupCurrency(inStream, entity);
break; break;
} }
case eGameMessageType::PICKUP_ITEM: { case MessageType::Game::PICKUP_ITEM: {
GameMessages::HandlePickupItem(inStream, entity); GameMessages::HandlePickupItem(inStream, entity);
break; break;
} }
case eGameMessageType::RESURRECT: { case MessageType::Game::RESURRECT: {
GameMessages::HandleResurrect(inStream, entity); GameMessages::HandleResurrect(inStream, entity);
break; break;
} }
case eGameMessageType::REQUEST_RESURRECT: { case MessageType::Game::REQUEST_RESURRECT: {
GameMessages::SendResurrect(entity); GameMessages::SendResurrect(entity);
break; break;
} }
case eGameMessageType::GET_HOT_PROPERTY_DATA: { case MessageType::Game::GET_HOT_PROPERTY_DATA: {
GameMessages::HandleGetHotPropertyData(inStream, entity, sysAddr); GameMessages::HandleGetHotPropertyData(inStream, entity, sysAddr);
break; break;
} }
case eGameMessageType::REQUEST_SERVER_PROJECTILE_IMPACT: case MessageType::Game::REQUEST_SERVER_PROJECTILE_IMPACT:
{ {
auto message = RequestServerProjectileImpact(); auto message = RequestServerProjectileImpact();
@ -275,7 +275,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
break; break;
} }
case eGameMessageType::START_SKILL: { case MessageType::Game::START_SKILL: {
StartSkill startSkill = StartSkill(); StartSkill startSkill = StartSkill();
startSkill.Deserialize(inStream); // inStream replaces &bitStream startSkill.Deserialize(inStream); // inStream replaces &bitStream
@ -311,7 +311,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
if (success) { if (success) {
//Broadcast our startSkill: //Broadcast our startSkill:
RakNet::BitStream bitStreamLocal; RakNet::BitStream bitStreamLocal;
BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
bitStreamLocal.Write(entity->GetObjectID()); bitStreamLocal.Write(entity->GetObjectID());
EchoStartSkill echoStartSkill; EchoStartSkill echoStartSkill;
@ -331,9 +331,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
} }
} break; } break;
case eGameMessageType::SYNC_SKILL: { case MessageType::Game::SYNC_SKILL: {
RakNet::BitStream bitStreamLocal; RakNet::BitStream bitStreamLocal;
BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
bitStreamLocal.Write(entity->GetObjectID()); bitStreamLocal.Write(entity->GetObjectID());
SyncSkill sync = SyncSkill(inStream); // inStream replaced &bitStream SyncSkill sync = SyncSkill(inStream); // inStream replaced &bitStream
@ -365,330 +365,330 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
Game::server->Send(bitStreamLocal, sysAddr, true); Game::server->Send(bitStreamLocal, sysAddr, true);
} break; } break;
case eGameMessageType::REQUEST_SMASH_PLAYER: case MessageType::Game::REQUEST_SMASH_PLAYER:
entity->Smash(entity->GetObjectID()); entity->Smash(entity->GetObjectID());
break; break;
case eGameMessageType::MOVE_ITEM_BETWEEN_INVENTORY_TYPES: case MessageType::Game::MOVE_ITEM_BETWEEN_INVENTORY_TYPES:
GameMessages::HandleMoveItemBetweenInventoryTypes(inStream, entity, sysAddr); GameMessages::HandleMoveItemBetweenInventoryTypes(inStream, entity, sysAddr);
break; break;
case eGameMessageType::MODULAR_BUILD_FINISH: case MessageType::Game::MODULAR_BUILD_FINISH:
GameMessages::HandleModularBuildFinish(inStream, entity, sysAddr); GameMessages::HandleModularBuildFinish(inStream, entity, sysAddr);
break; break;
case eGameMessageType::PUSH_EQUIPPED_ITEMS_STATE: case MessageType::Game::PUSH_EQUIPPED_ITEMS_STATE:
GameMessages::HandlePushEquippedItemsState(inStream, entity); GameMessages::HandlePushEquippedItemsState(inStream, entity);
break; break;
case eGameMessageType::POP_EQUIPPED_ITEMS_STATE: case MessageType::Game::POP_EQUIPPED_ITEMS_STATE:
GameMessages::HandlePopEquippedItemsState(inStream, entity); GameMessages::HandlePopEquippedItemsState(inStream, entity);
break; break;
case eGameMessageType::BUY_FROM_VENDOR: case MessageType::Game::BUY_FROM_VENDOR:
GameMessages::HandleBuyFromVendor(inStream, entity, sysAddr); GameMessages::HandleBuyFromVendor(inStream, entity, sysAddr);
break; break;
case eGameMessageType::SELL_TO_VENDOR: case MessageType::Game::SELL_TO_VENDOR:
GameMessages::HandleSellToVendor(inStream, entity, sysAddr); GameMessages::HandleSellToVendor(inStream, entity, sysAddr);
break; break;
case eGameMessageType::BUYBACK_FROM_VENDOR: case MessageType::Game::BUYBACK_FROM_VENDOR:
GameMessages::HandleBuybackFromVendor(inStream, entity, sysAddr); GameMessages::HandleBuybackFromVendor(inStream, entity, sysAddr);
break; break;
case eGameMessageType::MODULAR_BUILD_MOVE_AND_EQUIP: case MessageType::Game::MODULAR_BUILD_MOVE_AND_EQUIP:
GameMessages::HandleModularBuildMoveAndEquip(inStream, entity, sysAddr); GameMessages::HandleModularBuildMoveAndEquip(inStream, entity, sysAddr);
break; break;
case eGameMessageType::DONE_ARRANGING_WITH_ITEM: case MessageType::Game::DONE_ARRANGING_WITH_ITEM:
GameMessages::HandleDoneArrangingWithItem(inStream, entity, sysAddr); GameMessages::HandleDoneArrangingWithItem(inStream, entity, sysAddr);
break; break;
case eGameMessageType::MODULAR_BUILD_CONVERT_MODEL: case MessageType::Game::MODULAR_BUILD_CONVERT_MODEL:
GameMessages::HandleModularBuildConvertModel(inStream, entity, sysAddr); GameMessages::HandleModularBuildConvertModel(inStream, entity, sysAddr);
break; break;
case eGameMessageType::BUILD_MODE_SET: case MessageType::Game::BUILD_MODE_SET:
GameMessages::HandleBuildModeSet(inStream, entity); GameMessages::HandleBuildModeSet(inStream, entity);
break; break;
case eGameMessageType::REBUILD_CANCEL: case MessageType::Game::REBUILD_CANCEL:
GameMessages::HandleQuickBuildCancel(inStream, entity); GameMessages::HandleQuickBuildCancel(inStream, entity);
break; break;
case eGameMessageType::MATCH_REQUEST: case MessageType::Game::MATCH_REQUEST:
GameMessages::HandleMatchRequest(inStream, entity); GameMessages::HandleMatchRequest(inStream, entity);
break; break;
case eGameMessageType::USE_NON_EQUIPMENT_ITEM: case MessageType::Game::USE_NON_EQUIPMENT_ITEM:
GameMessages::HandleUseNonEquipmentItem(inStream, entity); GameMessages::HandleUseNonEquipmentItem(inStream, entity);
break; break;
case eGameMessageType::CLIENT_ITEM_CONSUMED: case MessageType::Game::CLIENT_ITEM_CONSUMED:
GameMessages::HandleClientItemConsumed(inStream, entity); GameMessages::HandleClientItemConsumed(inStream, entity);
break; break;
case eGameMessageType::SET_CONSUMABLE_ITEM: case MessageType::Game::SET_CONSUMABLE_ITEM:
GameMessages::HandleSetConsumableItem(inStream, entity, sysAddr); GameMessages::HandleSetConsumableItem(inStream, entity, sysAddr);
break; break;
case eGameMessageType::VERIFY_ACK: case MessageType::Game::VERIFY_ACK:
GameMessages::HandleVerifyAck(inStream, entity, sysAddr); GameMessages::HandleVerifyAck(inStream, entity, sysAddr);
break; break;
// Trading // Trading
case eGameMessageType::CLIENT_TRADE_REQUEST: case MessageType::Game::CLIENT_TRADE_REQUEST:
GameMessages::HandleClientTradeRequest(inStream, entity, sysAddr); GameMessages::HandleClientTradeRequest(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CLIENT_TRADE_CANCEL: case MessageType::Game::CLIENT_TRADE_CANCEL:
GameMessages::HandleClientTradeCancel(inStream, entity, sysAddr); GameMessages::HandleClientTradeCancel(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CLIENT_TRADE_ACCEPT: case MessageType::Game::CLIENT_TRADE_ACCEPT:
GameMessages::HandleClientTradeAccept(inStream, entity, sysAddr); GameMessages::HandleClientTradeAccept(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CLIENT_TRADE_UPDATE: case MessageType::Game::CLIENT_TRADE_UPDATE:
GameMessages::HandleClientTradeUpdate(inStream, entity, sysAddr); GameMessages::HandleClientTradeUpdate(inStream, entity, sysAddr);
break; break;
// Pets // Pets
case eGameMessageType::PET_TAMING_TRY_BUILD: case MessageType::Game::PET_TAMING_TRY_BUILD:
GameMessages::HandlePetTamingTryBuild(inStream, entity, sysAddr); GameMessages::HandlePetTamingTryBuild(inStream, entity, sysAddr);
break; break;
case eGameMessageType::NOTIFY_TAMING_BUILD_SUCCESS: case MessageType::Game::NOTIFY_TAMING_BUILD_SUCCESS:
GameMessages::HandleNotifyTamingBuildSuccess(inStream, entity, sysAddr); GameMessages::HandleNotifyTamingBuildSuccess(inStream, entity, sysAddr);
break; break;
case eGameMessageType::REQUEST_SET_PET_NAME: case MessageType::Game::REQUEST_SET_PET_NAME:
GameMessages::HandleRequestSetPetName(inStream, entity, sysAddr); GameMessages::HandleRequestSetPetName(inStream, entity, sysAddr);
break; break;
case eGameMessageType::START_SERVER_PET_MINIGAME_TIMER: case MessageType::Game::START_SERVER_PET_MINIGAME_TIMER:
GameMessages::HandleStartServerPetMinigameTimer(inStream, entity, sysAddr); GameMessages::HandleStartServerPetMinigameTimer(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CLIENT_EXIT_TAMING_MINIGAME: case MessageType::Game::CLIENT_EXIT_TAMING_MINIGAME:
GameMessages::HandleClientExitTamingMinigame(inStream, entity, sysAddr); GameMessages::HandleClientExitTamingMinigame(inStream, entity, sysAddr);
break; break;
case eGameMessageType::COMMAND_PET: case MessageType::Game::COMMAND_PET:
GameMessages::HandleCommandPet(inStream, entity, sysAddr); GameMessages::HandleCommandPet(inStream, entity, sysAddr);
break; break;
case eGameMessageType::DESPAWN_PET: case MessageType::Game::DESPAWN_PET:
GameMessages::HandleDespawnPet(inStream, entity, sysAddr); GameMessages::HandleDespawnPet(inStream, entity, sysAddr);
break; break;
case eGameMessageType::MESSAGE_BOX_RESPOND: case MessageType::Game::MESSAGE_BOX_RESPOND:
GameMessages::HandleMessageBoxResponse(inStream, entity, sysAddr); GameMessages::HandleMessageBoxResponse(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CHOICE_BOX_RESPOND: case MessageType::Game::CHOICE_BOX_RESPOND:
GameMessages::HandleChoiceBoxRespond(inStream, entity, sysAddr); GameMessages::HandleChoiceBoxRespond(inStream, entity, sysAddr);
break; break;
// Property // Property
case eGameMessageType::QUERY_PROPERTY_DATA: case MessageType::Game::QUERY_PROPERTY_DATA:
GameMessages::HandleQueryPropertyData(inStream, entity, sysAddr); GameMessages::HandleQueryPropertyData(inStream, entity, sysAddr);
break; break;
case eGameMessageType::START_BUILDING_WITH_ITEM: case MessageType::Game::START_BUILDING_WITH_ITEM:
GameMessages::HandleStartBuildingWithItem(inStream, entity, sysAddr); GameMessages::HandleStartBuildingWithItem(inStream, entity, sysAddr);
break; break;
case eGameMessageType::SET_BUILD_MODE: case MessageType::Game::SET_BUILD_MODE:
GameMessages::HandleSetBuildMode(inStream, entity, sysAddr); GameMessages::HandleSetBuildMode(inStream, entity, sysAddr);
break; break;
case eGameMessageType::PROPERTY_EDITOR_BEGIN: case MessageType::Game::PROPERTY_EDITOR_BEGIN:
GameMessages::HandlePropertyEditorBegin(inStream, entity, sysAddr); GameMessages::HandlePropertyEditorBegin(inStream, entity, sysAddr);
break; break;
case eGameMessageType::PROPERTY_EDITOR_END: case MessageType::Game::PROPERTY_EDITOR_END:
GameMessages::HandlePropertyEditorEnd(inStream, entity, sysAddr); GameMessages::HandlePropertyEditorEnd(inStream, entity, sysAddr);
break; break;
case eGameMessageType::PROPERTY_CONTENTS_FROM_CLIENT: case MessageType::Game::PROPERTY_CONTENTS_FROM_CLIENT:
GameMessages::HandlePropertyContentsFromClient(inStream, entity, sysAddr); GameMessages::HandlePropertyContentsFromClient(inStream, entity, sysAddr);
break; break;
case eGameMessageType::ZONE_PROPERTY_MODEL_EQUIPPED: case MessageType::Game::ZONE_PROPERTY_MODEL_EQUIPPED:
GameMessages::HandlePropertyModelEquipped(inStream, entity, sysAddr); GameMessages::HandlePropertyModelEquipped(inStream, entity, sysAddr);
break; break;
case eGameMessageType::PLACE_PROPERTY_MODEL: case MessageType::Game::PLACE_PROPERTY_MODEL:
GameMessages::HandlePlacePropertyModel(inStream, entity, sysAddr); GameMessages::HandlePlacePropertyModel(inStream, entity, sysAddr);
break; break;
case eGameMessageType::UPDATE_MODEL_FROM_CLIENT: case MessageType::Game::UPDATE_MODEL_FROM_CLIENT:
GameMessages::HandleUpdatePropertyModel(inStream, entity, sysAddr); GameMessages::HandleUpdatePropertyModel(inStream, entity, sysAddr);
break; break;
case eGameMessageType::DELETE_MODEL_FROM_CLIENT: case MessageType::Game::DELETE_MODEL_FROM_CLIENT:
GameMessages::HandleDeletePropertyModel(inStream, entity, sysAddr); GameMessages::HandleDeletePropertyModel(inStream, entity, sysAddr);
break; break;
case eGameMessageType::BBB_LOAD_ITEM_REQUEST: case MessageType::Game::BBB_LOAD_ITEM_REQUEST:
GameMessages::HandleBBBLoadItemRequest(inStream, entity, sysAddr); GameMessages::HandleBBBLoadItemRequest(inStream, entity, sysAddr);
break; break;
case eGameMessageType::BBB_SAVE_REQUEST: case MessageType::Game::BBB_SAVE_REQUEST:
GameMessages::HandleBBBSaveRequest(inStream, entity, sysAddr); GameMessages::HandleBBBSaveRequest(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CONTROL_BEHAVIORS: case MessageType::Game::CONTROL_BEHAVIORS:
GameMessages::HandleControlBehaviors(inStream, entity, sysAddr); GameMessages::HandleControlBehaviors(inStream, entity, sysAddr);
break; break;
case eGameMessageType::PROPERTY_ENTRANCE_SYNC: case MessageType::Game::PROPERTY_ENTRANCE_SYNC:
GameMessages::HandlePropertyEntranceSync(inStream, entity, sysAddr); GameMessages::HandlePropertyEntranceSync(inStream, entity, sysAddr);
break; break;
case eGameMessageType::ENTER_PROPERTY1: case MessageType::Game::ENTER_PROPERTY1:
GameMessages::HandleEnterProperty(inStream, entity, sysAddr); GameMessages::HandleEnterProperty(inStream, entity, sysAddr);
break; break;
case eGameMessageType::ZONE_PROPERTY_MODEL_ROTATED: case MessageType::Game::ZONE_PROPERTY_MODEL_ROTATED:
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity()); Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity());
break; break;
case eGameMessageType::UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK: case MessageType::Game::UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK:
GameMessages::HandleUpdatePropertyOrModelForFilterCheck(inStream, entity, sysAddr); GameMessages::HandleUpdatePropertyOrModelForFilterCheck(inStream, entity, sysAddr);
break; break;
case eGameMessageType::SET_PROPERTY_ACCESS: case MessageType::Game::SET_PROPERTY_ACCESS:
GameMessages::HandleSetPropertyAccess(inStream, entity, sysAddr); GameMessages::HandleSetPropertyAccess(inStream, entity, sysAddr);
break; break;
// Racing // Racing
case eGameMessageType::MODULE_ASSEMBLY_QUERY_DATA: case MessageType::Game::MODULE_ASSEMBLY_QUERY_DATA:
GameMessages::HandleModuleAssemblyQueryData(inStream, entity, sysAddr); GameMessages::HandleModuleAssemblyQueryData(inStream, entity, sysAddr);
break; break;
case eGameMessageType::ACKNOWLEDGE_POSSESSION: case MessageType::Game::ACKNOWLEDGE_POSSESSION:
GameMessages::HandleAcknowledgePossession(inStream, entity, sysAddr); GameMessages::HandleAcknowledgePossession(inStream, entity, sysAddr);
break; break;
case eGameMessageType::VEHICLE_SET_WHEEL_LOCK_STATE: case MessageType::Game::VEHICLE_SET_WHEEL_LOCK_STATE:
GameMessages::HandleVehicleSetWheelLockState(inStream, entity, sysAddr); GameMessages::HandleVehicleSetWheelLockState(inStream, entity, sysAddr);
break; break;
case eGameMessageType::MODULAR_ASSEMBLY_NIF_COMPLETED: case MessageType::Game::MODULAR_ASSEMBLY_NIF_COMPLETED:
GameMessages::HandleModularAssemblyNIFCompleted(inStream, entity, sysAddr); GameMessages::HandleModularAssemblyNIFCompleted(inStream, entity, sysAddr);
break; break;
case eGameMessageType::RACING_CLIENT_READY: case MessageType::Game::RACING_CLIENT_READY:
GameMessages::HandleRacingClientReady(inStream, entity, sysAddr); GameMessages::HandleRacingClientReady(inStream, entity, sysAddr);
break; break;
case eGameMessageType::REQUEST_DIE: case MessageType::Game::REQUEST_DIE:
GameMessages::HandleRequestDie(inStream, entity, sysAddr); GameMessages::HandleRequestDie(inStream, entity, sysAddr);
break; break;
case eGameMessageType::NOTIFY_SERVER_VEHICLE_ADD_PASSIVE_BOOST_ACTION: case MessageType::Game::NOTIFY_SERVER_VEHICLE_ADD_PASSIVE_BOOST_ACTION:
GameMessages::HandleVehicleNotifyServerAddPassiveBoostAction(inStream, entity, sysAddr); GameMessages::HandleVehicleNotifyServerAddPassiveBoostAction(inStream, entity, sysAddr);
break; break;
case eGameMessageType::NOTIFY_SERVER_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION: case MessageType::Game::NOTIFY_SERVER_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION:
GameMessages::HandleVehicleNotifyServerRemovePassiveBoostAction(inStream, entity, sysAddr); GameMessages::HandleVehicleNotifyServerRemovePassiveBoostAction(inStream, entity, sysAddr);
break; break;
case eGameMessageType::RACING_PLAYER_INFO_RESET_FINISHED: case MessageType::Game::RACING_PLAYER_INFO_RESET_FINISHED:
GameMessages::HandleRacingPlayerInfoResetFinished(inStream, entity, sysAddr); GameMessages::HandleRacingPlayerInfoResetFinished(inStream, entity, sysAddr);
break; break;
case eGameMessageType::VEHICLE_NOTIFY_HIT_IMAGINATION_SERVER: case MessageType::Game::VEHICLE_NOTIFY_HIT_IMAGINATION_SERVER:
GameMessages::HandleVehicleNotifyHitImaginationServer(inStream, entity, sysAddr); GameMessages::HandleVehicleNotifyHitImaginationServer(inStream, entity, sysAddr);
break; break;
case eGameMessageType::UPDATE_PROPERTY_PERFORMANCE_COST: case MessageType::Game::UPDATE_PROPERTY_PERFORMANCE_COST:
GameMessages::HandleUpdatePropertyPerformanceCost(inStream, entity, sysAddr); GameMessages::HandleUpdatePropertyPerformanceCost(inStream, entity, sysAddr);
break; break;
// SG // SG
case eGameMessageType::UPDATE_SHOOTING_GALLERY_ROTATION: case MessageType::Game::UPDATE_SHOOTING_GALLERY_ROTATION:
GameMessages::HandleUpdateShootingGalleryRotation(inStream, entity, sysAddr); GameMessages::HandleUpdateShootingGalleryRotation(inStream, entity, sysAddr);
break; break;
// NT // NT
case eGameMessageType::REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES: case MessageType::Game::REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES:
GameMessages::HandleRequestMoveItemBetweenInventoryTypes(inStream, entity, sysAddr); GameMessages::HandleRequestMoveItemBetweenInventoryTypes(inStream, entity, sysAddr);
break; break;
case eGameMessageType::TOGGLE_GHOST_REFERENCE_OVERRIDE: case MessageType::Game::TOGGLE_GHOST_REFERENCE_OVERRIDE:
GameMessages::HandleToggleGhostReferenceOverride(inStream, entity, sysAddr); GameMessages::HandleToggleGhostReferenceOverride(inStream, entity, sysAddr);
break; break;
case eGameMessageType::SET_GHOST_REFERENCE_POSITION: case MessageType::Game::SET_GHOST_REFERENCE_POSITION:
GameMessages::HandleSetGhostReferencePosition(inStream, entity, sysAddr); GameMessages::HandleSetGhostReferencePosition(inStream, entity, sysAddr);
break; break;
case eGameMessageType::READY_FOR_UPDATES: case MessageType::Game::READY_FOR_UPDATES:
//We don't really care about this message, as it's simply here to inform us that the client is done loading an object. //We don't really care about this message, as it's simply here to inform us that the client is done loading an object.
//In the event we _do_ send an update to an object that hasn't finished loading, the client will handle it anyway. //In the event we _do_ send an update to an object that hasn't finished loading, the client will handle it anyway.
break; break;
case eGameMessageType::REPORT_BUG: case MessageType::Game::REPORT_BUG:
GameMessages::HandleReportBug(inStream, entity); GameMessages::HandleReportBug(inStream, entity);
break; break;
case eGameMessageType::CLIENT_RAIL_MOVEMENT_READY: case MessageType::Game::CLIENT_RAIL_MOVEMENT_READY:
GameMessages::HandleClientRailMovementReady(inStream, entity, sysAddr); GameMessages::HandleClientRailMovementReady(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CANCEL_RAIL_MOVEMENT: case MessageType::Game::CANCEL_RAIL_MOVEMENT:
GameMessages::HandleCancelRailMovement(inStream, entity, sysAddr); GameMessages::HandleCancelRailMovement(inStream, entity, sysAddr);
break; break;
case eGameMessageType::PLAYER_RAIL_ARRIVED_NOTIFICATION: case MessageType::Game::PLAYER_RAIL_ARRIVED_NOTIFICATION:
GameMessages::HandlePlayerRailArrivedNotification(inStream, entity, sysAddr); GameMessages::HandlePlayerRailArrivedNotification(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CINEMATIC_UPDATE: case MessageType::Game::CINEMATIC_UPDATE:
GameMessages::HandleCinematicUpdate(inStream, entity, sysAddr); GameMessages::HandleCinematicUpdate(inStream, entity, sysAddr);
break; break;
case eGameMessageType::MODIFY_PLAYER_ZONE_STATISTIC: case MessageType::Game::MODIFY_PLAYER_ZONE_STATISTIC:
GameMessages::HandleModifyPlayerZoneStatistic(inStream, entity); GameMessages::HandleModifyPlayerZoneStatistic(inStream, entity);
break; break;
case eGameMessageType::UPDATE_PLAYER_STATISTIC: case MessageType::Game::UPDATE_PLAYER_STATISTIC:
GameMessages::HandleUpdatePlayerStatistic(inStream, entity); GameMessages::HandleUpdatePlayerStatistic(inStream, entity);
break; break;
case eGameMessageType::DISMOUNT_COMPLETE: case MessageType::Game::DISMOUNT_COMPLETE:
GameMessages::HandleDismountComplete(inStream, entity, sysAddr); GameMessages::HandleDismountComplete(inStream, entity, sysAddr);
break; break;
case eGameMessageType::DECTIVATE_BUBBLE_BUFF: case MessageType::Game::DECTIVATE_BUBBLE_BUFF:
GameMessages::HandleDeactivateBubbleBuff(inStream, entity); GameMessages::HandleDeactivateBubbleBuff(inStream, entity);
break; break;
case eGameMessageType::ACTIVATE_BUBBLE_BUFF: case MessageType::Game::ACTIVATE_BUBBLE_BUFF:
GameMessages::HandleActivateBubbleBuff(inStream, entity); GameMessages::HandleActivateBubbleBuff(inStream, entity);
break; break;
case eGameMessageType::ZONE_SUMMARY_DISMISSED: case MessageType::Game::ZONE_SUMMARY_DISMISSED:
GameMessages::HandleZoneSummaryDismissed(inStream, entity); GameMessages::HandleZoneSummaryDismissed(inStream, entity);
break; break;
case eGameMessageType::REQUEST_ACTIVITY_EXIT: case MessageType::Game::REQUEST_ACTIVITY_EXIT:
GameMessages::HandleRequestActivityExit(inStream, entity); GameMessages::HandleRequestActivityExit(inStream, entity);
break; break;
case eGameMessageType::ADD_DONATION_ITEM: case MessageType::Game::ADD_DONATION_ITEM:
GameMessages::HandleAddDonationItem(inStream, entity, sysAddr); GameMessages::HandleAddDonationItem(inStream, entity, sysAddr);
break; break;
case eGameMessageType::REMOVE_DONATION_ITEM: case MessageType::Game::REMOVE_DONATION_ITEM:
GameMessages::HandleRemoveDonationItem(inStream, entity, sysAddr); GameMessages::HandleRemoveDonationItem(inStream, entity, sysAddr);
break; break;
case eGameMessageType::CONFIRM_DONATION_ON_PLAYER: case MessageType::Game::CONFIRM_DONATION_ON_PLAYER:
GameMessages::HandleConfirmDonationOnPlayer(inStream, entity); GameMessages::HandleConfirmDonationOnPlayer(inStream, entity);
break; break;
case eGameMessageType::CANCEL_DONATION_ON_PLAYER: case MessageType::Game::CANCEL_DONATION_ON_PLAYER:
GameMessages::HandleCancelDonationOnPlayer(inStream, entity); GameMessages::HandleCancelDonationOnPlayer(inStream, entity);
break; break;
case eGameMessageType::REQUEST_VENDOR_STATUS_UPDATE: case MessageType::Game::REQUEST_VENDOR_STATUS_UPDATE:
GameMessages::SendVendorStatusUpdate(entity, sysAddr, true); GameMessages::SendVendorStatusUpdate(entity, sysAddr, true);
break; break;
case eGameMessageType::UPDATE_INVENTORY_GROUP: case MessageType::Game::UPDATE_INVENTORY_GROUP:
GameMessages::HandleUpdateInventoryGroup(inStream, entity, sysAddr); GameMessages::HandleUpdateInventoryGroup(inStream, entity, sysAddr);
break; break;
case eGameMessageType::UPDATE_INVENTORY_GROUP_CONTENTS: case MessageType::Game::UPDATE_INVENTORY_GROUP_CONTENTS:
GameMessages::HandleUpdateInventoryGroupContents(inStream, entity, sysAddr); GameMessages::HandleUpdateInventoryGroupContents(inStream, entity, sysAddr);
break; break;

View File

@ -19,10 +19,10 @@
#include "Logger.h" #include "Logger.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "CDClientDatabase.h" #include "CDClientDatabase.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
namespace GameMessageHandler { namespace GameMessageHandler {
void HandleMessage(RakNet::BitStream& inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID); void HandleMessage(RakNet::BitStream& inStream, const SystemAddress& sysAddr, LWOOBJID objectID, MessageType::Game messageID);
}; };
#endif // GAMEMESSAGEHANDLER_H #endif // GAMEMESSAGEHANDLER_H

File diff suppressed because it is too large Load Diff

View File

@ -29,10 +29,10 @@ void PropertySelectQueryProperty::Serialize(RakNet::BitStream& stream) const {
stream.Write(IsOwned); stream.Write(IsOwned);
stream.Write(AccessType); stream.Write(AccessType);
stream.Write(DateLastPublished); stream.Write(DateLastPublished);
stream.Write(PerformanceIndex);
stream.Write(PerformanceCost); stream.Write(PerformanceCost);
} }
void PropertySelectQueryProperty::Deserialize(RakNet::BitStream& stream) const { void PropertySelectQueryProperty::Deserialize(RakNet::BitStream& stream) const {
// Do we need this? // Do we need this?
// no
} }

View File

@ -5,8 +5,7 @@
#include "Entity.h" #include "Entity.h"
class PropertySelectQueryProperty final class PropertySelectQueryProperty final {
{
public: public:
void Serialize(RakNet::BitStream& stream) const; void Serialize(RakNet::BitStream& stream) const;
@ -23,9 +22,8 @@ public:
bool IsAlt = false; // Whether or not the property is owned by an alt of the account owner bool IsAlt = false; // Whether or not the property is owned by an alt of the account owner
bool IsOwned = false; // Whether or not the property is owned bool IsOwned = false; // Whether or not the property is owned
uint32_t AccessType = 0; // The privacy option of the property uint32_t AccessType = 0; // The privacy option of the property
uint32_t DateLastPublished = 0; // The last day the property was published uint64_t DateLastPublished = 0; // The last day the property was published
float PerformanceCost = 0; // The performance cost of the property float PerformanceCost = 0; // The performance cost of the property
uint32_t PerformanceIndex = 0; // The performance index of the property? Always 0?
}; };
#endif #endif

View File

@ -2,7 +2,7 @@
#define __REQUESTSERVERPROJECTILEIMPACT__H__ #define __REQUESTSERVERPROJECTILEIMPACT__H__
#include "dCommonVars.h" #include "dCommonVars.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
/* Notifying the server that a locally owned projectile impacted. Sent to the caster of the projectile /* Notifying the server that a locally owned projectile impacted. Sent to the caster of the projectile
should always be the local char. */ should always be the local char. */
@ -27,7 +27,7 @@ public:
} }
void Serialize(RakNet::BitStream& stream) { void Serialize(RakNet::BitStream& stream) {
stream.Write(eGameMessageType::REQUEST_SERVER_PROJECTILE_IMPACT); stream.Write(MessageType::Game::REQUEST_SERVER_PROJECTILE_IMPACT);
stream.Write(i64LocalID != LWOOBJID_EMPTY); stream.Write(i64LocalID != LWOOBJID_EMPTY);
if (i64LocalID != LWOOBJID_EMPTY) stream.Write(i64LocalID); if (i64LocalID != LWOOBJID_EMPTY) stream.Write(i64LocalID);

View File

@ -4,7 +4,7 @@
#include "dCommonVars.h" #include "dCommonVars.h"
#include "NiPoint3.h" #include "NiPoint3.h"
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
/** /**
* Same as sync skill but with different network options. An echo down to other clients that need to play the skill. * Same as sync skill but with different network options. An echo down to other clients that need to play the skill.
@ -44,7 +44,7 @@ public:
} }
void Serialize(RakNet::BitStream& stream) { void Serialize(RakNet::BitStream& stream) {
stream.Write(eGameMessageType::START_SKILL); stream.Write(MessageType::Game::START_SKILL);
stream.Write(bUsedMouse); stream.Write(bUsedMouse);

View File

@ -5,7 +5,7 @@
#include <string> #include <string>
#include "BitStream.h" #include "BitStream.h"
#include "eGameMessageType.h" #include "MessageType/Game.h"
/* Message to synchronize a skill cast */ /* Message to synchronize a skill cast */
class SyncSkill { class SyncSkill {
@ -29,7 +29,7 @@ public:
} }
void Serialize(RakNet::BitStream& stream) { void Serialize(RakNet::BitStream& stream) {
stream.Write(eGameMessageType::SYNC_SKILL); stream.Write(MessageType::Game::SYNC_SKILL);
stream.Write(bDone); stream.Write(bDone);
uint32_t sBitStreamLength = sBitStream.length(); uint32_t sBitStreamLength = sBitStream.length();

View File

@ -2,7 +2,7 @@
BlockDefinition BlockDefinition::blockDefinitionDefault{}; BlockDefinition BlockDefinition::blockDefinitionDefault{};
BlockDefinition::BlockDefinition(const std::string& defaultValue, const float minimumValue, const float maximumValue) BlockDefinition::BlockDefinition(const std::string_view defaultValue, const float minimumValue, const float maximumValue)
: m_DefaultValue{ defaultValue } : m_DefaultValue{ defaultValue }
, m_MinimumValue{ minimumValue } , m_MinimumValue{ minimumValue }
, m_MaximumValue{ maximumValue } { , m_MaximumValue{ maximumValue } {

View File

@ -7,13 +7,13 @@ class AMFArrayValue;
class BlockDefinition { class BlockDefinition {
public: public:
BlockDefinition(const std::string& defaultValue = "", const float minimumValue = 0.0f, const float maximumValue = 0.0f); BlockDefinition(const std::string_view defaultValue = "", const float minimumValue = 0.0f, const float maximumValue = 0.0f);
static BlockDefinition blockDefinitionDefault; static BlockDefinition blockDefinitionDefault;
[[nodiscard]] const std::string& GetDefaultValue() const { return m_DefaultValue; } [[nodiscard]] std::string_view GetDefaultValue() const { return m_DefaultValue; }
[[nodiscard]] float GetMinimumValue() const noexcept { return m_MinimumValue; } [[nodiscard]] float GetMinimumValue() const noexcept { return m_MinimumValue; }
[[nodiscard]] float GetMaximumValue() const noexcept { return m_MaximumValue; } [[nodiscard]] float GetMaximumValue() const noexcept { return m_MaximumValue; }
void SetDefaultValue(const std::string& value) { m_DefaultValue = value; } void SetDefaultValue(const std::string_view value) { m_DefaultValue = std::string{ value }; }
void SetMinimumValue(const float value) noexcept { m_MinimumValue = value; } void SetMinimumValue(const float value) noexcept { m_MinimumValue = value; }
void SetMaximumValue(const float value) noexcept { m_MaximumValue = value; } void SetMaximumValue(const float value) noexcept { m_MaximumValue = value; }

View File

@ -7,16 +7,16 @@ Action::Action(const AMFArrayValue& arguments) {
for (const auto& [paramName, paramValue] : arguments.GetAssociative()) { for (const auto& [paramName, paramValue] : arguments.GetAssociative()) {
if (paramName == "Type") { if (paramName == "Type") {
if (paramValue->GetValueType() != eAmf::String) continue; if (paramValue->GetValueType() != eAmf::String) continue;
m_Type = static_cast<AMFStringValue*>(paramValue)->GetValue(); m_Type = static_cast<AMFStringValue*>(paramValue.get())->GetValue();
} else { } else {
m_ValueParameterName = paramName; m_ValueParameterName = paramName;
// Message is the only known string parameter // Message is the only known string parameter
if (m_ValueParameterName == "Message") { if (m_ValueParameterName == "Message") {
if (paramValue->GetValueType() != eAmf::String) continue; if (paramValue->GetValueType() != eAmf::String) continue;
m_ValueParameterString = static_cast<AMFStringValue*>(paramValue)->GetValue(); m_ValueParameterString = static_cast<AMFStringValue*>(paramValue.get())->GetValue();
} else { } else {
if (paramValue->GetValueType() != eAmf::Double) continue; if (paramValue->GetValueType() != eAmf::Double) continue;
m_ValueParameterDouble = static_cast<AMFDoubleValue*>(paramValue)->GetValue(); m_ValueParameterDouble = static_cast<AMFDoubleValue*>(paramValue.get())->GetValue();
} }
} }
} }

View File

@ -17,9 +17,9 @@ class Action {
public: public:
Action() = default; Action() = default;
Action(const AMFArrayValue& arguments); Action(const AMFArrayValue& arguments);
[[nodiscard]] const std::string& GetType() const { return m_Type; }; [[nodiscard]] std::string_view GetType() const { return m_Type; };
[[nodiscard]] const std::string& GetValueParameterName() const { return m_ValueParameterName; }; [[nodiscard]] std::string_view GetValueParameterName() const { return m_ValueParameterName; };
[[nodiscard]] const std::string& GetValueParameterString() const { return m_ValueParameterString; }; [[nodiscard]] std::string_view GetValueParameterString() const { return m_ValueParameterString; };
[[nodiscard]] double GetValueParameterDouble() const noexcept { return m_ValueParameterDouble; }; [[nodiscard]] double GetValueParameterDouble() const noexcept { return m_ValueParameterDouble; };
void SendBehaviorBlocksToClient(AMFArrayValue& args) const; void SendBehaviorBlocksToClient(AMFArrayValue& args) const;

View File

@ -4,21 +4,21 @@
#include "Amf3.h" #include "Amf3.h"
ActionContext::ActionContext(const AMFArrayValue& arguments, const std::string& customStateKey, const std::string& customStripKey) ActionContext::ActionContext(const AMFArrayValue& arguments, const std::string_view customStateKey, const std::string_view customStripKey)
: m_StripId{ GetStripIdFromArgument(arguments, customStripKey) } : m_StripId{ GetStripIdFromArgument(arguments, customStripKey) }
, m_StateId{ GetBehaviorStateFromArgument(arguments, customStateKey) } { , m_StateId{ GetBehaviorStateFromArgument(arguments, customStateKey) } {
} }
BehaviorState ActionContext::GetBehaviorStateFromArgument(const AMFArrayValue& arguments, const std::string& key) const { BehaviorState ActionContext::GetBehaviorStateFromArgument(const AMFArrayValue& arguments, const std::string_view key) const {
const auto* const stateIDValue = arguments.Get<double>(key); const auto* const stateIDValue = arguments.Get<double>(key);
if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + std::string{ key } + "\"");
return static_cast<BehaviorState>(stateIDValue->GetValue()); return static_cast<BehaviorState>(stateIDValue->GetValue());
} }
StripId ActionContext::GetStripIdFromArgument(const AMFArrayValue& arguments, const std::string& key) const { StripId ActionContext::GetStripIdFromArgument(const AMFArrayValue& arguments, const std::string_view key) const {
const auto* const stripIdValue = arguments.Get<double>(key); const auto* const stripIdValue = arguments.Get<double>(key);
if (!stripIdValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); if (!stripIdValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + std::string{ key } + "\"");
return static_cast<StripId>(stripIdValue->GetValue()); return static_cast<StripId>(stripIdValue->GetValue());
} }

View File

@ -4,6 +4,8 @@
#include "BehaviorStates.h" #include "BehaviorStates.h"
#include "dCommonVars.h" #include "dCommonVars.h"
#include <string_view>
class AMFArrayValue; class AMFArrayValue;
/** /**
@ -13,13 +15,13 @@ class AMFArrayValue;
class ActionContext { class ActionContext {
public: public:
ActionContext() noexcept = default; ActionContext() noexcept = default;
ActionContext(const AMFArrayValue& arguments, const std::string& customStateKey = "stateID", const std::string& customStripKey = "stripID"); ActionContext(const AMFArrayValue& arguments, const std::string_view customStateKey = "stateID", const std::string_view customStripKey = "stripID");
[[nodiscard]] StripId GetStripId() const noexcept { return m_StripId; }; [[nodiscard]] StripId GetStripId() const noexcept { return m_StripId; };
[[nodiscard]] BehaviorState GetStateId() const noexcept { return m_StateId; }; [[nodiscard]] BehaviorState GetStateId() const noexcept { return m_StateId; };
private: private:
[[nodiscard]] BehaviorState GetBehaviorStateFromArgument(const AMFArrayValue& arguments, const std::string& key) const; [[nodiscard]] BehaviorState GetBehaviorStateFromArgument(const AMFArrayValue& arguments, const std::string_view key) const;
[[nodiscard]] StripId GetStripIdFromArgument(const AMFArrayValue& arguments, const std::string& key) const; [[nodiscard]] StripId GetStripIdFromArgument(const AMFArrayValue& arguments, const std::string_view key) const;
StripId m_StripId{ 0 }; StripId m_StripId{ 0 };
BehaviorState m_StateId{ BehaviorState::HOME_STATE }; BehaviorState m_StateId{ BehaviorState::HOME_STATE };
}; };

View File

@ -10,5 +10,5 @@ AddActionMessage::AddActionMessage(const AMFArrayValue& arguments)
m_Action = Action{ *actionValue }; m_Action = Action{ *actionValue };
LOG_DEBUG("actionIndex %i stripId %i stateId %i type %s valueParameterName %s valueParameterString %s valueParameterDouble %f m_BehaviorId %i", m_ActionIndex, m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_Action.GetType().c_str(), m_Action.GetValueParameterName().c_str(), m_Action.GetValueParameterString().c_str(), m_Action.GetValueParameterDouble(), m_BehaviorId); LOG_DEBUG("actionIndex %i stripId %i stateId %i type %s valueParameterName %s valueParameterString %s valueParameterDouble %f m_BehaviorId %i", m_ActionIndex, m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_Action.GetType().data(), m_Action.GetValueParameterName().data(), m_Action.GetValueParameterString().data(), m_Action.GetValueParameterDouble(), m_BehaviorId);
} }

View File

@ -19,7 +19,7 @@ AddStripMessage::AddStripMessage(const AMFArrayValue& arguments)
m_ActionsToAdd.emplace_back(*actionValue); m_ActionsToAdd.emplace_back(*actionValue);
LOG_DEBUG("xPosition %f yPosition %f stripId %i stateId %i behaviorId %i t %s valueParameterName %s valueParameterString %s valueParameterDouble %f", m_Position.GetX(), m_Position.GetY(), m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_BehaviorId, m_ActionsToAdd.back().GetType().c_str(), m_ActionsToAdd.back().GetValueParameterName().c_str(), m_ActionsToAdd.back().GetValueParameterString().c_str(), m_ActionsToAdd.back().GetValueParameterDouble()); LOG_DEBUG("xPosition %f yPosition %f stripId %i stateId %i behaviorId %i t %s valueParameterName %s valueParameterString %s valueParameterDouble %f", m_Position.GetX(), m_Position.GetY(), m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_BehaviorId, m_ActionsToAdd.back().GetType().data(), m_ActionsToAdd.back().GetValueParameterName().data(), m_ActionsToAdd.back().GetValueParameterString().data(), m_ActionsToAdd.back().GetValueParameterDouble());
} }
LOG_DEBUG("number of actions %i", m_ActionsToAdd.size()); LOG_DEBUG("number of actions %i", m_ActionsToAdd.size());
} }

View File

@ -5,7 +5,7 @@
#include "dCommonVars.h" #include "dCommonVars.h"
int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(const AMFArrayValue& arguments) { int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(const AMFArrayValue& arguments) {
static constexpr const char* key = "BehaviorID"; static constexpr std::string_view key = "BehaviorID";
const auto* const behaviorIDValue = arguments.Get<std::string>(key); const auto* const behaviorIDValue = arguments.Get<std::string>(key);
int32_t behaviorId = DefaultBehaviorId; int32_t behaviorId = DefaultBehaviorId;
@ -19,7 +19,7 @@ int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(const AMFArrayValue& argu
return behaviorId; return behaviorId;
} }
int32_t BehaviorMessageBase::GetActionIndexFromArgument(const AMFArrayValue& arguments, const std::string& keyName) const { int32_t BehaviorMessageBase::GetActionIndexFromArgument(const AMFArrayValue& arguments, const std::string_view keyName) const {
const auto* const actionIndexAmf = arguments.Get<double>(keyName); const auto* const actionIndexAmf = arguments.Get<double>(keyName);
if (!actionIndexAmf) throw std::invalid_argument("Unable to find actionIndex"); if (!actionIndexAmf) throw std::invalid_argument("Unable to find actionIndex");

View File

@ -22,7 +22,7 @@ public:
protected: protected:
[[nodiscard]] int32_t GetBehaviorIdFromArgument(const AMFArrayValue& arguments); [[nodiscard]] int32_t GetBehaviorIdFromArgument(const AMFArrayValue& arguments);
[[nodiscard]] int32_t GetActionIndexFromArgument(const AMFArrayValue& arguments, const std::string& keyName = "actionIndex") const; [[nodiscard]] int32_t GetActionIndexFromArgument(const AMFArrayValue& arguments, const std::string_view keyName = "actionIndex") const;
int32_t m_BehaviorId{ DefaultBehaviorId }; int32_t m_BehaviorId{ DefaultBehaviorId };
}; };

View File

@ -11,7 +11,7 @@ class AMFArrayValue;
class RenameMessage : public BehaviorMessageBase { class RenameMessage : public BehaviorMessageBase {
public: public:
RenameMessage(const AMFArrayValue& arguments); RenameMessage(const AMFArrayValue& arguments);
[[nodiscard]] const std::string& GetName() const { return m_Name; }; [[nodiscard]] std::string_view GetName() const { return m_Name; };
private: private:
std::string m_Name; std::string m_Name;

View File

@ -3,7 +3,7 @@
#include "Amf3.h" #include "Amf3.h"
#include "tinyxml2.h" #include "tinyxml2.h"
StripUiPosition::StripUiPosition(const AMFArrayValue& arguments, const std::string& uiKeyName) { StripUiPosition::StripUiPosition(const AMFArrayValue& arguments, const std::string_view uiKeyName) {
const auto* const uiArray = arguments.GetArray(uiKeyName); const auto* const uiArray = arguments.GetArray(uiKeyName);
if (!uiArray) return; if (!uiArray) return;

View File

@ -14,7 +14,7 @@ namespace tinyxml2 {
class StripUiPosition { class StripUiPosition {
public: public:
StripUiPosition() noexcept = default; StripUiPosition() noexcept = default;
StripUiPosition(const AMFArrayValue& arguments, const std::string& uiKeyName = "ui"); StripUiPosition(const AMFArrayValue& arguments, const std::string_view uiKeyName = "ui");
void SendBehaviorBlocksToClient(AMFArrayValue& args) const; void SendBehaviorBlocksToClient(AMFArrayValue& args) const;
[[nodiscard]] double GetX() const noexcept { return m_XPosition; } [[nodiscard]] double GetX() const noexcept { return m_XPosition; }
[[nodiscard]] double GetY() const noexcept { return m_YPosition; } [[nodiscard]] double GetY() const noexcept { return m_YPosition; }

View File

@ -12,5 +12,5 @@ UpdateActionMessage::UpdateActionMessage(const AMFArrayValue& arguments)
m_Action = Action{ *actionValue }; m_Action = Action{ *actionValue };
LOG_DEBUG("type %s valueParameterName %s valueParameterString %s valueParameterDouble %f behaviorId %i actionIndex %i stripId %i stateId %i", m_Action.GetType().c_str(), m_Action.GetValueParameterName().c_str(), m_Action.GetValueParameterString().c_str(), m_Action.GetValueParameterDouble(), m_BehaviorId, m_ActionIndex, m_ActionContext.GetStripId(), m_ActionContext.GetStateId()); LOG_DEBUG("type %s valueParameterName %s valueParameterString %s valueParameterDouble %f behaviorId %i actionIndex %i stripId %i stateId %i", m_Action.GetType().data(), m_Action.GetValueParameterName().data(), m_Action.GetValueParameterString().data(), m_Action.GetValueParameterDouble(), m_BehaviorId, m_ActionIndex, m_ActionContext.GetStripId(), m_ActionContext.GetStateId());
} }

View File

@ -76,26 +76,26 @@ void ControlBehaviors::UpdateAction(const AMFArrayValue& arguments) {
auto blockDefinition = GetBlockInfo(updateActionMessage.GetAction().GetType()); auto blockDefinition = GetBlockInfo(updateActionMessage.GetAction().GetType());
if (!blockDefinition) { if (!blockDefinition) {
LOG("Received undefined block type %s. Ignoring.", updateActionMessage.GetAction().GetType().c_str()); LOG("Received undefined block type %s. Ignoring.", updateActionMessage.GetAction().GetType().data());
return; return;
} }
if (updateActionMessage.GetAction().GetValueParameterString().size() > 0) { if (updateActionMessage.GetAction().GetValueParameterString().size() > 0) {
if (updateActionMessage.GetAction().GetValueParameterString().size() < blockDefinition->GetMinimumValue() || if (updateActionMessage.GetAction().GetValueParameterString().size() < blockDefinition->GetMinimumValue() ||
updateActionMessage.GetAction().GetValueParameterString().size() > blockDefinition->GetMaximumValue()) { updateActionMessage.GetAction().GetValueParameterString().size() > blockDefinition->GetMaximumValue()) {
LOG("Updated block %s is out of range. Ignoring update", updateActionMessage.GetAction().GetType().c_str()); LOG("Updated block %s is out of range. Ignoring update", updateActionMessage.GetAction().GetType().data());
return; return;
} }
} else { } else {
if (updateActionMessage.GetAction().GetValueParameterDouble() < blockDefinition->GetMinimumValue() || if (updateActionMessage.GetAction().GetValueParameterDouble() < blockDefinition->GetMinimumValue() ||
updateActionMessage.GetAction().GetValueParameterDouble() > blockDefinition->GetMaximumValue()) { updateActionMessage.GetAction().GetValueParameterDouble() > blockDefinition->GetMaximumValue()) {
LOG("Updated block %s is out of range. Ignoring update", updateActionMessage.GetAction().GetType().c_str()); LOG("Updated block %s is out of range. Ignoring update", updateActionMessage.GetAction().GetType().data());
return; return;
} }
} }
} }
void ControlBehaviors::ProcessCommand(Entity* const modelEntity, const AMFArrayValue& arguments, const std::string& command, Entity* const modelOwner) { void ControlBehaviors::ProcessCommand(Entity* const modelEntity, const AMFArrayValue& arguments, const std::string_view command, Entity* const modelOwner) {
if (!isInitialized || !modelEntity || !modelOwner) return; if (!isInitialized || !modelEntity || !modelOwner) return;
auto* const modelComponent = modelEntity->GetComponent<ModelComponent>(); auto* const modelComponent = modelEntity->GetComponent<ModelComponent>();
@ -157,7 +157,7 @@ void ControlBehaviors::ProcessCommand(Entity* const modelEntity, const AMFArrayV
} else if (command == "updateAction") { } else if (command == "updateAction") {
context.modelComponent->HandleControlBehaviorsMsg<UpdateActionMessage>(arguments); context.modelComponent->HandleControlBehaviorsMsg<UpdateActionMessage>(arguments);
} else { } else {
LOG("Unknown behavior command (%s)", command.c_str()); LOG("Unknown behavior command (%s)", command.data());
} }
} }
@ -279,11 +279,11 @@ ControlBehaviors::ControlBehaviors() {
isInitialized = true; isInitialized = true;
LOG_DEBUG("Created all base block classes"); LOG_DEBUG("Created all base block classes");
for (auto& [name, block] : blockTypes) { for (auto& [name, block] : blockTypes) {
LOG_DEBUG("block name is %s default %s min %f max %f", name.c_str(), block.GetDefaultValue().c_str(), block.GetMinimumValue(), block.GetMaximumValue()); LOG_DEBUG("block name is %s default %s min %f max %f", name.data(), block.GetDefaultValue().data(), block.GetMinimumValue(), block.GetMaximumValue());
} }
} }
std::optional<BlockDefinition> ControlBehaviors::GetBlockInfo(const std::string& blockName) { std::optional<BlockDefinition> ControlBehaviors::GetBlockInfo(const std::string_view blockName) {
auto blockDefinition = blockTypes.find(blockName); auto blockDefinition = blockTypes.find(blockName);
return blockDefinition != blockTypes.end() ? std::optional(blockDefinition->second) : std::nullopt; return blockDefinition != blockTypes.end() ? std::optional(blockDefinition->second) : std::nullopt;
} }

View File

@ -43,7 +43,7 @@ public:
* @param command The command to perform * @param command The command to perform
* @param modelOwner The owner of the model which sent this command * @param modelOwner The owner of the model which sent this command
*/ */
void ProcessCommand(Entity* const modelEntity, const AMFArrayValue& arguments, const std::string& command, Entity* const modelOwner); void ProcessCommand(Entity* const modelEntity, const AMFArrayValue& arguments, const std::string_view command, Entity* const modelOwner);
/** /**
* @brief Gets a blocks parameter values by the name * @brief Gets a blocks parameter values by the name
@ -53,7 +53,7 @@ public:
* *
* @return A pair of the block parameter name to its typing * @return A pair of the block parameter name to its typing
*/ */
[[nodiscard]] std::optional<BlockDefinition> GetBlockInfo(const std::string& blockName); [[nodiscard]] std::optional<BlockDefinition> GetBlockInfo(const std::string_view blockName);
private: private:
void RequestUpdatedID(ControlBehaviorContext& context); void RequestUpdatedID(ControlBehaviorContext& context);
void SendBehaviorListToClient(const ControlBehaviorContext& context); void SendBehaviorListToClient(const ControlBehaviorContext& context);

View File

@ -245,7 +245,7 @@ void Mail::HandleDataRequest(RakNet::BitStream& packet, const SystemAddress& sys
auto playerMail = Database::Get()->GetMailForPlayer(player->GetCharacter()->GetID(), 20); auto playerMail = Database::Get()->GetMailForPlayer(player->GetCharacter()->GetID(), 20);
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::MAIL);
bitStream.Write(int(MailMessageID::MailData)); bitStream.Write(int(MailMessageID::MailData));
bitStream.Write(int(0)); // throttled bitStream.Write(int(0)); // throttled
@ -348,7 +348,7 @@ void Mail::HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t obje
void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) { void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) {
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::MAIL);
bitStream.Write(int(MailMessageID::SendResponse)); bitStream.Write(int(MailMessageID::SendResponse));
bitStream.Write(int(response)); bitStream.Write(int(response));
Game::server->Send(bitStream, sysAddr, false); Game::server->Send(bitStream, sysAddr, false);
@ -356,7 +356,7 @@ void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse respo
void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) { void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::MAIL);
uint64_t messageType = 2; uint64_t messageType = 2;
uint64_t s1 = 0; uint64_t s1 = 0;
uint64_t s2 = 0; uint64_t s2 = 0;
@ -375,7 +375,7 @@ void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) { void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::MAIL);
bitStream.Write(int(MailMessageID::AttachmentCollectConfirm)); bitStream.Write(int(MailMessageID::AttachmentCollectConfirm));
bitStream.Write(int(0)); //unknown bitStream.Write(int(0)); //unknown
bitStream.Write(mailID); bitStream.Write(mailID);
@ -384,7 +384,7 @@ void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t ma
void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) { void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) {
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::MAIL);
bitStream.Write(int(MailMessageID::MailDeleteConfirm)); bitStream.Write(int(MailMessageID::MailDeleteConfirm));
bitStream.Write(int(0)); //unknown bitStream.Write(int(0)); //unknown
bitStream.Write(mailID); bitStream.Write(mailID);
@ -395,7 +395,7 @@ void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOO
void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) { void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::MAIL);
bitStream.Write(int(MailMessageID::MailReadConfirm)); bitStream.Write(int(MailMessageID::MailReadConfirm));
bitStream.Write(int(0)); //unknown bitStream.Write(int(0)); //unknown
bitStream.Write(mailID); bitStream.Write(mailID);

View File

@ -16,7 +16,7 @@
#include "Amf3.h" #include "Amf3.h"
#include "Database.h" #include "Database.h"
#include "eChatMessageType.h" #include "MessageType/Chat.h"
#include "dServer.h" #include "dServer.h"
namespace { namespace {
@ -153,7 +153,7 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::
//Notify chat about it //Notify chat about it
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GM_ANNOUNCE); BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_ANNOUNCE);
bitStream.Write<uint32_t>(title.size()); bitStream.Write<uint32_t>(title.size());
for (auto character : title) { for (auto character : title) {

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