Compare commits

..

5 Commits

Author SHA1 Message Date
David Markowitz
0dd3cce8ed Remove extra includes 2024-01-12 03:26:33 -08:00
David Markowitz
87d5bd0229 remove player cast 2024-01-12 03:17:01 -08:00
David Markowitz
f4a6086e4c Merge branch 'player-stuff' of https://github.com/DarkflameUniverse/DarkflameServer into player-stuff 2024-01-11 04:35:00 -08:00
David Markowitz
eccd6f691f Moving and organizing Player code
- Move code to CharacterComponent
- Remove extraneous interfaces
- Simplify some code greatly
- Change some types to return and take in const ref (only structs larger than 8 bytes benefit from this change.)
- Update code to use CharacterComponent for sending to zone instead of Player*.
- Remove static storage container (static containers can be destroyed before exit/terminate handler executes)
2024-01-11 04:34:55 -08:00
David Markowitz
a54085945f Moving and organizing Player code
- Move code to CharacterComponent
- Remove extraneous interfaces
- Simplify some code greatly
- Change some types to return and take in const ref (only structs larger than 8 bytes benefit from this change.)
- Update code to use CharacterComponent for sending to zone instead of Player*.
2024-01-11 04:33:53 -08:00
741 changed files with 12343 additions and 15456 deletions

View File

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

View File

@@ -1,18 +1,8 @@
cmake_minimum_required(VERSION 3.25)
cmake_minimum_required(VERSION 3.18)
project(Darkflame)
# check if the path to the source directory contains a space
if("${CMAKE_SOURCE_DIR}" MATCHES " ")
message(FATAL_ERROR "The server cannot build in the path (" ${CMAKE_SOURCE_DIR} ") because it contains a space. Please move the server to a path without spaces.")
endif()
include(CTest)
set(CMAKE_CXX_STANDARD 20)
set(CXX_STANDARD_REQUIRED ON)
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_VISIBILITY_INLINES_HIDDEN ON) # Set C and C++ symbol visibility to hide inlined functions
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# Read variables from file
@@ -79,15 +69,13 @@ if(UNIX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC")
elseif(MSVC)
# Skip warning for invalid conversion from size_t to uint32_t for all targets below for now
# Also disable non-portable MSVC volatile behavior
add_compile_options("/wd4267" "/utf-8" "/volatile:iso")
add_compile_options("/wd4267" "/utf-8")
elseif(WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()
# 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
# TODO make this not have to override the build type directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR})
@@ -101,8 +89,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
find_package(MariaDB)
# Create a /resServer directory
make_directory(${CMAKE_BINARY_DIR}/resServer)
@@ -110,7 +96,7 @@ make_directory(${CMAKE_BINARY_DIR}/resServer)
make_directory(${CMAKE_BINARY_DIR}/logs)
# 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" "blacklist.dcf")
message(STATUS "Checking resource file integrity")
include(Utils)
@@ -192,7 +178,7 @@ file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip DESTINATION ${PRO
file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip)
# Copy vanity files on first build
set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "root.xml" "dev-tribute.xml" "atm.xml" "demo.xml")
set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml")
foreach(file ${VANITY_FILES})
configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY)
@@ -215,47 +201,88 @@ foreach(file ${SQL_FILES})
configure_file(${CMAKE_SOURCE_DIR}/migrations/cdserver/${file} ${PROJECT_BINARY_DIR}/migrations/cdserver/${file})
endforeach()
# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
if (APPLE)
include_directories("/usr/local/include/")
endif()
# Load all of our third party directories
add_subdirectory(thirdparty SYSTEM)
# Create our list of include directories
include_directories(
set(INCLUDED_DIRECTORIES
"dCommon"
"dCommon/dClient"
"dCommon/dEnums"
"dChatFilter"
"dGame"
"dGame/dBehaviors"
"dGame/dComponents"
"dGame/dGameMessages"
"dGame/dInventory"
"dGame/dMission"
"dGame/dEntity"
"dGame/dPropertyBehaviors"
"dGame/dPropertyBehaviors/ControlBehaviorMessages"
"dGame/dUtilities"
"dPhysics"
"dNavigation"
"dNavigation/dTerrain"
"dZoneManager"
"dDatabase"
"dDatabase/CDClientDatabase"
"dDatabase/CDClientDatabase/CDClientTables"
"dDatabase/GameDatabase"
"dDatabase/GameDatabase/ITables"
"dDatabase/GameDatabase/MySQL"
"dDatabase/GameDatabase/MySQL/Tables"
"dNet"
"thirdparty/magic_enum/include/magic_enum"
"thirdparty/raknet/Source"
"thirdparty/tinyxml2"
"thirdparty/recastnavigation"
"thirdparty/SQLite"
"thirdparty/cpplinq"
"thirdparty/cpp-httplib"
"tests"
"tests/dCommonTests"
"tests/dGameTests"
"tests/dGameTests/dComponentsTests"
SYSTEM "thirdparty/magic_enum/include/magic_enum"
SYSTEM "thirdparty/raknet/Source"
SYSTEM "thirdparty/tinyxml2"
SYSTEM "thirdparty/recastnavigation"
SYSTEM "thirdparty/SQLite"
SYSTEM "thirdparty/cpplinq"
SYSTEM "thirdparty/cpp-httplib"
SYSTEM "thirdparty/MD5"
)
# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
# TODO: Should probably not do this.
if(APPLE)
include_directories("/usr/local/include/")
endif()
# Add linking directories:
if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast -Werror") # Warning flags
# Actually include the directories from our list
foreach(dir ${INCLUDED_DIRECTORIES})
include_directories(${PROJECT_SOURCE_DIR}/${dir})
endforeach()
if(NOT WIN32)
include_directories("${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include/bcrypt")
endif()
include_directories("${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include")
# Add linking directories:
link_directories(${PROJECT_BINARY_DIR})
# Load all of our third party directories
add_subdirectory(thirdparty)
# Glob together all headers that need to be precompiled
file(
GLOB HEADERS_DDATABASE
LIST_DIRECTORIES false
${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/*.h
${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables/*.h
${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables/*.h
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h
)
file(
GLOB HEADERS_DZONEMANAGER
LIST_DIRECTORIES false
@@ -290,7 +317,7 @@ add_subdirectory(dPhysics)
add_subdirectory(dServer)
# Create a list of common libraries shared between all binaries
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "MariaDB::ConnCpp" "magic_enum")
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum")
# Add platform specific common libraries
if(UNIX)
@@ -312,6 +339,12 @@ target_precompile_headers(
${HEADERS_DZONEMANAGER}
)
# Need to specify to use the CXX compiler language here or else we get errors including <string>.
target_precompile_headers(
dDatabase PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE}>"
)
target_precompile_headers(
dCommon PRIVATE
${HEADERS_DCOMMON}

View File

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

View File

@@ -1,6 +1,6 @@
PROJECT_VERSION_MAJOR=2
PROJECT_VERSION_MINOR=3
PROJECT_VERSION_PATCH=0
PROJECT_VERSION_MAJOR=1
PROJECT_VERSION_MINOR=1
PROJECT_VERSION_PATCH=1
# Debugging
# Set DYNAMIC to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs.

View File

@@ -23,7 +23,8 @@ RUN --mount=type=cache,id=build-apt-cache,target=/var/cache/apt \
rm -rf /var/lib/apt/lists/*
# Grab libraries and load them
COPY --from=build /app/build/mariadbcpp/libmariadbcpp.so /usr/local/lib/
COPY --from=build /app/build/mariadbcpp/src/mariadb_connector_cpp-build/libmariadbcpp.so /usr/local/lib/
COPY --from=build /app/build/mariadbcpp/src/mariadb_connector_cpp-build/libmariadb/libmariadb/libmariadb.so.3 /usr/local/lib
RUN ldconfig
# Server bins
@@ -31,7 +32,7 @@ COPY --from=build /app/build/*Server /app/
# Necessary suplimentary files
COPY --from=build /app/build/*.ini /app/configs/
COPY --from=build /app/build/vanity/*.* /app/vanity/
COPY --from=build /app/build/vanity/*.* /app/vanity/*
COPY --from=build /app/build/navmeshes /app/navmeshes
COPY --from=build /app/build/migrations /app/migrations
COPY --from=build /app/build/*.dcf /app/
@@ -39,7 +40,7 @@ COPY --from=build /app/build/*.dcf /app/
# backup of config and vanity files to copy to the host incase
# of a mount clobbering the copy from above
COPY --from=build /app/build/*.ini /app/default-configs/
COPY --from=build /app/build/vanity/*.* /app/default-vanity/
COPY --from=build /app/build/vanity/*.* /app/default-vanity/*
# needed as the container runs with the root user
# and therefore sudo doesn't exist

View File

@@ -51,7 +51,7 @@ git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer
### Windows packages
Ensure that you have either the [MSVC C++ compiler](https://visualstudio.microsoft.com/vs/features/cplusplus/) (recommended) or the [Clang compiler](https://github.com/llvm/llvm-project/releases/) installed.
You'll also need to download and install [CMake](https://cmake.org/download/) (version <font size="4">**CMake version 3.25**</font> or later!).
You'll also need to download and install [CMake](https://cmake.org/download/) (version <font size="4">**CMake version 3.18**</font> or later!).
### MacOS packages
Ensure you have [brew](https://brew.sh) installed.
@@ -73,7 +73,7 @@ sudo apt install build-essential gcc zlib1g-dev libssl-dev openssl mariadb-serve
```
#### Required CMake version
This project uses <font size="4">**CMake version 3.25**</font> or higher and as such you will need to ensure you have this version installed.
This project uses <font size="4">**CMake version 3.18**</font> or higher and as such you will need to ensure you have this version installed.
You can check your CMake version by using the following command in a terminal.
```bash
cmake --version
@@ -356,10 +356,6 @@ The Darkflame Server is automatically built and published as a Docker Container
## Compose
> [!WARNING]
> It seems that Docker Desktop on Windows with the WSL 2 backend has some issues with MariaDB (c.f. [mariadb-docker#331](https://github.com/MariaDB/mariadb-docker/issues/331)) triggered by NexusDashboard
> migrations, so this setup may not work for you. If that is the case, please tell us about your setup in [NexusDashboard#92](https://github.com/DarkflameUniverse/NexusDashboard/issues/92).
You can use the `docker-compose` tool to [setup a MariaDB database](#database-setup), run the Darkflame Server and manage it with [Nexus Dashboard](https://github.com/DarkflameUniverse/NexusDashboard) all
at once. For that:

View File

@@ -1,17 +0,0 @@
include(FetchContent)
message(STATUS "Fetching gtest...")
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(GoogleTest)
message(STATUS "gtest fetched and is now ready.")
set(GoogleTest_FOUND TRUE)

View File

@@ -82,11 +82,11 @@ int main(int argc, char** argv) {
Game::randomEngine = std::mt19937(time(0));
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999;
uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
std::string ourIP = "localhost";
const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999);
//LU client is hardcoded to use this for auth port, so I'm making it the default.
const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("auth_server_port")).value_or(1001);
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
GeneralUtils::TryParse(Game::config->GetValue("auth_server_port"), ourPort);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;

View File

@@ -27,8 +27,8 @@ dChatFilter::dChatFilter(const std::string& filepath, bool dontGenerateDCF) {
ExportWordlistToDCF(filepath + ".dcf", true);
}
if (BinaryIO::DoesFileExist("blocklist.dcf")) {
ReadWordlistDCF("blocklist.dcf", false);
if (BinaryIO::DoesFileExist("blacklist.dcf")) {
ReadWordlistDCF("blacklist.dcf", false);
}
//Read player names that are ok as well:
@@ -44,20 +44,20 @@ dChatFilter::~dChatFilter() {
m_DeniedWords.clear();
}
void dChatFilter::ReadWordlistPlaintext(const std::string& filepath, bool allowList) {
void dChatFilter::ReadWordlistPlaintext(const std::string& filepath, bool whiteList) {
std::ifstream file(filepath);
if (file) {
std::string line;
while (std::getline(file, line)) {
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
std::transform(line.begin(), line.end(), line.begin(), ::tolower); //Transform to lowercase
if (allowList) m_ApprovedWords.push_back(CalculateHash(line));
if (whiteList) m_ApprovedWords.push_back(CalculateHash(line));
else m_DeniedWords.push_back(CalculateHash(line));
}
}
}
bool dChatFilter::ReadWordlistDCF(const std::string& filepath, bool allowList) {
bool dChatFilter::ReadWordlistDCF(const std::string& filepath, bool whiteList) {
std::ifstream file(filepath, std::ios::binary);
if (file) {
fileHeader hdr;
@@ -70,13 +70,13 @@ bool dChatFilter::ReadWordlistDCF(const std::string& filepath, bool allowList) {
if (hdr.formatVersion == formatVersion) {
size_t wordsToRead = 0;
BinaryIO::BinaryRead(file, wordsToRead);
if (allowList) m_ApprovedWords.reserve(wordsToRead);
if (whiteList) m_ApprovedWords.reserve(wordsToRead);
else m_DeniedWords.reserve(wordsToRead);
size_t word = 0;
for (size_t i = 0; i < wordsToRead; ++i) {
BinaryIO::BinaryRead(file, word);
if (allowList) m_ApprovedWords.push_back(word);
if (whiteList) m_ApprovedWords.push_back(word);
else m_DeniedWords.push_back(word);
}
@@ -90,14 +90,14 @@ bool dChatFilter::ReadWordlistDCF(const std::string& filepath, bool allowList) {
return false;
}
void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool allowList) {
void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool whiteList) {
std::ofstream file(filepath, std::ios::binary | std::ios_base::out);
if (file) {
BinaryIO::BinaryWrite(file, uint32_t(dChatFilterDCF::header));
BinaryIO::BinaryWrite(file, uint32_t(dChatFilterDCF::formatVersion));
BinaryIO::BinaryWrite(file, size_t(allowList ? m_ApprovedWords.size() : m_DeniedWords.size()));
BinaryIO::BinaryWrite(file, size_t(whiteList ? m_ApprovedWords.size() : m_DeniedWords.size()));
for (size_t word : allowList ? m_ApprovedWords : m_DeniedWords) {
for (size_t word : whiteList ? m_ApprovedWords : m_DeniedWords) {
BinaryIO::BinaryWrite(file, word);
}
@@ -105,10 +105,10 @@ void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool allowLis
}
}
std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool allowList) {
std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList) {
if (gmLevel > eGameMasterLevel::FORUM_MODERATOR) return { }; //If anything but a forum mod, return true.
if (message.empty()) return { };
if (!allowList && m_DeniedWords.empty()) return { { 0, message.length() } };
if (!whiteList && m_DeniedWords.empty()) return { { 0, message.length() } };
std::stringstream sMessage(message);
std::string segment;
@@ -126,16 +126,16 @@ std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::
size_t hash = CalculateHash(segment);
if (std::find(m_UserUnapprovedWordCache.begin(), m_UserUnapprovedWordCache.end(), hash) != m_UserUnapprovedWordCache.end() && allowList) {
if (std::find(m_UserUnapprovedWordCache.begin(), m_UserUnapprovedWordCache.end(), hash) != m_UserUnapprovedWordCache.end() && whiteList) {
listOfBadSegments.emplace_back(position, originalSegment.length());
}
if (std::find(m_ApprovedWords.begin(), m_ApprovedWords.end(), hash) == m_ApprovedWords.end() && allowList) {
if (std::find(m_ApprovedWords.begin(), m_ApprovedWords.end(), hash) == m_ApprovedWords.end() && whiteList) {
m_UserUnapprovedWordCache.push_back(hash);
listOfBadSegments.emplace_back(position, originalSegment.length());
}
if (std::find(m_DeniedWords.begin(), m_DeniedWords.end(), hash) != m_DeniedWords.end() && !allowList) {
if (std::find(m_DeniedWords.begin(), m_DeniedWords.end(), hash) != m_DeniedWords.end() && !whiteList) {
m_UserUnapprovedWordCache.push_back(hash);
listOfBadSegments.emplace_back(position, originalSegment.length());
}

View File

@@ -21,10 +21,10 @@ public:
dChatFilter(const std::string& filepath, bool dontGenerateDCF);
~dChatFilter();
void ReadWordlistPlaintext(const std::string& filepath, bool allowList);
bool ReadWordlistDCF(const std::string& filepath, bool allowList);
void ExportWordlistToDCF(const std::string& filepath, bool allowList);
std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool allowList = true);
void ReadWordlistPlaintext(const std::string& filepath, bool whiteList);
bool ReadWordlistDCF(const std::string& filepath, bool whiteList);
void ExportWordlistToDCF(const std::string& filepath, bool whiteList);
std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList = true);
private:
bool m_DontGenerateDCF;

View File

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

View File

@@ -1,6 +1,6 @@
#include "ChatIgnoreList.h"
#include "PlayerContainer.h"
#include "eChatMessageType.h"
#include "eChatInternalMessageType.h"
#include "BitStreamUtils.h"
#include "Game.h"
#include "Logger.h"
@@ -13,7 +13,7 @@
// 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) {
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receivingPlayer);
//portion that will get routed:
@@ -59,7 +59,7 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
bitStream.Write(LUWString(ignoredPlayer.playerName, 36));
}
Game::server->Send(bitStream, packet->systemAddress, false);
Game::server->Send(&bitStream, packet->systemAddress, false);
}
void ChatIgnoreList::AddIgnore(Packet* packet) {
@@ -81,7 +81,7 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
inStream.IgnoreBytes(4); // ignore some garbage zeros idk
LUWString toIgnoreName;
LUWString toIgnoreName(33);
inStream.Read(toIgnoreName);
std::string toIgnoreStr = toIgnoreName.GetAsString();
@@ -131,7 +131,7 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
bitStream.Write(playerNameSend);
bitStream.Write(ignoredPlayerId);
Game::server->Send(bitStream, packet->systemAddress, false);
Game::server->Send(&bitStream, packet->systemAddress, false);
}
void ChatIgnoreList::RemoveIgnore(Packet* packet) {
@@ -147,7 +147,7 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
inStream.IgnoreBytes(4); // ignore some garbage zeros idk
LUWString removedIgnoreName;
LUWString removedIgnoreName(33);
inStream.Read(removedIgnoreName);
std::string removedIgnoreStr = removedIgnoreName.GetAsString();
@@ -167,5 +167,5 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
LUWString playerNameSend(removedIgnoreStr, 33);
bitStream.Write(playerNameSend);
Game::server->Send(bitStream, packet->systemAddress, false);
Game::server->Send(&bitStream, packet->systemAddress, false);
}

View File

@@ -1,5 +1,5 @@
#ifndef CHATIGNORELIST_H
#define CHATIGNORELIST_H
#ifndef __CHATIGNORELIST__H__
#define __CHATIGNORELIST__H__
struct Packet;
@@ -24,4 +24,4 @@ namespace ChatIgnoreList {
};
};
#endif //!CHATIGNORELIST_H
#endif //!__CHATIGNORELIST__H__

View File

@@ -2,6 +2,7 @@
#include "PlayerContainer.h"
#include "Database.h"
#include <vector>
#include "PacketUtils.h"
#include "BitStreamUtils.h"
#include "Game.h"
#include "dServer.h"
@@ -14,11 +15,9 @@
#include "eObjectBits.h"
#include "eConnectionType.h"
#include "eChatMessageType.h"
#include "eChatInternalMessageType.h"
#include "eClientMessageType.h"
#include "eGameMessageType.h"
#include "StringifiedEnum.h"
#include "eGameMasterLevel.h"
#include "ChatPackets.h"
void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
//Get from the packet which player we want to do something with:
@@ -60,7 +59,7 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
//Now, we need to send the friendlist to the server they came from:
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(playerID);
//portion that will get routed:
@@ -79,17 +78,22 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID requestorPlayerID;
LUWString LUplayerName;
char isBestFriendRequest{};
inStream.Read(requestorPlayerID);
inStream.IgnoreBytes(4);
inStream.Read(LUplayerName);
inStream.Read(isBestFriendRequest);
uint32_t spacing{};
inStream.Read(spacing);
std::string playerName = "";
uint16_t character;
bool noMoreLettersInName = false;
auto playerName = LUplayerName.GetAsString();
for (uint32_t j = 0; j < 33; j++) {
inStream.Read(character);
if (character == '\0') noMoreLettersInName = true;
if (!noMoreLettersInName) playerName.push_back(static_cast<char>(character));
}
char isBestFriendRequest{};
inStream.Read(isBestFriendRequest);
auto& requestor = Game::playerContainer.GetPlayerDataMutable(requestorPlayerID);
if (!requestor) {
@@ -97,9 +101,8 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
return;
}
// you cannot friend yourself
if (requestor.playerName == playerName) {
SendFriendResponse(requestor, requestor, eAddFriendResponseType::GENERALERROR);
SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN);
return;
};
@@ -138,13 +141,6 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
return;
}
// Prevent GM friend spam
// If the player we are trying to be friends with is not a civilian and we are a civilian, abort the process
if (requestee.gmLevel > eGameMasterLevel::CIVILIAN && requestor.gmLevel == eGameMasterLevel::CIVILIAN ) {
SendFriendResponse(requestor, requestee, eAddFriendResponseType::MYTHRAN);
return;
}
if (isBestFriendRequest) {
uint8_t oldBestFriendStatus{};
@@ -222,19 +218,15 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID;
eAddFriendResponseCode clientResponseCode;
LUWString friendName;
inStream.Read(playerID);
inStream.IgnoreBytes(4);
inStream.Read(clientResponseCode);
inStream.Read(friendName);
eAddFriendResponseCode clientResponseCode = static_cast<eAddFriendResponseCode>(packet->data[0x14]);
std::string friendName = PacketUtils::ReadString(0x15, packet, true);
//Now to try and find both of these:
auto& requestor = Game::playerContainer.GetPlayerDataMutable(playerID);
auto& requestee = Game::playerContainer.GetPlayerDataMutable(friendName.GetAsString());
auto& requestee = Game::playerContainer.GetPlayerDataMutable(friendName);
if (!requestor || !requestee) return;
eAddFriendResponseType serverResponseCode{};
@@ -296,11 +288,8 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID;
LUWString LUFriendName;
inStream.Read(playerID);
inStream.IgnoreBytes(4);
inStream.Read(LUFriendName);
auto friendName = LUFriendName.GetAsString();
std::string friendName = PacketUtils::ReadString(0x14, packet, true);
//we'll have to query the db here to find the user, since you can delete them while they're offline.
//First, we need to find their ID:
@@ -346,205 +335,123 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
SendRemoveFriend(goonB, goonAName, true);
}
void ChatPacketHandler::HandleGMLevelUpdate(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID;
inStream.Read(playerID);
auto& player = Game::playerContainer.GetPlayerData(playerID);
if (!player) return;
inStream.Read(player.gmLevel);
}
void ChatPacketHandler::HandleWho(Packet* packet) {
CINSTREAM_SKIP_HEADER;
FindPlayerRequest request;
request.Deserialize(inStream);
const auto& sender = Game::playerContainer.GetPlayerData(request.requestor);
if (!sender) return;
const auto& player = Game::playerContainer.GetPlayerData(request.playerName.GetAsString());
bool online = player;
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::WHO_RESPONSE);
bitStream.Write<uint8_t>(online);
bitStream.Write(player.zoneID.GetMapID());
bitStream.Write(player.zoneID.GetInstanceID());
bitStream.Write(player.zoneID.GetCloneID());
bitStream.Write(request.playerName);
SystemAddress sysAddr = sender.sysAddr;
SEND_PACKET;
}
void ChatPacketHandler::HandleShowAll(Packet* packet) {
CINSTREAM_SKIP_HEADER;
ShowAllRequest request;
request.Deserialize(inStream);
const auto& sender = Game::playerContainer.GetPlayerData(request.requestor);
if (!sender) return;
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SHOW_ALL_RESPONSE);
bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers);
bitStream.Write(Game::playerContainer.GetPlayerCount());
bitStream.Write(Game::playerContainer.GetSimCount());
bitStream.Write<uint8_t>(request.displayIndividualPlayers);
bitStream.Write<uint8_t>(request.displayZoneData);
if (request.displayZoneData || request.displayIndividualPlayers){
for (auto& [playerID, playerData ]: Game::playerContainer.GetAllPlayers()){
if (!playerData) continue;
bitStream.Write<uint8_t>(0); // structure packing
if (request.displayIndividualPlayers) bitStream.Write(LUWString(playerData.playerName));
if (request.displayZoneData) {
bitStream.Write(playerData.zoneID.GetMapID());
bitStream.Write(playerData.zoneID.GetInstanceID());
bitStream.Write(playerData.zoneID.GetCloneID());
}
}
}
SystemAddress sysAddr = sender.sysAddr;
SEND_PACKET;
}
// the structure the client uses to send this packet is shared in many chat messages
// that are sent to the server. Because of this, there are large gaps of unused data in chat messages
void ChatPacketHandler::HandleChatMessage(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID;
LWOOBJID playerID = LWOOBJID_EMPTY;
inStream.Read(playerID);
const auto& sender = Game::playerContainer.GetPlayerData(playerID);
if (!sender || sender.GetIsMuted()) return;
eChatChannel channel;
uint32_t size;
if (!sender) return;
inStream.IgnoreBytes(4);
if (sender.GetIsMuted()) return;
inStream.SetReadOffset(0x14 * 8);
uint8_t channel = 0;
inStream.Read(channel);
inStream.Read(size);
inStream.IgnoreBytes(77);
LUWString message(size);
inStream.Read(message);
std::string message = PacketUtils::ReadString(0x66, packet, true, 512);
LOG("Got a message from (%s) via [%s]: %s", sender.playerName.c_str(), StringifiedEnum::ToString(channel).data(), message.GetAsString().c_str());
LOG("Got a message from (%s) [%d]: %s", sender.playerName.c_str(), channel, message.c_str());
if (channel != 8) return;
switch (channel) {
case eChatChannel::TEAM: {
auto* team = Game::playerContainer.GetTeam(playerID);
if (team == nullptr) return;
for (const auto memberId : team->memberIDs) {
const auto& otherMember = Game::playerContainer.GetPlayerData(memberId);
if (!otherMember) return;
SendPrivateChatMessage(sender, otherMember, otherMember, message, eChatChannel::TEAM, eChatMessageResponseCode::SENT);
}
break;
}
default:
LOG("Unhandled Chat channel [%s]", StringifiedEnum::ToString(channel).data());
break;
}
}
// the structure the client uses to send this packet is shared in many chat messages
// that are sent to the server. Because of this, there are large gaps of unused data in chat messages
void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID;
inStream.Read(playerID);
const auto& sender = Game::playerContainer.GetPlayerData(playerID);
if (!sender || sender.GetIsMuted()) return;
eChatChannel channel;
uint32_t size;
LUWString LUReceiverName;
inStream.IgnoreBytes(4);
inStream.Read(channel);
if (channel != eChatChannel::PRIVATE_CHAT) LOG("WARNING: Received Private chat with the wrong channel!");
inStream.Read(size);
inStream.IgnoreBytes(77);
inStream.Read(LUReceiverName);
auto receiverName = LUReceiverName.GetAsString();
inStream.IgnoreBytes(2);
LUWString message(size);
inStream.Read(message);
LOG("Got a message from (%s) via [%s]: %s to %s", sender.playerName.c_str(), StringifiedEnum::ToString(channel).data(), message.GetAsString().c_str(), receiverName.c_str());
const auto& receiver = Game::playerContainer.GetPlayerData(receiverName);
if (!receiver) {
PlayerData otherPlayer;
otherPlayer.playerName = receiverName;
auto responseType = Database::Get()->GetCharacterInfo(receiverName)
? eChatMessageResponseCode::NOTONLINE
: eChatMessageResponseCode::GENERALERROR;
SendPrivateChatMessage(sender, otherPlayer, sender, message, eChatChannel::GENERAL, responseType);
return;
}
// Check to see if they are friends
// only freinds can whispr each other
for (const auto& fr : receiver.friends) {
if (fr.friendID == sender.playerID) {
//To the sender:
SendPrivateChatMessage(sender, receiver, sender, message, eChatChannel::PRIVATE_CHAT, eChatMessageResponseCode::SENT);
//To the receiver:
SendPrivateChatMessage(sender, receiver, receiver, message, eChatChannel::PRIVATE_CHAT, eChatMessageResponseCode::RECEIVEDNEWWHISPER);
return;
}
}
SendPrivateChatMessage(sender, receiver, sender, message, eChatChannel::GENERAL, eChatMessageResponseCode::NOTFRIENDS);
}
void ChatPacketHandler::SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
bitStream.Write(routeTo.playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(otherMember.playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
bitStream.Write(sender.playerID);
bitStream.Write(channel);
bitStream.Write<uint32_t>(0); // not used
bitStream.Write(otherMember.playerID);
bitStream.Write<uint8_t>(8);
bitStream.Write<unsigned int>(69);
bitStream.Write(LUWString(sender.playerName));
bitStream.Write(sender.playerID);
bitStream.Write<uint16_t>(0); // sourceID
bitStream.Write(sender.gmLevel);
bitStream.Write(LUWString(receiver.playerName));
bitStream.Write(receiver.gmLevel);
bitStream.Write(responseCode);
bitStream.Write(message);
bitStream.Write<uint16_t>(0);
bitStream.Write<uint8_t>(0); //not mythran nametag
bitStream.Write(LUWString(otherMember.playerName));
bitStream.Write<uint8_t>(0); //not mythran for receiver
bitStream.Write<uint8_t>(0); //teams?
bitStream.Write(LUWString(message, 512));
SystemAddress sysAddr = routeTo.sysAddr;
SystemAddress sysAddr = otherMember.sysAddr;
SEND_PACKET;
}
}
void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
LWOOBJID senderID = PacketUtils::ReadS64(0x08, packet);
std::string receiverName = PacketUtils::ReadString(0x66, packet, true);
std::string message = PacketUtils::ReadString(0xAA, packet, true, 512);
//Get the bois:
const auto& goonA = Game::playerContainer.GetPlayerData(senderID);
const auto& goonB = Game::playerContainer.GetPlayerData(receiverName);
if (!goonA || !goonB) return;
if (goonA.GetIsMuted()) return;
//To the sender:
{
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(goonA.playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
bitStream.Write(goonA.playerID);
bitStream.Write<uint8_t>(7);
bitStream.Write<unsigned int>(69);
bitStream.Write(LUWString(goonA.playerName));
bitStream.Write(goonA.playerID);
bitStream.Write<uint16_t>(0);
bitStream.Write<uint8_t>(0); //not mythran nametag
bitStream.Write(LUWString(goonB.playerName));
bitStream.Write<uint8_t>(0); //not mythran for receiver
bitStream.Write<uint8_t>(0); //success
bitStream.Write(LUWString(message, 512));
SystemAddress sysAddr = goonA.sysAddr;
SEND_PACKET;
}
//To the receiver:
{
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(goonB.playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
bitStream.Write(goonA.playerID);
bitStream.Write<uint8_t>(7);
bitStream.Write<unsigned int>(69);
bitStream.Write(LUWString(goonA.playerName));
bitStream.Write(goonA.playerID);
bitStream.Write<uint16_t>(0);
bitStream.Write<uint8_t>(0); //not mythran nametag
bitStream.Write(LUWString(goonB.playerName));
bitStream.Write<uint8_t>(0); //not mythran for receiver
bitStream.Write<uint8_t>(3); //new whisper
bitStream.Write(LUWString(message, 512));
SystemAddress sysAddr = goonB.sysAddr;
SEND_PACKET;
}
}
void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID;
LUWString invitedPlayer;
inStream.Read(playerID);
inStream.IgnoreBytes(4);
inStream.Read(invitedPlayer);
std::string invitedPlayer = PacketUtils::ReadString(0x14, packet, true);
const auto& player = Game::playerContainer.GetPlayerData(playerID);
@@ -556,7 +463,7 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
team = Game::playerContainer.CreateTeam(playerID);
}
const auto& other = Game::playerContainer.GetPlayerData(invitedPlayer.GetAsString());
const auto& other = Game::playerContainer.GetPlayerData(invitedPlayer);
if (!other) return;
@@ -573,7 +480,7 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
SendTeamInvite(other, player);
LOG("Got team invite: %llu -> %s", playerID, invitedPlayer.GetAsString().c_str());
LOG("Got team invite: %llu -> %s", playerID, invitedPlayer.c_str());
}
void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) {
@@ -627,25 +534,21 @@ void ChatPacketHandler::HandleTeamLeave(Packet* packet) {
void ChatPacketHandler::HandleTeamKick(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID = LWOOBJID_EMPTY;
LUWString kickedPlayer;
inStream.Read(playerID);
inStream.IgnoreBytes(4);
inStream.Read(kickedPlayer);
std::string kickedPlayer = PacketUtils::ReadString(0x14, packet, true);
LOG("(%llu) kicking (%s) from team", playerID, kickedPlayer.GetAsString().c_str());
LOG("(%llu) kicking (%s) from team", playerID, kickedPlayer.c_str());
const auto& kicked = Game::playerContainer.GetPlayerData(kickedPlayer.GetAsString());
const auto& kicked = Game::playerContainer.GetPlayerData(kickedPlayer);
LWOOBJID kickedId = LWOOBJID_EMPTY;
if (kicked) {
kickedId = kicked.playerID;
} else {
kickedId = Game::playerContainer.GetId(kickedPlayer.string);
kickedId = Game::playerContainer.GetId(GeneralUtils::UTF8ToUTF16(kickedPlayer));
}
if (kickedId == LWOOBJID_EMPTY) return;
@@ -661,17 +564,14 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) {
void ChatPacketHandler::HandleTeamPromote(Packet* packet) {
CINSTREAM_SKIP_HEADER;
LWOOBJID playerID = LWOOBJID_EMPTY;
LUWString promotedPlayer;
inStream.Read(playerID);
inStream.IgnoreBytes(4);
inStream.Read(promotedPlayer);
LOG("(%llu) promoting (%s) to team leader", playerID, promotedPlayer.GetAsString().c_str());
std::string promotedPlayer = PacketUtils::ReadString(0x14, packet, true);
const auto& promoted = Game::playerContainer.GetPlayerData(promotedPlayer.GetAsString());
LOG("(%llu) promoting (%s) to team leader", playerID, promotedPlayer.c_str());
const auto& promoted = Game::playerContainer.GetPlayerData(promotedPlayer);
if (!promoted) return;
@@ -757,7 +657,7 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) {
void ChatPacketHandler::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -772,7 +672,7 @@ 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) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -799,7 +699,7 @@ 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) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -824,7 +724,7 @@ void ChatPacketHandler::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64L
void ChatPacketHandler::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -841,7 +741,7 @@ 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) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -870,7 +770,7 @@ 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) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -896,7 +796,7 @@ void ChatPacketHandler::SendTeamRemovePlayer(const PlayerData& receiver, bool bD
void ChatPacketHandler::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -930,7 +830,7 @@ void ChatPacketHandler::SendFriendUpdate(const PlayerData& friendData, const Pla
[bool] - is FTP*/
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(friendData.playerID);
//portion that will get routed:
@@ -967,7 +867,7 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
}
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:
@@ -981,7 +881,7 @@ 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) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
// Portion that will get routed:
@@ -1004,7 +904,7 @@ void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const Pla
void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver.playerID);
//portion that will get routed:

View File

@@ -7,55 +7,14 @@ struct PlayerData;
enum class eAddFriendResponseType : uint8_t;
enum class eChatChannel : uint8_t {
SYSTEMNOTIFY = 0,
SYSTEMWARNING,
SYSTEMERROR,
BROADCAST,
LOCAL,
LOCALNOANIM,
EMOTE,
PRIVATE_CHAT,
TEAM,
TEAMLOCAL,
GUILD,
GUILDNOTIFY,
PROPERTY,
ADMIN,
COMBATDAMAGE,
COMBATHEALING,
COMBATLOOT,
COMBATEXP,
COMBATDEATH,
GENERAL,
TRADE,
LFG,
USER
};
enum class eChatMessageResponseCode : uint8_t {
SENT = 0,
NOTONLINE,
GENERALERROR,
RECEIVEDNEWWHISPER,
NOTFRIENDS,
SENDERFREETRIAL,
RECEIVERFREETRIAL,
};
namespace ChatPacketHandler {
void HandleFriendlistRequest(Packet* packet);
void HandleFriendRequest(Packet* packet);
void HandleFriendResponse(Packet* packet);
void HandleRemoveFriend(Packet* packet);
void HandleGMLevelUpdate(Packet* packet);
void HandleWho(Packet* packet);
void HandleShowAll(Packet* packet);
void HandleChatMessage(Packet* packet);
void HandlePrivateChatMessage(Packet* packet);
void SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode);
void HandleTeamInvite(Packet* packet);
void HandleTeamInviteResponse(Packet* packet);

View File

@@ -17,9 +17,9 @@
#include "PlayerContainer.h"
#include "ChatPacketHandler.h"
#include "eChatMessageType.h"
#include "eChatInternalMessageType.h"
#include "eWorldMessageType.h"
#include "ChatIgnoreList.h"
#include "StringifiedEnum.h"
#include "Game.h"
#include "Server.h"
@@ -98,15 +98,18 @@ int main(int argc, char** argv) {
masterPort = masterInfo->port;
}
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999;
uint32_t ourPort = 1501;
std::string ourIP = "localhost";
const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999);
const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("chat_server_port")).value_or(2005);
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
GeneralUtils::TryParse(Game::config->GetValue("chat_server_port"), ourPort);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal);
const bool dontGenerateDCF = GeneralUtils::TryParse<bool>(Game::config->GetValue("dont_generate_dcf")).value_or(false);
bool dontGenerateDCF = false;
GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf"), dontGenerateDCF);
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF);
Game::randomEngine = std::mt19937(time(0));
@@ -179,32 +182,48 @@ int main(int argc, char** argv) {
}
void HandlePacket(Packet* packet) {
if (packet->length < 1) return;
if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) {
LOG("A server has disconnected, erasing their connected players from the list.");
} else if (packet->data[0] == ID_NEW_INCOMING_CONNECTION) {
}
if (packet->data[0] == ID_NEW_INCOMING_CONNECTION) {
LOG("A server is connecting, awaiting user list.");
} else if (packet->length < 4 || packet->data[0] != ID_USER_PACKET_ENUM) return; // Nothing left to process or not the right packet type
}
CINSTREAM;
inStream.SetReadOffset(BYTES_TO_BITS(1));
if (packet->length < 4) return; // Nothing left to process. Need 4 bytes to continue.
eConnectionType connection;
eChatMessageType chatMessageID;
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::CHAT_INTERNAL) {
switch (static_cast<eChatInternalMessageType>(packet->data[3])) {
case eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION:
Game::playerContainer.InsertPlayer(packet);
break;
inStream.Read(connection);
if (connection != eConnectionType::CHAT) return;
inStream.Read(chatMessageID);
case eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION:
Game::playerContainer.RemovePlayer(packet);
break;
switch (chatMessageID) {
case eChatMessageType::GM_MUTE:
case eChatInternalMessageType::MUTE_UPDATE:
Game::playerContainer.MuteUpdate(packet);
break;
case eChatMessageType::CREATE_TEAM:
case eChatInternalMessageType::CREATE_TEAM:
Game::playerContainer.CreateTeamServer(packet);
break;
case eChatInternalMessageType::ANNOUNCEMENT: {
//we just forward this packet to every connected server
CINSTREAM;
Game::server->Send(&inStream, packet->systemAddress, true); //send to everyone except origin
break;
}
default:
LOG("Unknown CHAT_INTERNAL id: %i", int(packet->data[3]));
}
}
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::CHAT) {
switch (static_cast<eChatMessageType>(packet->data[3])) {
case eChatMessageType::GET_FRIENDS_LIST:
ChatPacketHandler::HandleFriendlistRequest(packet);
break;
@@ -274,73 +293,21 @@ void HandlePacket(Packet* packet) {
case eChatMessageType::TEAM_SET_LOOT:
ChatPacketHandler::HandleTeamLootOption(packet);
break;
case eChatMessageType::GMLEVEL_UPDATE:
ChatPacketHandler::HandleGMLevelUpdate(packet);
break;
case eChatMessageType::LOGIN_SESSION_NOTIFY:
Game::playerContainer.InsertPlayer(packet);
break;
case eChatMessageType::GM_ANNOUNCE:{
// we just forward this packet to every connected server
inStream.ResetReadPointer();
Game::server->Send(inStream, packet->systemAddress, true); // send to everyone except origin
}
break;
case eChatMessageType::UNEXPECTED_DISCONNECT:
Game::playerContainer.RemovePlayer(packet);
break;
case eChatMessageType::WHO:
ChatPacketHandler::HandleWho(packet);
break;
case eChatMessageType::SHOW_ALL:
ChatPacketHandler::HandleShowAll(packet);
break;
case eChatMessageType::USER_CHANNEL_CHAT_MESSAGE:
case eChatMessageType::WORLD_DISCONNECT_REQUEST:
case eChatMessageType::WORLD_PROXIMITY_RESPONSE:
case eChatMessageType::WORLD_PARCEL_RESPONSE:
case eChatMessageType::TEAM_MISSED_INVITE_CHECK:
case eChatMessageType::GUILD_CREATE:
case eChatMessageType::GUILD_INVITE:
case eChatMessageType::GUILD_INVITE_RESPONSE:
case eChatMessageType::GUILD_LEAVE:
case eChatMessageType::GUILD_KICK:
case eChatMessageType::GUILD_GET_STATUS:
case eChatMessageType::GUILD_GET_ALL:
case eChatMessageType::BLUEPRINT_MODERATED:
case eChatMessageType::BLUEPRINT_MODEL_READY:
case eChatMessageType::PROPERTY_READY_FOR_APPROVAL:
case eChatMessageType::PROPERTY_MODERATION_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED_REPORT:
case eChatMessageType::MAIL:
case eChatMessageType::WORLD_INSTANCE_LOCATION_REQUEST:
case eChatMessageType::REPUTATION_UPDATE:
case eChatMessageType::SEND_CANNED_TEXT:
case eChatMessageType::CHARACTER_NAME_CHANGE_REQUEST:
case eChatMessageType::CSR_REQUEST:
case eChatMessageType::CSR_REPLY:
case eChatMessageType::GM_KICK:
case eChatMessageType::WORLD_ROUTE_PACKET:
case eChatMessageType::GET_ZONE_POPULATIONS:
case eChatMessageType::REQUEST_MINIMUM_CHAT_MODE:
case eChatMessageType::MATCH_REQUEST:
case eChatMessageType::UGCMANIFEST_REPORT_MISSING_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_BLUEPRINT:
case eChatMessageType::UGCC_REQUEST:
case eChatMessageType::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE:
case eChatMessageType::ACHIEVEMENT_NOTIFY:
case eChatMessageType::GM_CLOSE_PRIVATE_CHAT_WINDOW:
case eChatMessageType::PLAYER_READY:
case eChatMessageType::GET_DONATION_TOTAL:
case eChatMessageType::UPDATE_DONATION:
case eChatMessageType::PRG_CSR_COMMAND:
case eChatMessageType::HEARTBEAT_REQUEST_FROM_WORLD:
case eChatMessageType::UPDATE_FREE_TRIAL_STATUS:
LOG("Unhandled CHAT Message id: %s (%i)", StringifiedEnum::ToString(chatMessageID).data(), chatMessageID);
break;
default:
LOG("Unknown CHAT Message id: %i", chatMessageID);
LOG("Unknown CHAT id: %i", int(packet->data[3]));
}
}
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::WORLD) {
switch (static_cast<eWorldMessageType>(packet->data[3])) {
case eWorldMessageType::ROUTE_PACKET: {
LOG("Routing packet from world");
break;
}
default:
LOG("Unknown World id: %i", int(packet->data[3]));
}
}
}

View File

@@ -9,15 +9,17 @@
#include "BitStreamUtils.h"
#include "Database.h"
#include "eConnectionType.h"
#include "eChatInternalMessageType.h"
#include "ChatPackets.h"
#include "dConfig.h"
#include "eChatMessageType.h"
void PlayerContainer::Initialize() {
m_MaxNumberOfBestFriends =
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends")).value_or(m_MaxNumberOfBestFriends);
m_MaxNumberOfFriends =
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends")).value_or(m_MaxNumberOfFriends);
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends"), m_MaxNumberOfBestFriends);
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends"), m_MaxNumberOfFriends);
}
PlayerContainer::~PlayerContainer() {
m_Players.clear();
}
TeamData::TeamData() {
@@ -36,23 +38,18 @@ void PlayerContainer::InsertPlayer(Packet* packet) {
data.playerID = playerId;
uint32_t len;
if (!inStream.Read<uint32_t>(len)) return;
inStream.Read<uint32_t>(len);
if (len > 33) {
LOG("Received a really long player name, probably a fake packet %i.", len);
return;
for (int i = 0; i < len; i++) {
char character; inStream.Read<char>(character);
data.playerName += character;
}
data.playerName.resize(len);
inStream.ReadAlignedBytes(reinterpret_cast<unsigned char*>(data.playerName.data()), len);
if (!inStream.Read(data.zoneID)) return;
if (!inStream.Read(data.muteExpire)) return;
if (!inStream.Read(data.gmLevel)) return;
inStream.Read(data.zoneID);
inStream.Read(data.muteExpire);
data.sysAddr = packet->systemAddress;
m_Names[data.playerID] = GeneralUtils::UTF8ToUTF16(data.playerName);
m_PlayerCount++;
LOG("Added user: %s (%llu), zone: %i", data.playerName.c_str(), data.playerID, data.zoneID.GetMapID());
@@ -91,7 +88,6 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
}
}
m_PlayerCount--;
LOG("Removed user: %llu", playerID);
m_Players.erase(playerID);
@@ -125,11 +121,6 @@ void PlayerContainer::CreateTeamServer(Packet* packet) {
size_t membersSize = 0;
inStream.Read(membersSize);
if (membersSize >= 4) {
LOG("Tried to create a team with more than 4 players");
return;
}
std::vector<LWOOBJID> members;
members.reserve(membersSize);
@@ -155,12 +146,12 @@ void PlayerContainer::CreateTeamServer(Packet* packet) {
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GM_MUTE);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE);
bitStream.Write(player);
bitStream.Write(time);
Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
}
TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members) {
@@ -362,7 +353,7 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) {
void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::TEAM_GET_STATUS);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::TEAM_UPDATE);
bitStream.Write(team->teamID);
bitStream.Write(deleteTeam);
@@ -375,7 +366,7 @@ void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
}
}
Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
}
std::u16string PlayerContainer::GetName(LWOOBJID playerID) {
@@ -400,7 +391,7 @@ LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) {
}
PlayerData& PlayerContainer::GetPlayerDataMutable(const LWOOBJID& playerID) {
return m_Players.contains(playerID) ? m_Players[playerID] : m_Players[LWOOBJID_EMPTY];
return m_Players[playerID];
}
PlayerData& PlayerContainer::GetPlayerDataMutable(const std::string& playerName) {

View File

@@ -7,10 +7,8 @@
#include "dServer.h"
#include <unordered_map>
enum class eGameMasterLevel : uint8_t;
struct IgnoreData {
IgnoreData(const std::string& name, const LWOOBJID& id) : playerName{ name }, playerId{ id } {}
IgnoreData(const std::string& name, const LWOOBJID& id) : playerName(name), playerId(id) {}
inline bool operator==(const std::string& other) const noexcept {
return playerName == other;
}
@@ -44,8 +42,6 @@ struct PlayerData {
std::string playerName;
std::vector<FriendData> friends;
std::vector<IgnoreData> ignoredPlayers;
eGameMasterLevel gmLevel = static_cast<eGameMasterLevel>(0); // CIVILLIAN
bool isFTP = false;
};
struct TeamData {
@@ -60,6 +56,8 @@ struct TeamData {
class PlayerContainer {
public:
~PlayerContainer();
void Initialize();
void InsertPlayer(Packet* packet);
void RemovePlayer(Packet* packet);
@@ -71,9 +69,6 @@ public:
const PlayerData& GetPlayerData(const std::string& playerName);
PlayerData& GetPlayerDataMutable(const LWOOBJID& playerID);
PlayerData& GetPlayerDataMutable(const std::string& playerName);
uint32_t GetPlayerCount() { return m_PlayerCount; };
uint32_t GetSimCount() { return m_SimCount; };
const std::map<LWOOBJID, PlayerData>& GetAllPlayers() { return m_Players; };
TeamData* CreateLocalTeam(std::vector<LWOOBJID> members);
TeamData* CreateTeam(LWOOBJID leader, bool local = false);
@@ -96,7 +91,5 @@ private:
std::unordered_map<LWOOBJID, std::u16string> m_Names;
uint32_t m_MaxNumberOfBestFriends = 5;
uint32_t m_MaxNumberOfFriends = 50;
uint32_t m_PlayerCount = 0;
uint32_t m_SimCount = 0;
};

View File

@@ -9,11 +9,12 @@
* AMF3 Deserializer written by EmosewaMC
*/
AMFBaseValue* AMFDeserialize::Read(RakNet::BitStream& inStream) {
AMFBaseValue* AMFDeserialize::Read(RakNet::BitStream* inStream) {
if (!inStream) return nullptr;
AMFBaseValue* returnValue = nullptr;
// Read in the value type from the bitStream
eAmf marker;
inStream.Read(marker);
inStream->Read(marker);
// Based on the typing, create the value associated with that and return the base value class
switch (marker) {
case eAmf::Undefined: {
@@ -78,13 +79,13 @@ AMFBaseValue* AMFDeserialize::Read(RakNet::BitStream& inStream) {
return returnValue;
}
uint32_t AMFDeserialize::ReadU29(RakNet::BitStream& inStream) {
uint32_t AMFDeserialize::ReadU29(RakNet::BitStream* inStream) {
bool byteFlag = true;
uint32_t actualNumber{};
uint8_t numberOfBytesRead{};
while (byteFlag && numberOfBytesRead < 4) {
uint8_t byte{};
inStream.Read(byte);
inStream->Read(byte);
// Parse the byte
if (numberOfBytesRead < 3) {
byteFlag = byte & static_cast<uint8_t>(1 << 7);
@@ -100,7 +101,7 @@ uint32_t AMFDeserialize::ReadU29(RakNet::BitStream& inStream) {
return actualNumber;
}
const std::string AMFDeserialize::ReadString(RakNet::BitStream& inStream) {
const std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) {
auto length = ReadU29(inStream);
// Check if this is a reference
bool isReference = length % 2 == 1;
@@ -108,7 +109,7 @@ const std::string AMFDeserialize::ReadString(RakNet::BitStream& inStream) {
length = length >> 1;
if (isReference) {
std::string value(length, 0);
inStream.Read(&value[0], length);
inStream->Read(&value[0], length);
// Empty strings are never sent by reference
if (!value.empty()) accessedElements.push_back(value);
return value;
@@ -118,20 +119,20 @@ const std::string AMFDeserialize::ReadString(RakNet::BitStream& inStream) {
}
}
AMFBaseValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream& inStream) {
AMFBaseValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) {
double value;
inStream.Read<double>(value);
inStream->Read<double>(value);
return new AMFDoubleValue(value);
}
AMFBaseValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream& inStream) {
AMFBaseValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) {
auto arrayValue = new AMFArrayValue();
// Read size of dense array
const auto sizeOfDenseArray = (ReadU29(inStream) >> 1);
auto sizeOfDenseArray = (ReadU29(inStream) >> 1);
// Then read associative portion
while (true) {
const auto key = ReadString(inStream);
auto key = ReadString(inStream);
// No more associative values when we encounter an empty string key
if (key.size() == 0) break;
arrayValue->Insert(key, Read(inStream));
@@ -143,10 +144,10 @@ AMFBaseValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream& inStream) {
return arrayValue;
}
AMFBaseValue* AMFDeserialize::ReadAmfString(RakNet::BitStream& inStream) {
AMFBaseValue* AMFDeserialize::ReadAmfString(RakNet::BitStream* inStream) {
return new AMFStringValue(ReadString(inStream));
}
AMFBaseValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream& inStream) {
AMFBaseValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream* inStream) {
return new AMFIntValue(ReadU29(inStream));
}

View File

@@ -15,7 +15,7 @@ public:
* @param inStream inStream to read value from.
* @return Returns an AMFValue with all the information from the bitStream in it.
*/
AMFBaseValue* Read(RakNet::BitStream& inStream);
AMFBaseValue* Read(RakNet::BitStream* inStream);
private:
/**
* @brief Private method to read a U29 integer from a bitstream
@@ -23,7 +23,7 @@ private:
* @param inStream bitstream to read data from
* @return The number as an unsigned 29 bit integer
*/
static uint32_t ReadU29(RakNet::BitStream& inStream);
uint32_t ReadU29(RakNet::BitStream* inStream);
/**
* @brief Reads a string from a bitstream
@@ -31,7 +31,7 @@ private:
* @param inStream bitStream to read data from
* @return The read string
*/
const std::string ReadString(RakNet::BitStream& inStream);
const std::string ReadString(RakNet::BitStream* inStream);
/**
* @brief Read an AMFDouble value from a bitStream
@@ -39,7 +39,7 @@ private:
* @param inStream bitStream to read data from
* @return Double value represented as an AMFValue
*/
AMFBaseValue* ReadAmfDouble(RakNet::BitStream& inStream);
AMFBaseValue* ReadAmfDouble(RakNet::BitStream* inStream);
/**
* @brief Read an AMFArray from a bitStream
@@ -47,7 +47,7 @@ private:
* @param inStream bitStream to read data from
* @return Array value represented as an AMFValue
*/
AMFBaseValue* ReadAmfArray(RakNet::BitStream& inStream);
AMFBaseValue* ReadAmfArray(RakNet::BitStream* inStream);
/**
* @brief Read an AMFString from a bitStream
@@ -55,7 +55,7 @@ private:
* @param inStream bitStream to read data from
* @return String value represented as an AMFValue
*/
AMFBaseValue* ReadAmfString(RakNet::BitStream& inStream);
AMFBaseValue* ReadAmfString(RakNet::BitStream* inStream);
/**
* @brief Read an AMFInteger from a bitStream
@@ -63,7 +63,7 @@ private:
* @param inStream bitStream to read data from
* @return Integer value represented as an AMFValue
*/
AMFBaseValue* ReadAmfInteger(RakNet::BitStream& inStream);
AMFBaseValue* ReadAmfInteger(RakNet::BitStream* inStream);
/**
* List of strings read so far saved to be read by reference.

View File

@@ -1,5 +1,5 @@
#ifndef AMF3_H
#define AMF3_H
#ifndef __AMF3__H__
#define __AMF3__H__
#include "dCommonVars.h"
#include "Logger.h"
@@ -31,70 +31,54 @@ enum class eAmf : uint8_t {
class AMFBaseValue {
public:
[[nodiscard]] constexpr virtual eAmf GetValueType() const noexcept { return eAmf::Undefined; }
constexpr AMFBaseValue() noexcept = default;
constexpr virtual ~AMFBaseValue() noexcept = default;
virtual eAmf GetValueType() { return eAmf::Undefined; };
AMFBaseValue() {};
virtual ~AMFBaseValue() {};
};
// AMFValue template class instantiations
template <typename ValueType>
template<typename ValueType>
class AMFValue : public AMFBaseValue {
public:
AMFValue() = default;
AMFValue(const ValueType value) : m_Data{ value } {}
AMFValue() {};
AMFValue(ValueType value) { SetValue(value); };
virtual ~AMFValue() override {};
virtual ~AMFValue() override = default;
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override;
[[nodiscard]] const ValueType& GetValue() const { return m_Data; }
void SetValue(const ValueType value) { m_Data = value; }
eAmf GetValueType() override { return eAmf::Undefined; };
const ValueType& GetValue() { return data; };
void SetValue(ValueType value) { data = value; };
protected:
ValueType m_Data;
ValueType data;
};
// Explicit template class instantiations
template class AMFValue<std::nullptr_t>;
template class AMFValue<bool>;
template class AMFValue<int32_t>;
template class AMFValue<uint32_t>;
template class AMFValue<std::string>;
template class AMFValue<double>;
// AMFValue template class member function instantiations
template <> [[nodiscard]] constexpr eAmf AMFValue<std::nullptr_t>::GetValueType() const noexcept { return eAmf::Null; }
template <> [[nodiscard]] constexpr eAmf AMFValue<bool>::GetValueType() const noexcept { return m_Data ? eAmf::True : eAmf::False; }
template <> [[nodiscard]] constexpr eAmf AMFValue<int32_t>::GetValueType() const noexcept { return eAmf::Integer; }
template <> [[nodiscard]] constexpr eAmf AMFValue<uint32_t>::GetValueType() const noexcept { return eAmf::Integer; }
template <> [[nodiscard]] constexpr eAmf AMFValue<std::string>::GetValueType() const noexcept { return eAmf::String; }
template <> [[nodiscard]] constexpr eAmf AMFValue<double>::GetValueType() const noexcept { return eAmf::Double; }
template <typename ValueType>
[[nodiscard]] constexpr eAmf AMFValue<ValueType>::GetValueType() const noexcept { return eAmf::Undefined; }
// As a string this is much easier to write and read from a BitStream.
template <>
template<>
class AMFValue<const char*> : public AMFBaseValue {
public:
AMFValue() = default;
AMFValue(const char* value) { m_Data = value; }
virtual ~AMFValue() override = default;
AMFValue() {};
AMFValue(const char* value) { SetValue(std::string(value)); };
virtual ~AMFValue() override {};
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::String; }
eAmf GetValueType() override { return eAmf::String; };
[[nodiscard]] const std::string& GetValue() const { return m_Data; }
void SetValue(const std::string& value) { m_Data = value; }
const std::string& GetValue() { return data; };
void SetValue(std::string value) { data = value; };
protected:
std::string m_Data;
std::string data;
};
using AMFNullValue = AMFValue<std::nullptr_t>;
using AMFBoolValue = AMFValue<bool>;
using AMFIntValue = AMFValue<int32_t>;
using AMFStringValue = AMFValue<std::string>;
using AMFDoubleValue = AMFValue<double>;
typedef AMFValue<std::nullptr_t> AMFNullValue;
typedef AMFValue<bool> AMFBoolValue;
typedef AMFValue<int32_t> AMFIntValue;
typedef AMFValue<std::string> AMFStringValue;
typedef AMFValue<double> AMFDoubleValue;
template<> inline eAmf AMFValue<std::nullptr_t>::GetValueType() { return eAmf::Null; };
template<> inline eAmf AMFValue<bool>::GetValueType() { return this->data ? eAmf::True : eAmf::False; };
template<> inline eAmf AMFValue<int32_t>::GetValueType() { return eAmf::Integer; };
template<> inline eAmf AMFValue<uint32_t>::GetValueType() { return eAmf::Integer; };
template<> inline eAmf AMFValue<std::string>::GetValueType() { return eAmf::String; };
template<> inline eAmf AMFValue<double>::GetValueType() { return eAmf::Double; };
/**
* The AMFArrayValue object holds 2 types of lists:
@@ -105,14 +89,15 @@ using AMFDoubleValue = AMFValue<double>;
* and are not to be deleted by a caller.
*/
class AMFArrayValue : public AMFBaseValue {
using AMFAssociative = std::unordered_map<std::string, AMFBaseValue*>;
using AMFDense = std::vector<AMFBaseValue*>;
typedef std::unordered_map<std::string, AMFBaseValue*> AMFAssociative;
typedef std::vector<AMFBaseValue*> AMFDense;
public:
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::Array; }
eAmf GetValueType() override { return eAmf::Array; };
~AMFArrayValue() override {
for (const auto* valueToDelete : GetDense()) {
for (auto valueToDelete : GetDense()) {
if (valueToDelete) {
delete valueToDelete;
valueToDelete = nullptr;
@@ -124,17 +109,17 @@ public:
valueToDelete.second = nullptr;
}
}
}
};
/**
* Returns the Associative portion of the object
*/
[[nodiscard]] inline const AMFAssociative& GetAssociative() const noexcept { return m_Associative; }
inline AMFAssociative& GetAssociative() { return this->associative; };
/**
* Returns the dense portion of the object
*/
[[nodiscard]] inline const AMFDense& GetDense() const noexcept { return m_Dense; }
inline AMFDense& GetDense() { return this->dense; };
/**
* Inserts an AMFValue into the associative portion with the given key.
@@ -150,48 +135,48 @@ public:
* @return The inserted element if the type matched,
* or nullptr if a key existed and was not the same type
*/
template <typename ValueType>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, const ValueType value) {
const auto element = m_Associative.find(key);
template<typename ValueType>
std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, ValueType value) {
auto element = associative.find(key);
AMFValue<ValueType>* val = nullptr;
bool found = true;
if (element == m_Associative.cend()) {
if (element == associative.end()) {
val = new AMFValue<ValueType>(value);
m_Associative.emplace(key, val);
associative.insert(std::make_pair(key, val));
} else {
val = dynamic_cast<AMFValue<ValueType>*>(element->second);
found = false;
}
return std::make_pair(val, found);
}
};
// Associates an array with a string key
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
const auto element = m_Associative.find(key);
std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
auto element = associative.find(key);
AMFArrayValue* val = nullptr;
bool found = true;
if (element == m_Associative.cend()) {
if (element == associative.end()) {
val = new AMFArrayValue();
m_Associative.emplace(key, val);
associative.insert(std::make_pair(key, val));
} else {
val = dynamic_cast<AMFArrayValue*>(element->second);
found = false;
}
return std::make_pair(val, found);
}
};
// Associates an array with an integer key
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const size_t index) {
std::pair<AMFBaseValue*, bool> Insert(const uint32_t& index) {
AMFArrayValue* val = nullptr;
bool inserted = false;
if (index >= m_Dense.size()) {
m_Dense.resize(index + 1);
if (index >= dense.size()) {
dense.resize(index + 1);
val = new AMFArrayValue();
m_Dense.at(index) = val;
dense.at(index) = val;
inserted = true;
}
return std::make_pair(dynamic_cast<AMFArrayValue*>(m_Dense.at(index)), inserted);
}
return std::make_pair(dynamic_cast<AMFArrayValue*>(dense.at(index)), inserted);
};
/**
* @brief Inserts an AMFValue into the AMFArray key'd by index.
@@ -203,18 +188,18 @@ public:
* @return The inserted element, or nullptr if the type did not match
* what was at the index.
*/
template <typename ValueType>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const size_t index, const ValueType value) {
template<typename ValueType>
std::pair<AMFValue<ValueType>*, bool> Insert(const uint32_t& index, ValueType value) {
AMFValue<ValueType>* val = nullptr;
bool inserted = false;
if (index >= m_Dense.size()) {
m_Dense.resize(index + 1);
if (index >= this->dense.size()) {
this->dense.resize(index + 1);
val = new AMFValue<ValueType>(value);
m_Dense.at(index) = val;
this->dense.at(index) = val;
inserted = true;
}
return std::make_pair(dynamic_cast<AMFValue<ValueType>*>(m_Dense.at(index)), inserted);
}
return std::make_pair(dynamic_cast<AMFValue<ValueType>*>(this->dense.at(index)), inserted);
};
/**
* Inserts an AMFValue into the associative portion with the given key.
@@ -225,15 +210,15 @@ public:
* @param key The key to associate with the value
* @param value The value to insert
*/
void Insert(const std::string& key, AMFBaseValue* const value) {
const auto element = m_Associative.find(key);
if (element != m_Associative.cend() && element->second) {
void Insert(const std::string& key, AMFBaseValue* value) {
auto element = associative.find(key);
if (element != associative.end() && element->second) {
delete element->second;
element->second = value;
} else {
m_Associative.emplace(key, value);
}
associative.insert(std::make_pair(key, value));
}
};
/**
* Inserts an AMFValue into the associative portion with the given index.
@@ -244,15 +229,15 @@ public:
* @param key The key to associate with the value
* @param value The value to insert
*/
void Insert(const size_t index, AMFBaseValue* const value) {
if (index < m_Dense.size()) {
const AMFDense::const_iterator itr = m_Dense.cbegin() + index;
if (*itr) delete m_Dense.at(index);
void Insert(const uint32_t index, AMFBaseValue* value) {
if (index < dense.size()) {
AMFDense::iterator itr = dense.begin() + index;
if (*itr) delete dense.at(index);
} else {
m_Dense.resize(index + 1);
}
m_Dense.at(index) = value;
dense.resize(index + 1);
}
dense.at(index) = value;
};
/**
* Pushes an AMFValue into the back of the dense portion.
@@ -264,10 +249,10 @@ public:
*
* @return The inserted pointer, or nullptr should the key already be in use.
*/
template <typename ValueType>
[[maybe_unused]] inline AMFValue<ValueType>* Push(const ValueType value) {
return Insert(m_Dense.size(), value).first;
}
template<typename ValueType>
inline AMFValue<ValueType>* Push(ValueType value) {
return Insert(this->dense.size(), value).first;
};
/**
* Removes the key from the associative portion
@@ -276,49 +261,52 @@ public:
*
* @param key The key to remove from the associative portion
*/
void Remove(const std::string& key, const bool deleteValue = true) {
const AMFAssociative::const_iterator it = m_Associative.find(key);
if (it != m_Associative.cend()) {
void Remove(const std::string& key, bool deleteValue = true) {
AMFAssociative::iterator it = this->associative.find(key);
if (it != this->associative.end()) {
if (deleteValue) delete it->second;
m_Associative.erase(it);
this->associative.erase(it);
}
}
/**
* Pops the last element in the dense portion, deleting it in the process.
*/
void Remove(const size_t index) {
if (!m_Dense.empty() && index < m_Dense.size()) {
const auto itr = m_Dense.cbegin() + index;
void Remove(const uint32_t index) {
if (!this->dense.empty() && index < this->dense.size()) {
auto itr = this->dense.begin() + index;
if (*itr) delete (*itr);
m_Dense.erase(itr);
this->dense.erase(itr);
}
}
void Pop() {
if (!m_Dense.empty()) Remove(m_Dense.size() - 1);
if (!this->dense.empty()) Remove(this->dense.size() - 1);
}
[[nodiscard]] AMFArrayValue* GetArray(const std::string& key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ? dynamic_cast<AMFArrayValue*>(it->second) : nullptr;
AMFArrayValue* GetArray(const std::string& key) {
AMFAssociative::const_iterator it = this->associative.find(key);
if (it != this->associative.end()) {
return dynamic_cast<AMFArrayValue*>(it->second);
}
return nullptr;
};
[[nodiscard]] AMFArrayValue* GetArray(const size_t index) const {
return index < m_Dense.size() ? dynamic_cast<AMFArrayValue*>(m_Dense.at(index)) : nullptr;
}
AMFArrayValue* GetArray(const uint32_t index) {
return index >= this->dense.size() ? nullptr : dynamic_cast<AMFArrayValue*>(this->dense.at(index));
};
[[maybe_unused]] inline AMFArrayValue* InsertArray(const std::string& key) {
inline AMFArrayValue* InsertArray(const std::string& key) {
return static_cast<AMFArrayValue*>(Insert(key).first);
}
};
[[maybe_unused]] inline AMFArrayValue* InsertArray(const size_t index) {
inline AMFArrayValue* InsertArray(const uint32_t index) {
return static_cast<AMFArrayValue*>(Insert(index).first);
}
};
[[maybe_unused]] inline AMFArrayValue* PushArray() {
return static_cast<AMFArrayValue*>(Insert(m_Dense.size()).first);
}
inline AMFArrayValue* PushArray() {
return static_cast<AMFArrayValue*>(Insert(this->dense.size()).first);
};
/**
* Gets an AMFValue by the key from the associative portion and converts it
@@ -330,18 +318,18 @@ public:
* @return The AMFValue
*/
template <typename AmfType>
[[nodiscard]] AMFValue<AmfType>* Get(const std::string& key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ?
AMFValue<AmfType>* Get(const std::string& key) const {
AMFAssociative::const_iterator it = this->associative.find(key);
return it != this->associative.end() ?
dynamic_cast<AMFValue<AmfType>*>(it->second) :
nullptr;
}
};
// Get from the array but dont cast it
[[nodiscard]] AMFBaseValue* Get(const std::string& key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ? it->second : nullptr;
}
AMFBaseValue* Get(const std::string& key) const {
AMFAssociative::const_iterator it = this->associative.find(key);
return it != this->associative.end() ? it->second : nullptr;
};
/**
* @brief Get an AMFValue object at a position in the dense portion.
@@ -353,28 +341,27 @@ public:
* @return The casted object, or nullptr.
*/
template <typename AmfType>
[[nodiscard]] AMFValue<AmfType>* Get(const size_t index) const {
return index < m_Dense.size() ?
dynamic_cast<AMFValue<AmfType>*>(m_Dense.at(index)) :
AMFValue<AmfType>* Get(uint32_t index) const {
return index < this->dense.size() ?
dynamic_cast<AMFValue<AmfType>*>(this->dense.at(index)) :
nullptr;
}
};
// Get from the dense but dont cast it
[[nodiscard]] AMFBaseValue* Get(const size_t index) const {
return index < m_Dense.size() ? m_Dense.at(index) : nullptr;
}
AMFBaseValue* Get(const uint32_t index) const {
return index < this->dense.size() ? this->dense.at(index) : nullptr;
};
private:
/**
* The associative portion. These values are key'd with strings to an AMFValue.
*/
AMFAssociative m_Associative;
AMFAssociative associative;
/**
* The dense portion. These AMFValue's are stored one after
* another with the most recent addition being at the back.
*/
AMFDense m_Dense;
AMFDense dense;
};
#endif //!AMF3_H
#endif //!__AMF3__H__

View File

@@ -53,7 +53,7 @@ void RakNet::BitStream::Write<AMFBaseValue&>(AMFBaseValue& value) {
* A private function to write an value to a RakNet::BitStream
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteUInt29(RakNet::BitStream& bs, uint32_t v) {
void WriteUInt29(RakNet::BitStream* bs, uint32_t v) {
unsigned char b4 = static_cast<unsigned char>(v);
if (v < 0x00200000) {
b4 = b4 & 0x7F;
@@ -65,10 +65,10 @@ void WriteUInt29(RakNet::BitStream& bs, uint32_t v) {
unsigned char b2;
v = v >> 7;
b2 = static_cast<unsigned char>(v) | 0x80;
bs.Write(b2);
bs->Write(b2);
}
bs.Write(b3);
bs->Write(b3);
}
} else {
unsigned char b1;
@@ -82,19 +82,19 @@ void WriteUInt29(RakNet::BitStream& bs, uint32_t v) {
v = v >> 7;
b1 = static_cast<unsigned char>(v) | 0x80;
bs.Write(b1);
bs.Write(b2);
bs.Write(b3);
bs->Write(b1);
bs->Write(b2);
bs->Write(b3);
}
bs.Write(b4);
bs->Write(b4);
}
/**
* Writes a flag number to a RakNet::BitStream
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteFlagNumber(RakNet::BitStream& bs, uint32_t v) {
void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) {
v = (v << 1) | 0x01;
WriteUInt29(bs, v);
}
@@ -104,9 +104,9 @@ void WriteFlagNumber(RakNet::BitStream& bs, uint32_t v) {
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFString(RakNet::BitStream& bs, const std::string& str) {
void WriteAMFString(RakNet::BitStream* bs, const std::string& str) {
WriteFlagNumber(bs, static_cast<uint32_t>(str.size()));
bs.Write(str.c_str(), static_cast<uint32_t>(str.size()));
bs->Write(str.c_str(), static_cast<uint32_t>(str.size()));
}
/**
@@ -114,8 +114,8 @@ void WriteAMFString(RakNet::BitStream& bs, const std::string& str) {
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFU16(RakNet::BitStream& bs, uint16_t value) {
bs.Write(value);
void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) {
bs->Write(value);
}
/**
@@ -123,8 +123,8 @@ void WriteAMFU16(RakNet::BitStream& bs, uint16_t value) {
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFU32(RakNet::BitStream& bs, uint32_t value) {
bs.Write(value);
void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) {
bs->Write(value);
}
/**
@@ -132,40 +132,40 @@ void WriteAMFU32(RakNet::BitStream& bs, uint32_t value) {
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFU64(RakNet::BitStream& bs, uint64_t value) {
bs.Write(value);
void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) {
bs->Write(value);
}
// Writes an AMFIntegerValue to BitStream
template<>
void RakNet::BitStream::Write<AMFIntValue&>(AMFIntValue& value) {
WriteUInt29(*this, value.GetValue());
WriteUInt29(this, value.GetValue());
}
// Writes an AMFDoubleValue to BitStream
template<>
void RakNet::BitStream::Write<AMFDoubleValue&>(AMFDoubleValue& value) {
double d = value.GetValue();
WriteAMFU64(*this, *reinterpret_cast<uint64_t*>(&d));
WriteAMFU64(this, *reinterpret_cast<uint64_t*>(&d));
}
// Writes an AMFStringValue to BitStream
template<>
void RakNet::BitStream::Write<AMFStringValue&>(AMFStringValue& value) {
WriteAMFString(*this, value.GetValue());
WriteAMFString(this, value.GetValue());
}
// Writes an AMFArrayValue to BitStream
template<>
void RakNet::BitStream::Write<AMFArrayValue&>(AMFArrayValue& value) {
uint32_t denseSize = value.GetDense().size();
WriteFlagNumber(*this, denseSize);
WriteFlagNumber(this, denseSize);
auto it = value.GetAssociative().begin();
auto end = value.GetAssociative().end();
while (it != end) {
WriteAMFString(*this, it->first);
WriteAMFString(this, it->first);
this->Write<AMFBaseValue&>(*it->second);
it++;
}

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef BINARYIO_H
#define BINARYIO_H
#ifndef __BINARYIO__H__
#define __BINARYIO__H__
#include <iostream>
#include <fstream>
@@ -71,4 +71,4 @@ namespace BinaryIO {
}
}
#endif //!BINARYIO_H
#endif //!__BINARYIO__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef BINARYPATHFINDER_H
#define BINARYPATHFINDER_H
#ifndef __BINARYPATHFINDER__H__
#define __BINARYPATHFINDER__H__
#include <filesystem>
@@ -12,4 +12,4 @@ public:
static std::filesystem::path GetBinaryDir();
};
#endif //!BINARYPATHFINDER_H
#endif //!__BINARYPATHFINDER__H__

View File

@@ -1,5 +1,5 @@
#ifndef BRICK_H
#define BRICK_H
#ifndef __BRICK__H__
#define __BRICK__H__
#include <cstdint>
@@ -8,4 +8,4 @@ struct Brick {
uint32_t materialID;
};
#endif //!BRICK_H
#endif //!__BRICK__H__

View File

@@ -8,9 +8,11 @@ set(DCOMMON_SOURCES
"Game.cpp"
"GeneralUtils.cpp"
"LDFFormat.cpp"
"MD5.cpp"
"Metrics.cpp"
"NiPoint3.cpp"
"NiQuaternion.cpp"
"SHA512.cpp"
"Demangler.cpp"
"ZCompression.cpp"
"BrickByBrickFix.cpp"
@@ -18,27 +20,17 @@ set(DCOMMON_SOURCES
"FdbToSqlite.cpp"
)
# Workaround for compiler bug where the optimized code could result in a memcpy of 0 bytes, even though that isnt possible.
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97185
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set_source_files_properties("FdbToSqlite.cpp" PROPERTIES COMPILE_FLAGS "-Wno-stringop-overflow")
endif()
add_subdirectory(dClient)
foreach(file ${DCOMMON_DCLIENT_SOURCES})
set(DCOMMON_SOURCES ${DCOMMON_SOURCES} "dClient/${file}")
endforeach()
include_directories(${PROJECT_SOURCE_DIR}/dCommon/)
add_library(dCommon STATIC ${DCOMMON_SOURCES})
target_include_directories(dCommon
PUBLIC "." "dClient" "dEnums"
PRIVATE
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
"${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include"
)
target_link_libraries(dCommon bcrypt dDatabase tinyxml2)
if (UNIX)
find_package(ZLIB REQUIRED)
@@ -69,6 +61,4 @@ else ()
)
endif ()
target_link_libraries(dCommon
PRIVATE ZLIB::ZLIB bcrypt tinyxml2
INTERFACE dDatabase)
target_link_libraries(dCommon ZLIB::ZLIB)

View File

@@ -120,8 +120,6 @@ void CatchUnhandled(int sig) {
if (eptr) std::rethrow_exception(eptr);
} catch(const std::exception& e) {
LOG("Caught exception: '%s'", e.what());
} catch (...) {
LOG("Caught unknown exception.");
}
#ifndef INCLUDE_BACKTRACE
@@ -201,7 +199,7 @@ void OnTerminate() {
}
void MakeBacktrace() {
struct sigaction sigact{};
struct sigaction sigact;
sigact.sa_sigaction = CritErrHdlr;
sigact.sa_flags = SA_RESTART | SA_SIGINFO;

View File

@@ -1,5 +1,5 @@
#ifndef DLUASSERT_H
#define DLUASSERT_H
#ifndef __DLUASSERT__H__
#define __DLUASSERT__H__
#include <assert.h>
@@ -9,4 +9,4 @@
# define DluAssert(expression)
#endif
#endif //!DLUASSERT_H
#endif //!__DLUASSERT__H__

View File

@@ -1,5 +1,5 @@
#ifndef FDBTOSQLITE_H
#define FDBTOSQLITE_H
#ifndef __FDBTOSQLITE__H__
#define __FDBTOSQLITE__H__
#pragma once
@@ -142,4 +142,4 @@ namespace FdbToSqlite {
}; //! class FdbToSqlite
}; //! namespace FdbToSqlite
#endif //!FDBTOSQLITE_H
#endif //!__FDBTOSQLITE__H__

View File

@@ -8,23 +8,23 @@
#include <map>
template <typename T>
static inline size_t MinSize(const size_t size, const std::basic_string_view<T> string) {
if (size == SIZE_MAX || size > string.size()) {
inline size_t MinSize(size_t size, const std::basic_string_view<T>& string) {
if (size == size_t(-1) || size > string.size()) {
return string.size();
} else {
return size;
}
}
inline bool IsLeadSurrogate(const char16_t c) {
inline bool IsLeadSurrogate(char16_t c) {
return (0xD800 <= c) && (c <= 0xDBFF);
}
inline bool IsTrailSurrogate(const char16_t c) {
inline bool IsTrailSurrogate(char16_t c) {
return (0xDC00 <= c) && (c <= 0xDFFF);
}
inline void PushUTF8CodePoint(std::string& ret, const char32_t cp) {
inline void PushUTF8CodePoint(std::string& ret, char32_t cp) {
if (cp <= 0x007F) {
ret.push_back(static_cast<uint8_t>(cp));
} else if (cp <= 0x07FF) {
@@ -46,16 +46,16 @@ inline void PushUTF8CodePoint(std::string& ret, const char32_t cp) {
constexpr const char16_t REPLACEMENT_CHARACTER = 0xFFFD;
bool static _IsSuffixChar(const uint8_t c) {
bool _IsSuffixChar(uint8_t c) {
return (c & 0xC0) == 0x80;
}
bool GeneralUtils::details::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
const size_t rem = slice.length();
bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
size_t rem = slice.length();
if (slice.empty()) return false;
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&slice.front());
if (rem > 0) {
const uint8_t first = bytes[0];
uint8_t first = bytes[0];
if (first < 0x80) { // 1 byte character
out = static_cast<uint32_t>(first & 0x7F);
slice.remove_prefix(1);
@@ -64,7 +64,7 @@ bool GeneralUtils::details::_NextUTF8Char(std::string_view& slice, uint32_t& out
// middle byte, not valid at start, fall through
} else if (first < 0xE0) { // two byte character
if (rem > 1) {
const uint8_t second = bytes[1];
uint8_t second = bytes[1];
if (_IsSuffixChar(second)) {
out = (static_cast<uint32_t>(first & 0x1F) << 6)
+ static_cast<uint32_t>(second & 0x3F);
@@ -74,8 +74,8 @@ bool GeneralUtils::details::_NextUTF8Char(std::string_view& slice, uint32_t& out
}
} else if (first < 0xF0) { // three byte character
if (rem > 2) {
const uint8_t second = bytes[1];
const uint8_t third = bytes[2];
uint8_t second = bytes[1];
uint8_t third = bytes[2];
if (_IsSuffixChar(second) && _IsSuffixChar(third)) {
out = (static_cast<uint32_t>(first & 0x0F) << 12)
+ (static_cast<uint32_t>(second & 0x3F) << 6)
@@ -86,9 +86,9 @@ bool GeneralUtils::details::_NextUTF8Char(std::string_view& slice, uint32_t& out
}
} else if (first < 0xF8) { // four byte character
if (rem > 3) {
const uint8_t second = bytes[1];
const uint8_t third = bytes[2];
const uint8_t fourth = bytes[3];
uint8_t second = bytes[1];
uint8_t third = bytes[2];
uint8_t fourth = bytes[3];
if (_IsSuffixChar(second) && _IsSuffixChar(third) && _IsSuffixChar(fourth)) {
out = (static_cast<uint32_t>(first & 0x07) << 18)
+ (static_cast<uint32_t>(second & 0x3F) << 12)
@@ -107,7 +107,7 @@ bool GeneralUtils::details::_NextUTF8Char(std::string_view& slice, uint32_t& out
}
/// See <https://www.ietf.org/rfc/rfc2781.html#section-2.1>
bool PushUTF16CodePoint(std::u16string& output, const uint32_t U, const size_t size) {
bool PushUTF16CodePoint(std::u16string& output, uint32_t U, size_t size) {
if (output.length() >= size) return false;
if (U < 0x10000) {
// If U < 0x10000, encode U as a 16-bit unsigned integer and terminate.
@@ -120,7 +120,7 @@ bool PushUTF16CodePoint(std::u16string& output, const uint32_t U, const size_t s
// Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
// U' must be less than or equal to 0xFFFFF. That is, U' can be
// represented in 20 bits.
const uint32_t Ut = U - 0x10000;
uint32_t Ut = U - 0x10000;
// Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
// 0xDC00, respectively. These integers each have 10 bits free to
@@ -141,25 +141,25 @@ bool PushUTF16CodePoint(std::u16string& output, const uint32_t U, const size_t s
} else return false;
}
std::u16string GeneralUtils::UTF8ToUTF16(const std::string_view string, const size_t size) {
const size_t newSize = MinSize(size, string);
std::u16string GeneralUtils::UTF8ToUTF16(const std::string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::u16string output;
output.reserve(newSize);
std::string_view iterator = string;
uint32_t c;
while (details::_NextUTF8Char(iterator, c) && PushUTF16CodePoint(output, c, size)) {}
while (_NextUTF8Char(iterator, c) && PushUTF16CodePoint(output, c, size)) {}
return output;
}
//! Converts an std::string (ASCII) to UCS-2 / UTF-16
std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view string, const size_t size) {
const size_t newSize = MinSize(size, string);
std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::u16string ret;
ret.reserve(newSize);
for (size_t i = 0; i < newSize; ++i) {
const char c = string[i];
for (size_t i = 0; i < newSize; i++) {
char c = string[i];
// Note: both 7-bit ascii characters and REPLACEMENT_CHARACTER fit in one char16_t
ret.push_back((c > 0 && c <= 127) ? static_cast<char16_t>(c) : REPLACEMENT_CHARACTER);
}
@@ -169,18 +169,18 @@ std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view string, const s
//! Converts a (potentially-ill-formed) UTF-16 string to UTF-8
//! See: <http://simonsapin.github.io/wtf-8/#decoding-ill-formed-utf-16>
std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view string, const size_t size) {
const size_t newSize = MinSize(size, string);
std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::string ret;
ret.reserve(newSize);
for (size_t i = 0; i < newSize; ++i) {
const char16_t u = string[i];
for (size_t i = 0; i < newSize; i++) {
char16_t u = string[i];
if (IsLeadSurrogate(u) && (i + 1) < newSize) {
const char16_t next = string[i + 1];
char16_t next = string[i + 1];
if (IsTrailSurrogate(next)) {
i += 1;
const char32_t cp = 0x10000
char32_t cp = 0x10000
+ ((static_cast<char32_t>(u) - 0xD800) << 10)
+ (static_cast<char32_t>(next) - 0xDC00);
PushUTF8CodePoint(ret, cp);
@@ -195,40 +195,40 @@ std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view string, const si
return ret;
}
bool GeneralUtils::CaseInsensitiveStringCompare(const std::string_view a, const std::string_view b) {
bool GeneralUtils::CaseInsensitiveStringCompare(const std::string& a, const std::string& b) {
return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b) { return tolower(a) == tolower(b); });
}
// MARK: Bits
//! Sets a specific bit in a signed 64-bit integer
int64_t GeneralUtils::SetBit(int64_t value, const uint32_t index) {
int64_t GeneralUtils::SetBit(int64_t value, uint32_t index) {
return value |= 1ULL << index;
}
//! Clears a specific bit in a signed 64-bit integer
int64_t GeneralUtils::ClearBit(int64_t value, const uint32_t index) {
int64_t GeneralUtils::ClearBit(int64_t value, uint32_t index) {
return value &= ~(1ULL << index);
}
//! Checks a specific bit in a signed 64-bit integer
bool GeneralUtils::CheckBit(int64_t value, const uint32_t index) {
bool GeneralUtils::CheckBit(int64_t value, uint32_t index) {
return value & (1ULL << index);
}
bool GeneralUtils::ReplaceInString(std::string& str, const std::string_view from, const std::string_view to) {
const size_t start_pos = str.find(from);
bool GeneralUtils::ReplaceInString(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if (start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::vector<std::wstring> GeneralUtils::SplitString(const std::wstring_view str, const wchar_t delimiter) {
std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t delimiter) {
std::vector<std::wstring> vector = std::vector<std::wstring>();
std::wstring current;
for (const wchar_t c : str) {
for (const auto& c : str) {
if (c == delimiter) {
vector.push_back(current);
current = L"";
@@ -237,15 +237,15 @@ std::vector<std::wstring> GeneralUtils::SplitString(const std::wstring_view str,
}
}
vector.push_back(std::move(current));
vector.push_back(current);
return vector;
}
std::vector<std::u16string> GeneralUtils::SplitString(const std::u16string_view str, const char16_t delimiter) {
std::vector<std::u16string> GeneralUtils::SplitString(const std::u16string& str, char16_t delimiter) {
std::vector<std::u16string> vector = std::vector<std::u16string>();
std::u16string current;
for (const char16_t c : str) {
for (const auto& c : str) {
if (c == delimiter) {
vector.push_back(current);
current = u"";
@@ -254,15 +254,17 @@ std::vector<std::u16string> GeneralUtils::SplitString(const std::u16string_view
}
}
vector.push_back(std::move(current));
vector.push_back(current);
return vector;
}
std::vector<std::string> GeneralUtils::SplitString(const std::string_view str, const char delimiter) {
std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char delimiter) {
std::vector<std::string> vector = std::vector<std::string>();
std::string current = "";
for (const char c : str) {
for (size_t i = 0; i < str.length(); i++) {
char c = str[i];
if (c == delimiter) {
vector.push_back(current);
current = "";
@@ -271,70 +273,53 @@ std::vector<std::string> GeneralUtils::SplitString(const std::string_view str, c
}
}
vector.push_back(std::move(current));
vector.push_back(current);
return vector;
}
std::u16string GeneralUtils::ReadWString(RakNet::BitStream& inStream) {
std::u16string GeneralUtils::ReadWString(RakNet::BitStream* inStream) {
uint32_t length;
inStream.Read<uint32_t>(length);
inStream->Read<uint32_t>(length);
std::u16string string;
for (uint32_t i = 0; i < length; ++i) {
for (auto i = 0; i < length; i++) {
uint16_t c;
inStream.Read(c);
inStream->Read(c);
string.push_back(c);
}
return string;
}
std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::string_view folder) {
std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::string& folder) {
// Because we dont know how large the initial number before the first _ is we need to make it a map like so.
std::map<uint32_t, std::string> filenames{};
for (const auto& t : std::filesystem::directory_iterator(folder)) {
for (auto& t : std::filesystem::directory_iterator(folder)) {
auto filename = t.path().filename().string();
const auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0));
filenames.emplace(index, std::move(filename));
auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0));
filenames.insert(std::make_pair(index, filename));
}
// Now sort the map by the oldest migration.
std::vector<std::string> sortedFiles{};
auto fileIterator = filenames.cbegin();
auto oldest = filenames.cbegin();
auto fileIterator = filenames.begin();
std::map<uint32_t, std::string>::iterator oldest = filenames.begin();
while (!filenames.empty()) {
if (fileIterator == filenames.cend()) {
if (fileIterator == filenames.end()) {
sortedFiles.push_back(oldest->second);
filenames.erase(oldest);
fileIterator = filenames.cbegin();
oldest = filenames.cbegin();
fileIterator = filenames.begin();
oldest = filenames.begin();
continue;
}
if (oldest->first > fileIterator->first) oldest = fileIterator;
++fileIterator;
fileIterator++;
}
return sortedFiles;
}
#if !(__GNUC__ >= 11 || _MSC_VER >= 1924)
// MacOS floating-point parse function specializations
namespace GeneralUtils::details {
template <>
[[nodiscard]] float _parse<float>(const std::string_view str, size_t& parseNum) {
return std::stof(std::string{ str }, &parseNum);
}
template <>
[[nodiscard]] double _parse<double>(const std::string_view str, size_t& parseNum) {
return std::stod(std::string{ str }, &parseNum);
}
template <>
[[nodiscard]] long double _parse<long double>(const std::string_view str, size_t& parseNum) {
return std::stold(std::string{ str }, &parseNum);
}
bool GeneralUtils::TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst) {
return TryParse<float>(x.c_str(), dst.x) && TryParse<float>(y.c_str(), dst.y) && TryParse<float>(z.c_str(), dst.z);
}
#endif

View File

@@ -1,21 +1,17 @@
#pragma once
// C++
#include <charconv>
#include <cstdint>
#include <ctime>
#include <functional>
#include <optional>
#include <stdint.h>
#include <random>
#include <span>
#include <stdexcept>
#include <time.h>
#include <string>
#include <string_view>
#include <type_traits>
#include <functional>
#include <type_traits>
#include <stdexcept>
#include "BitStream.h"
#include "NiPoint3.h"
#include "dPlatforms.h"
#include "Game.h"
#include "Logger.h"
@@ -33,31 +29,29 @@ namespace GeneralUtils {
//! Converts a plain ASCII string to a UTF-16 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is SIZE_MAX (No trimming)
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-16 representation of the string
*/
std::u16string ASCIIToUTF16(const std::string_view string, const size_t size = SIZE_MAX);
std::u16string ASCIIToUTF16(const std::string_view& string, size_t size = -1);
//! Converts a UTF-8 String to a UTF-16 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is SIZE_MAX (No trimming)
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-16 representation of the string
*/
std::u16string UTF8ToUTF16(const std::string_view string, const size_t size = SIZE_MAX);
std::u16string UTF8ToUTF16(const std::string_view& string, size_t size = -1);
namespace details {
//! Internal, do not use
bool _NextUTF8Char(std::string_view& slice, uint32_t& out);
}
//! Converts a UTF-16 string to a UTF-8 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is SIZE_MAX (No trimming)
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-8 representation of the string
*/
std::string UTF16ToWTF8(const std::u16string_view string, const size_t size = SIZE_MAX);
std::string UTF16ToWTF8(const std::u16string_view& string, size_t size = -1);
/**
* Compares two basic strings but does so ignoring case sensitivity
@@ -65,7 +59,7 @@ namespace GeneralUtils {
* \param b the second string to compare against the first string
* @return if the two strings are equal
*/
bool CaseInsensitiveStringCompare(const std::string_view a, const std::string_view b);
bool CaseInsensitiveStringCompare(const std::string& a, const std::string& b);
// MARK: Bits
@@ -73,9 +67,9 @@ namespace GeneralUtils {
//! Sets a bit on a numerical value
template <typename T>
inline void SetBit(T& value, const eObjectBits bits) {
inline void SetBit(T& value, eObjectBits bits) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
const auto index = static_cast<size_t>(bits);
auto index = static_cast<size_t>(bits);
if (index > (sizeof(T) * 8) - 1) {
return;
}
@@ -85,9 +79,9 @@ namespace GeneralUtils {
//! Clears a bit on a numerical value
template <typename T>
inline void ClearBit(T& value, const eObjectBits bits) {
inline void ClearBit(T& value, eObjectBits bits) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
const auto index = static_cast<size_t>(bits);
auto index = static_cast<size_t>(bits);
if (index > (sizeof(T) * 8 - 1)) {
return;
}
@@ -100,14 +94,14 @@ namespace GeneralUtils {
\param value The value to set the bit for
\param index The index of the bit
*/
int64_t SetBit(int64_t value, const uint32_t index);
int64_t SetBit(int64_t value, uint32_t index);
//! Clears a specific bit in a signed 64-bit integer
/*!
\param value The value to clear the bit from
\param index The index of the bit
*/
int64_t ClearBit(int64_t value, const uint32_t index);
int64_t ClearBit(int64_t value, uint32_t index);
//! Checks a specific bit in a signed 64-bit integer
/*!
@@ -115,128 +109,104 @@ namespace GeneralUtils {
\param index The index of the bit
\return Whether or not the bit is set
*/
bool CheckBit(int64_t value, const uint32_t index);
bool CheckBit(int64_t value, uint32_t index);
bool ReplaceInString(std::string& str, const std::string_view from, const std::string_view to);
bool ReplaceInString(std::string& str, const std::string& from, const std::string& to);
std::u16string ReadWString(RakNet::BitStream& inStream);
std::u16string ReadWString(RakNet::BitStream* inStream);
std::vector<std::wstring> SplitString(const std::wstring_view str, const wchar_t delimiter);
std::vector<std::wstring> SplitString(std::wstring& str, wchar_t delimiter);
std::vector<std::u16string> SplitString(const std::u16string_view str, const char16_t delimiter);
std::vector<std::u16string> SplitString(const std::u16string& str, char16_t delimiter);
std::vector<std::string> SplitString(const std::string_view str, const char delimiter);
std::vector<std::string> SplitString(const std::string& str, char delimiter);
std::vector<std::string> GetSqlFileNamesFromFolder(const std::string_view folder);
std::vector<std::string> GetSqlFileNamesFromFolder(const std::string& folder);
// Concept constraining to enum types
template <typename T>
concept Enum = std::is_enum_v<T>;
T Parse(const char* value);
// Concept constraining to numeric types
template <typename T>
concept Numeric = std::integral<T> || Enum<T> || std::floating_point<T>;
// Concept trickery to enable parsing underlying numeric types
template <Numeric T>
struct numeric_parse { using type = T; };
// If an enum, present an alias to its underlying type for parsing
template <Numeric T> requires Enum<T>
struct numeric_parse<T> { using type = std::underlying_type_t<T>; };
// If a boolean, present an alias to an intermediate integral type for parsing
template <Numeric T> requires std::same_as<T, bool>
struct numeric_parse<T> { using type = uint8_t; };
// Shorthand type alias
template <Numeric T>
using numeric_parse_t = numeric_parse<T>::type;
/**
* For numeric values: Parses a string_view and returns an optional variable depending on the result.
* @param str The string_view to be evaluated
* @returns An std::optional containing the desired value if it is equivalent to the string
*/
template <Numeric T>
[[nodiscard]] std::optional<T> TryParse(std::string_view str) {
numeric_parse_t<T> result;
while (!str.empty() && std::isspace(str.front())) str.remove_prefix(1);
const char* const strEnd = str.data() + str.size();
const auto [parseEnd, ec] = std::from_chars(str.data(), strEnd, result);
const bool isParsed = parseEnd == strEnd && ec == std::errc{};
return isParsed ? static_cast<T>(result) : std::optional<T>{};
template <>
inline bool Parse(const char* value) {
return std::stoi(value);
}
#if !(__GNUC__ >= 11 || _MSC_VER >= 1924)
// MacOS floating-point parse helper function specializations
namespace details {
template <std::floating_point T>
[[nodiscard]] T _parse(const std::string_view str, size_t& parseNum);
template <>
inline int32_t Parse(const char* value) {
return std::stoi(value);
}
/**
* For floating-point values: Parses a string_view and returns an optional variable depending on the result.
* Note that this function overload is only included for MacOS, as from_chars will fulfill its purpose otherwise.
* @param str The string_view to be evaluated
* @returns An std::optional containing the desired value if it is equivalent to the string
*/
template <std::floating_point T>
[[nodiscard]] std::optional<T> TryParse(std::string_view str) noexcept
template <>
inline int64_t Parse(const char* value) {
return std::stoll(value);
}
template <>
inline float Parse(const char* value) {
return std::stof(value);
}
template <>
inline double Parse(const char* value) {
return std::stod(value);
}
template <>
inline uint16_t Parse(const char* value) {
return std::stoul(value);
}
template <>
inline uint32_t Parse(const char* value) {
return std::stoul(value);
}
template <>
inline uint64_t Parse(const char* value) {
return std::stoull(value);
}
template <>
inline eInventoryType Parse(const char* value) {
return static_cast<eInventoryType>(std::stoul(value));
}
template <>
inline eReplicaComponentType Parse(const char* value) {
return static_cast<eReplicaComponentType>(std::stoul(value));
}
template <typename T>
bool TryParse(const char* value, T& dst) {
try {
while (!str.empty() && std::isspace(str.front())) str.remove_prefix(1);
dst = Parse<T>(value);
size_t parseNum;
const T result = details::_parse<T>(str, parseNum);
const bool isParsed = str.length() == parseNum;
return isParsed ? result : std::optional<T>{};
return true;
} catch (...) {
return std::nullopt;
return false;
}
#endif
/**
* The TryParse overload for handling NiPoint3 by passing 3 seperate string references
* @param strX The string representing the X coordinate
* @param strY The string representing the Y coordinate
* @param strZ The string representing the Z coordinate
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::string_view strX, const std::string_view strY, const std::string_view strZ) {
const auto x = TryParse<float>(strX);
if (!x) return std::nullopt;
const auto y = TryParse<float>(strY);
if (!y) return std::nullopt;
const auto z = TryParse<float>(strZ);
return z ? std::make_optional<NiPoint3>(x.value(), y.value(), z.value()) : std::nullopt;
}
/**
* The TryParse overload for handling NiPoint3 by passing a span of three strings
* @param str The string vector representing the X, Y, and Z coordinates
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::span<const std::string> str) {
return (str.size() == 3) ? TryParse<NiPoint3>(str[0], str[1], str[2]) : std::nullopt;
}
template <typename T>
std::u16string to_u16string(const T value) {
T Parse(const std::string& value) {
return Parse<T>(value.c_str());
}
template <typename T>
bool TryParse(const std::string& value, T& dst) {
return TryParse<T>(value.c_str(), dst);
}
bool TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst);
template<typename T>
std::u16string to_u16string(T value) {
return GeneralUtils::ASCIIToUTF16(std::to_string(value));
}
// From boost::hash_combine
template <class T>
constexpr void hash_combine(std::size_t& s, const T& v) {
void hash_combine(std::size_t& s, const T& v) {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
@@ -249,7 +219,7 @@ namespace GeneralUtils {
\param max The maximum to generate to
*/
template <typename T>
inline T GenerateRandomNumber(const std::size_t min, const std::size_t max) {
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
// Make sure it is a numeric type
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
@@ -269,17 +239,19 @@ namespace GeneralUtils {
* @param entry Enum entry to cast
* @returns The enum entry's value in its underlying type
*/
template <Enum eType>
constexpr std::underlying_type_t<eType> ToUnderlying(const eType entry) noexcept {
return static_cast<std::underlying_type_t<eType>>(entry);
template <typename eType>
inline constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) {
static_assert(std::is_enum_v<eType>, "Not an enum");
return static_cast<typename std::underlying_type_t<eType>>(entry);
}
// on Windows we need to undef these or else they conflict with our numeric limits calls
// DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS
#ifdef _WIN32
#undef min
#undef max
#endif
#ifdef _WIN32
#undef min
#undef max
#endif
template <typename T>
inline T GenerateRandomNumber() {

View File

@@ -61,33 +61,33 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}
case LDF_TYPE_S32: {
const auto data = GeneralUtils::TryParse<int32_t>(ldfTypeAndValue.second);
if (!data) {
int32_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
LOG("Warning: Attempted to process invalid int32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<int32_t>(key, data.value());
returnValue = new LDFData<int32_t>(key, data);
break;
}
case LDF_TYPE_FLOAT: {
const auto data = GeneralUtils::TryParse<float>(ldfTypeAndValue.second);
if (!data) {
float data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
LOG("Warning: Attempted to process invalid float value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<float>(key, data.value());
returnValue = new LDFData<float>(key, data);
break;
}
case LDF_TYPE_DOUBLE: {
const auto data = GeneralUtils::TryParse<double>(ldfTypeAndValue.second);
if (!data) {
double data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
LOG("Warning: Attempted to process invalid double value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<double>(key, data.value());
returnValue = new LDFData<double>(key, data);
break;
}
@@ -100,12 +100,10 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = 0;
} else {
const auto dataOptional = GeneralUtils::TryParse<uint32_t>(ldfTypeAndValue.second);
if (!dataOptional) {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
LOG("Warning: Attempted to process invalid uint32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
data = dataOptional.value();
}
returnValue = new LDFData<uint32_t>(key, data);
@@ -120,12 +118,10 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = false;
} else {
const auto dataOptional = GeneralUtils::TryParse<bool>(ldfTypeAndValue.second);
if (!dataOptional) {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
LOG("Warning: Attempted to process invalid bool value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
data = dataOptional.value();
}
returnValue = new LDFData<bool>(key, data);
@@ -133,22 +129,22 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}
case LDF_TYPE_U64: {
const auto data = GeneralUtils::TryParse<uint64_t>(ldfTypeAndValue.second);
if (!data) {
uint64_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
LOG("Warning: Attempted to process invalid uint64 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<uint64_t>(key, data.value());
returnValue = new LDFData<uint64_t>(key, data);
break;
}
case LDF_TYPE_OBJID: {
const auto data = GeneralUtils::TryParse<LWOOBJID>(ldfTypeAndValue.second);
if (!data) {
LWOOBJID data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
LOG("Warning: Attempted to process invalid LWOOBJID value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<LWOOBJID>(key, data.value());
returnValue = new LDFData<LWOOBJID>(key, data);
break;
}

View File

@@ -1,5 +1,5 @@
#ifndef LDFFORMAT_H
#define LDFFORMAT_H
#ifndef __LDFFORMAT__H__
#define __LDFFORMAT__H__
// Custom Classes
#include "dCommonVars.h"
@@ -31,22 +31,22 @@ public:
virtual ~LDFBaseData() {}
virtual void WriteToPacket(RakNet::BitStream& packet) const = 0;
virtual void WriteToPacket(RakNet::BitStream* packet) = 0;
virtual const std::u16string& GetKey() const = 0;
virtual const std::u16string& GetKey() = 0;
virtual eLDFType GetValueType() const = 0;
virtual eLDFType GetValueType() = 0;
/** Gets a string from the key/value pair
* @param includeKey Whether or not to include the key in the data
* @param includeTypeId Whether or not to include the type id in the data
* @return The string representation of the data
*/
virtual std::string GetString(bool includeKey = true, bool includeTypeId = true) const = 0;
virtual std::string GetString(bool includeKey = true, bool includeTypeId = true) = 0;
virtual std::string GetValueAsString() const = 0;
virtual std::string GetValueAsString() = 0;
virtual LDFBaseData* Copy() const = 0;
virtual LDFBaseData* Copy() = 0;
/**
* Given an input string, return the data as a LDF key.
@@ -62,17 +62,17 @@ private:
T value;
//! Writes the key to the packet
void WriteKey(RakNet::BitStream& packet) const {
packet.Write<uint8_t>(this->key.length() * sizeof(uint16_t));
void WriteKey(RakNet::BitStream* packet) {
packet->Write<uint8_t>(this->key.length() * sizeof(uint16_t));
for (uint32_t i = 0; i < this->key.length(); ++i) {
packet.Write<uint16_t>(this->key[i]);
packet->Write<uint16_t>(this->key[i]);
}
}
//! Writes the value to the packet
void WriteValue(RakNet::BitStream& packet) const {
packet.Write<uint8_t>(this->GetValueType());
packet.Write(this->value);
void WriteValue(RakNet::BitStream* packet) {
packet->Write<uint8_t>(this->GetValueType());
packet->Write(this->value);
}
public:
@@ -90,7 +90,7 @@ public:
/*!
\return The value
*/
const T& GetValue(void) const { return this->value; }
const T& GetValue(void) { return this->value; }
//! Sets the value
/*!
@@ -102,13 +102,13 @@ public:
/*!
\return The value string
*/
std::string GetValueString(void) const { return ""; }
std::string GetValueString(void) { return ""; }
//! Writes the data to a packet
/*!
\param packet The packet
*/
void WriteToPacket(RakNet::BitStream& packet) const override {
void WriteToPacket(RakNet::BitStream* packet) override {
this->WriteKey(packet);
this->WriteValue(packet);
}
@@ -117,13 +117,13 @@ public:
/*!
\return The key
*/
const std::u16string& GetKey(void) const override { return this->key; }
const std::u16string& GetKey(void) override { return this->key; }
//! Gets the LDF Type
/*!
\return The LDF value type
*/
eLDFType GetValueType(void) const override { return LDF_TYPE_UNKNOWN; }
eLDFType GetValueType(void) override { return LDF_TYPE_UNKNOWN; }
//! Gets the string data
/*!
@@ -131,7 +131,7 @@ public:
\param includeTypeId Whether or not to include the type id in the data
\return The string representation of the data
*/
std::string GetString(const bool includeKey = true, const bool includeTypeId = true) const override {
std::string GetString(const bool includeKey = true, const bool includeTypeId = true) override {
if (GetValueType() == -1) {
return GeneralUtils::UTF16ToWTF8(this->key) + "=-1:<server variable>";
}
@@ -154,70 +154,70 @@ public:
return stream.str();
}
std::string GetValueAsString() const override {
std::string GetValueAsString() override {
return this->GetValueString();
}
LDFBaseData* Copy() const override {
LDFBaseData* Copy() override {
return new LDFData<T>(key, value);
}
inline static const T Default = {};
inline static T Default = {};
};
// LDF Types
template<> inline eLDFType LDFData<std::u16string>::GetValueType(void) const { return LDF_TYPE_UTF_16; };
template<> inline eLDFType LDFData<int32_t>::GetValueType(void) const { return LDF_TYPE_S32; };
template<> inline eLDFType LDFData<float>::GetValueType(void) const { return LDF_TYPE_FLOAT; };
template<> inline eLDFType LDFData<double>::GetValueType(void) const { return LDF_TYPE_DOUBLE; };
template<> inline eLDFType LDFData<uint32_t>::GetValueType(void) const { return LDF_TYPE_U32; };
template<> inline eLDFType LDFData<bool>::GetValueType(void) const { return LDF_TYPE_BOOLEAN; };
template<> inline eLDFType LDFData<uint64_t>::GetValueType(void) const { return LDF_TYPE_U64; };
template<> inline eLDFType LDFData<LWOOBJID>::GetValueType(void) const { return LDF_TYPE_OBJID; };
template<> inline eLDFType LDFData<std::string>::GetValueType(void) const { return LDF_TYPE_UTF_8; };
template<> inline eLDFType LDFData<std::u16string>::GetValueType(void) { return LDF_TYPE_UTF_16; };
template<> inline eLDFType LDFData<int32_t>::GetValueType(void) { return LDF_TYPE_S32; };
template<> inline eLDFType LDFData<float>::GetValueType(void) { return LDF_TYPE_FLOAT; };
template<> inline eLDFType LDFData<double>::GetValueType(void) { return LDF_TYPE_DOUBLE; };
template<> inline eLDFType LDFData<uint32_t>::GetValueType(void) { return LDF_TYPE_U32; };
template<> inline eLDFType LDFData<bool>::GetValueType(void) { return LDF_TYPE_BOOLEAN; };
template<> inline eLDFType LDFData<uint64_t>::GetValueType(void) { return LDF_TYPE_U64; };
template<> inline eLDFType LDFData<LWOOBJID>::GetValueType(void) { return LDF_TYPE_OBJID; };
template<> inline eLDFType LDFData<std::string>::GetValueType(void) { return LDF_TYPE_UTF_8; };
// The specialized version for std::u16string (UTF-16)
template<>
inline void LDFData<std::u16string>::WriteValue(RakNet::BitStream& packet) const {
packet.Write<uint8_t>(this->GetValueType());
inline void LDFData<std::u16string>::WriteValue(RakNet::BitStream* packet) {
packet->Write<uint8_t>(this->GetValueType());
packet.Write<uint32_t>(this->value.length());
packet->Write<uint32_t>(this->value.length());
for (uint32_t i = 0; i < this->value.length(); ++i) {
packet.Write<uint16_t>(this->value[i]);
packet->Write<uint16_t>(this->value[i]);
}
}
// The specialized version for bool
template<>
inline void LDFData<bool>::WriteValue(RakNet::BitStream& packet) const {
packet.Write<uint8_t>(this->GetValueType());
inline void LDFData<bool>::WriteValue(RakNet::BitStream* packet) {
packet->Write<uint8_t>(this->GetValueType());
packet.Write<uint8_t>(this->value);
packet->Write<uint8_t>(this->value);
}
// The specialized version for std::string (UTF-8)
template<>
inline void LDFData<std::string>::WriteValue(RakNet::BitStream& packet) const {
packet.Write<uint8_t>(this->GetValueType());
inline void LDFData<std::string>::WriteValue(RakNet::BitStream* packet) {
packet->Write<uint8_t>(this->GetValueType());
packet.Write<uint32_t>(this->value.length());
packet->Write<uint32_t>(this->value.length());
for (uint32_t i = 0; i < this->value.length(); ++i) {
packet.Write<uint8_t>(this->value[i]);
packet->Write<uint8_t>(this->value[i]);
}
}
template<> inline std::string LDFData<std::u16string>::GetValueString() const {
template<> inline std::string LDFData<std::u16string>::GetValueString() {
return GeneralUtils::UTF16ToWTF8(this->value, this->value.size());
}
template<> inline std::string LDFData<int32_t>::GetValueString() const { return std::to_string(this->value); }
template<> inline std::string LDFData<float>::GetValueString() const { return std::to_string(this->value); }
template<> inline std::string LDFData<double>::GetValueString() const { return std::to_string(this->value); }
template<> inline std::string LDFData<uint32_t>::GetValueString() const { return std::to_string(this->value); }
template<> inline std::string LDFData<bool>::GetValueString() const { return std::to_string(this->value); }
template<> inline std::string LDFData<uint64_t>::GetValueString() const { return std::to_string(this->value); }
template<> inline std::string LDFData<LWOOBJID>::GetValueString() const { return std::to_string(this->value); }
template<> inline std::string LDFData<int32_t>::GetValueString() { return std::to_string(this->value); }
template<> inline std::string LDFData<float>::GetValueString() { return std::to_string(this->value); }
template<> inline std::string LDFData<double>::GetValueString() { return std::to_string(this->value); }
template<> inline std::string LDFData<uint32_t>::GetValueString() { return std::to_string(this->value); }
template<> inline std::string LDFData<bool>::GetValueString() { return std::to_string(this->value); }
template<> inline std::string LDFData<uint64_t>::GetValueString() { return std::to_string(this->value); }
template<> inline std::string LDFData<LWOOBJID>::GetValueString() { return std::to_string(this->value); }
template<> inline std::string LDFData<std::string>::GetValueString() const { return this->value; }
template<> inline std::string LDFData<std::string>::GetValueString() { return this->value; }
#endif //!LDFFORMAT_H
#endif //!__LDFFORMAT__H__

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

154
dCommon/SHA512.cpp Normal file
View File

@@ -0,0 +1,154 @@
// Source: http://www.zedwood.com/article/cpp-sha512-function
#include "SHA512.h"
#include <cstring>
#include <fstream>
const unsigned long long SHA512::sha512_k[80] = //ULL = uint64
{ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
void SHA512::transform(const unsigned char* message, unsigned int block_nb) {
uint64 w[80];
uint64 wv[8];
uint64 t1, t2;
const unsigned char* sub_block;
int i, j;
for (i = 0; i < (int)block_nb; i++) {
sub_block = message + (i << 7);
for (j = 0; j < 16; j++) {
SHA2_PACK64(&sub_block[j << 3], &w[j]);
}
for (j = 16; j < 80; j++) {
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
}
for (j = 0; j < 8; j++) {
wv[j] = m_h[j];
}
for (j = 0; j < 80; j++) {
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
+ sha512_k[j] + w[j];
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
m_h[j] += wv[j];
}
}
}
void SHA512::init() {
m_h[0] = 0x6a09e667f3bcc908ULL;
m_h[1] = 0xbb67ae8584caa73bULL;
m_h[2] = 0x3c6ef372fe94f82bULL;
m_h[3] = 0xa54ff53a5f1d36f1ULL;
m_h[4] = 0x510e527fade682d1ULL;
m_h[5] = 0x9b05688c2b3e6c1fULL;
m_h[6] = 0x1f83d9abfb41bd6bULL;
m_h[7] = 0x5be0cd19137e2179ULL;
m_len = 0;
m_tot_len = 0;
}
void SHA512::update(const unsigned char* message, unsigned int len) {
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char* shifted_message;
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&m_block[m_len], message, rem_len);
if (m_len + len < SHA384_512_BLOCK_SIZE) {
m_len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA384_512_BLOCK_SIZE;
shifted_message = message + rem_len;
transform(m_block, 1);
transform(shifted_message, block_nb);
rem_len = new_len % SHA384_512_BLOCK_SIZE;
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
m_len = rem_len;
m_tot_len += (block_nb + 1) << 7;
}
void SHA512::final(unsigned char* digest) {
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
int i;
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
< (m_len % SHA384_512_BLOCK_SIZE));
len_b = (m_tot_len + m_len) << 3;
pm_len = block_nb << 7;
memset(m_block + m_len, 0, pm_len - m_len);
m_block[m_len] = 0x80;
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
transform(m_block, block_nb);
for (i = 0; i < 8; i++) {
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
}
}
std::string sha512(std::string input) {
unsigned char digest[SHA512::DIGEST_SIZE];
memset(digest, 0, SHA512::DIGEST_SIZE);
class SHA512 ctx;
ctx.init();
ctx.update((unsigned char*)input.c_str(), input.length());
ctx.final(digest);
char buf[2 * SHA512::DIGEST_SIZE + 1];
buf[2 * SHA512::DIGEST_SIZE] = 0;
for (int i = 0; i < SHA512::DIGEST_SIZE; i++)
sprintf(buf + i * 2, "%02x", digest[i]);
return std::string(buf);
}

68
dCommon/SHA512.h Normal file
View File

@@ -0,0 +1,68 @@
#pragma once
// C++
#include <string>
class SHA512 {
protected:
typedef unsigned char uint8;
typedef unsigned int uint32;
typedef unsigned long long uint64;
const static uint64 sha512_k[];
static const unsigned int SHA384_512_BLOCK_SIZE = (1024 / 8);
public:
void init();
void update(const unsigned char* message, unsigned int len);
void final(unsigned char* digest);
static const unsigned int DIGEST_SIZE = (512 / 8);
protected:
void transform(const unsigned char* message, unsigned int block_nb);
unsigned int m_tot_len;
unsigned int m_len;
unsigned char m_block[2 * SHA384_512_BLOCK_SIZE];
uint64 m_h[8];
};
std::string sha512(std::string input);
#define SHA2_SHFR(x, n) (x >> n)
#define SHA2_ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define SHA2_ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define SHA2_CH(x, y, z) ((x & y) ^ (~x & z))
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA512_F1(x) (SHA2_ROTR(x, 28) ^ SHA2_ROTR(x, 34) ^ SHA2_ROTR(x, 39))
#define SHA512_F2(x) (SHA2_ROTR(x, 14) ^ SHA2_ROTR(x, 18) ^ SHA2_ROTR(x, 41))
#define SHA512_F3(x) (SHA2_ROTR(x, 1) ^ SHA2_ROTR(x, 8) ^ SHA2_SHFR(x, 7))
#define SHA512_F4(x) (SHA2_ROTR(x, 19) ^ SHA2_ROTR(x, 61) ^ SHA2_SHFR(x, 6))
#define SHA2_UNPACK32(x, str) \
{ \
*((str) + 3) = (uint8) ((x) ); \
*((str) + 2) = (uint8) ((x) >> 8); \
*((str) + 1) = (uint8) ((x) >> 16); \
*((str) + 0) = (uint8) ((x) >> 24); \
}
#define SHA2_UNPACK64(x, str) \
{ \
*((str) + 7) = (uint8) ((x) ); \
*((str) + 6) = (uint8) ((x) >> 8); \
*((str) + 5) = (uint8) ((x) >> 16); \
*((str) + 4) = (uint8) ((x) >> 24); \
*((str) + 3) = (uint8) ((x) >> 32); \
*((str) + 2) = (uint8) ((x) >> 40); \
*((str) + 1) = (uint8) ((x) >> 48); \
*((str) + 0) = (uint8) ((x) >> 56); \
}
#define SHA2_PACK64(str, x) \
{ \
*(x) = ((uint64) *((str) + 7) ) \
| ((uint64) *((str) + 6) << 8) \
| ((uint64) *((str) + 5) << 16) \
| ((uint64) *((str) + 4) << 24) \
| ((uint64) *((str) + 3) << 32) \
| ((uint64) *((str) + 2) << 40) \
| ((uint64) *((str) + 1) << 48) \
| ((uint64) *((str) + 0) << 56); \
}

View File

@@ -1,6 +1,6 @@
set(DCOMMON_DCLIENT_SOURCES
"AssetManager.cpp"
"PackIndex.cpp"
"Pack.cpp"
"AssetManager.cpp"
PARENT_SCOPE
)

View File

@@ -1,12 +0,0 @@
#ifndef CLIENTVERSION_H
#define CLIENTVERSION_H
#include <cstdint>
namespace ClientVersion {
constexpr uint16_t major = 1;
constexpr uint16_t current = 10;
constexpr uint16_t minor = 64;
}
#endif // !CLIENTVERSION_H

View File

@@ -1,7 +1,6 @@
#include "dConfig.h"
#include <sstream>
#include <algorithm>
#include "BinaryPathFinder.h"
#include "GeneralUtils.h"

View File

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

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef DCOMMONVARS_H
#define DCOMMONVARS_H
#ifndef __DCOMMONVARS__H__
#define __DCOMMONVARS__H__
#include <cstdint>
#include <string>
@@ -34,89 +34,91 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
#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 CMSGHEADER BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GAME_MSG);
#define SEND_PACKET Game::server->Send(bitStream, sysAddr, false);
#define SEND_PACKET_BROADCAST Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
#define SEND_PACKET Game::server->Send(&bitStream, sysAddr, false);
#define SEND_PACKET_BROADCAST Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
//=========== TYPEDEFS ==========
using LOT = int32_t; //!< A LOT
using LWOOBJID = int64_t; //!< An object ID (should be unsigned actually but ok)
using TSkillID = int32_t; //!< A skill ID
using LWOCLONEID = uint32_t; //!< Used for Clone IDs
using LWOMAPID = uint16_t; //!< Used for Map IDs
using LWOINSTANCEID = uint16_t; //!< Used for Instance IDs
using PROPERTYCLONELIST = uint32_t; //!< Used for Property Clone IDs
using StripId = uint32_t;
typedef int32_t LOT; //!< A LOT
typedef int64_t LWOOBJID; //!< An object ID (should be unsigned actually but ok)
typedef int32_t TSkillID; //!< A skill ID
typedef uint32_t LWOCLONEID; //!< Used for Clone IDs
typedef uint16_t LWOMAPID; //!< Used for Map IDs
typedef uint16_t LWOINSTANCEID; //!< Used for Instance IDs
typedef uint32_t PROPERTYCLONELIST; //!< Used for Property Clone IDs
typedef uint32_t StripId;
constexpr LWOOBJID LWOOBJID_EMPTY = 0; //!< An empty object ID
constexpr LOT LOT_NULL = -1; //!< A null LOT
constexpr int32_t LOOTTYPE_NONE = 0; //!< No loot type available
constexpr float SECONDARY_PRIORITY = 1.0f; //!< Secondary Priority
constexpr uint32_t INVENTORY_MAX = 9999999; //!< The Maximum Inventory Size
constexpr LWOCLONEID LWOCLONEID_INVALID = -1; //!< Invalid LWOCLONEID
constexpr LWOINSTANCEID LWOINSTANCEID_INVALID = -1; //!< Invalid LWOINSTANCEID
constexpr LWOMAPID LWOMAPID_INVALID = -1; //!< Invalid LWOMAPID
constexpr uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
const LWOOBJID LWOOBJID_EMPTY = 0; //!< An empty object ID
const LOT LOT_NULL = -1; //!< A null LOT
const int32_t LOOTTYPE_NONE = 0; //!< No loot type available
const float SECONDARY_PRIORITY = 1.0f; //!< Secondary Priority
const uint32_t INVENTORY_MAX = 9999999; //!< The Maximum Inventory Size
const uint32_t LWOCLONEID_INVALID = -1; //!< Invalid LWOCLONEID
const uint16_t LWOINSTANCEID_INVALID = -1; //!< Invalid LWOINSTANCEID
const uint16_t LWOMAPID_INVALID = -1; //!< Invalid LWOMAPID
const uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
constexpr float PI = 3.14159f;
const float PI = 3.14159f;
//============ STRUCTS ==============
struct LWOSCENEID {
public:
constexpr LWOSCENEID() noexcept { m_sceneID = -1; m_layerID = 0; }
constexpr LWOSCENEID(int32_t sceneID) noexcept { m_sceneID = sceneID; m_layerID = 0; }
constexpr LWOSCENEID(int32_t sceneID, uint32_t layerID) noexcept { m_sceneID = sceneID; m_layerID = layerID; }
LWOSCENEID() { m_sceneID = -1; m_layerID = 0; }
LWOSCENEID(int sceneID) { m_sceneID = sceneID; m_layerID = 0; }
LWOSCENEID(int sceneID, unsigned int layerID) { m_sceneID = sceneID; m_layerID = layerID; }
constexpr LWOSCENEID& operator=(const LWOSCENEID& rhs) noexcept { m_sceneID = rhs.m_sceneID; m_layerID = rhs.m_layerID; return *this; }
constexpr LWOSCENEID& operator=(const int32_t rhs) noexcept { m_sceneID = rhs; m_layerID = 0; return *this; }
LWOSCENEID& operator=(const LWOSCENEID& rhs) { m_sceneID = rhs.m_sceneID; m_layerID = rhs.m_layerID; return *this; }
LWOSCENEID& operator=(const int rhs) { m_sceneID = rhs; m_layerID = 0; return *this; }
constexpr bool operator<(const LWOSCENEID& rhs) const noexcept { return (m_sceneID < rhs.m_sceneID || (m_sceneID == rhs.m_sceneID && m_layerID < rhs.m_layerID)); }
constexpr bool operator<(const int32_t rhs) const noexcept { return m_sceneID < rhs; }
bool operator<(const LWOSCENEID& rhs) const { return (m_sceneID < rhs.m_sceneID || (m_sceneID == rhs.m_sceneID && m_layerID < rhs.m_layerID)); }
bool operator<(const int rhs) const { return m_sceneID < rhs; }
constexpr bool operator==(const LWOSCENEID& rhs) const noexcept { return (m_sceneID == rhs.m_sceneID && m_layerID == rhs.m_layerID); }
constexpr bool operator==(const int32_t rhs) const noexcept { return m_sceneID == rhs; }
bool operator==(const LWOSCENEID& rhs) const { return (m_sceneID == rhs.m_sceneID && m_layerID == rhs.m_layerID); }
bool operator==(const int rhs) const { return m_sceneID == rhs; }
constexpr int32_t GetSceneID() const noexcept { return m_sceneID; }
constexpr uint32_t GetLayerID() const noexcept { return m_layerID; }
const int GetSceneID() const { return m_sceneID; }
const unsigned int GetLayerID() const { return m_layerID; }
constexpr void SetSceneID(const int32_t sceneID) noexcept { m_sceneID = sceneID; }
constexpr void SetLayerID(const uint32_t layerID) noexcept { m_layerID = layerID; }
void SetSceneID(const int sceneID) { m_sceneID = sceneID; }
void SetLayerID(const unsigned int layerID) { m_layerID = layerID; }
private:
int32_t m_sceneID;
uint32_t m_layerID;
int m_sceneID;
unsigned int m_layerID;
};
struct LWOZONEID {
public:
constexpr const LWOMAPID& GetMapID() const noexcept { return m_MapID; }
constexpr const LWOINSTANCEID& GetInstanceID() const noexcept { return m_InstanceID; }
constexpr const LWOCLONEID& GetCloneID() const noexcept { return m_CloneID; }
const LWOMAPID& GetMapID() const { return m_MapID; }
const LWOINSTANCEID& GetInstanceID() const { return m_InstanceID; }
const LWOCLONEID& GetCloneID() const { return m_CloneID; }
//In order: def constr, constr, assign op
constexpr LWOZONEID() noexcept = default;
constexpr LWOZONEID(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) noexcept { m_MapID = mapID; m_InstanceID = instanceID; m_CloneID = cloneID; }
constexpr LWOZONEID(const LWOZONEID& replacement) noexcept { *this = replacement; }
LWOZONEID() { m_MapID = LWOMAPID_INVALID; m_InstanceID = LWOINSTANCEID_INVALID; m_CloneID = LWOCLONEID_INVALID; }
LWOZONEID(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) { m_MapID = mapID; m_InstanceID = instanceID; m_CloneID = cloneID; }
LWOZONEID(const LWOZONEID& replacement) { *this = replacement; }
private:
LWOMAPID m_MapID = LWOMAPID_INVALID; //1000 for VE, 1100 for AG, etc...
LWOINSTANCEID m_InstanceID = LWOINSTANCEID_INVALID; //Instances host the same world, but on a different dWorld process.
LWOCLONEID m_CloneID = LWOCLONEID_INVALID; //To differentiate between "your property" and "my property". Always 0 for non-prop worlds.
LWOMAPID m_MapID; //1000 for VE, 1100 for AG, etc...
LWOINSTANCEID m_InstanceID; //Instances host the same world, but on a different dWorld process.
LWOCLONEID m_CloneID; //To differentiate between "your property" and "my property". Always 0 for non-prop worlds.
};
constexpr LWOSCENEID LWOSCENEID_INVALID = -1;
const LWOSCENEID LWOSCENEID_INVALID = -1;
struct LWONameValue {
uint32_t length = 0; //!< The length of the name
std::u16string name; //!< The name
LWONameValue() = default;
LWONameValue(void) {}
LWONameValue(const std::u16string& name) {
this->name = name;
this->length = static_cast<uint32_t>(name.length());
}
~LWONameValue(void) {}
};
struct FriendData {
@@ -158,4 +160,4 @@ public:
}
};
#endif //!DCOMMONVARS_H
#endif //!__DCOMMONVARS__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EADDFRIENDRESPONSECODE_H
#define EADDFRIENDRESPONSECODE_H
#ifndef __EADDFRIENDRESPONSECODE__H__
#define __EADDFRIENDRESPONSECODE__H__
#include <cstdint>
@@ -12,4 +12,4 @@ enum class eAddFriendResponseCode : uint8_t {
CANCELLED
};
#endif //!ADDFRIENDRESPONSECODE_H
#endif //!__ADDFRIENDRESPONSECODE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EADDFRIENDRESPONSETYPE_H
#define EADDFRIENDRESPONSETYPE_H
#ifndef __EADDFRIENDRESPONSETYPE__H__
#define __EADDFRIENDRESPONSETYPE__H__
#include <cstdint>
@@ -21,4 +21,4 @@ enum class eAddFriendResponseType : uint8_t {
FRIENDISFREETRIAL
};
#endif //!EADDFRIENDRESPONSETYPE_H
#endif //!__EADDFRIENDRESPONSETYPE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EANINMATIONFLAGS_H
#define EANINMATIONFLAGS_H
#ifndef __EANINMATIONFLAGS__H__
#define __EANINMATIONFLAGS__H__
#include <cstdint>
@@ -41,4 +41,4 @@ enum class eAnimationFlags : uint32_t {
IDLE_MISC12
};
#endif //!EANINMATIONFLAGS_H
#endif //!__EANINMATIONFLAGS__H__

View File

@@ -1,5 +1,5 @@
#ifndef EAUTHMESSAGETYPE_H
#define EAUTHMESSAGETYPE_H
#ifndef __EAUTHMESSAGETYPE__H__
#define __EAUTHMESSAGETYPE__H__
#include <cstdint>
@@ -12,4 +12,4 @@ enum class eAuthMessageType : uint32_t {
RUNTIME_CONFIG
};
#endif //!EAUTHMESSAGETYPE_H
#endif //!__EAUTHMESSAGETYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EBASICATTACKSUCCESSTYPES_H
#define EBASICATTACKSUCCESSTYPES_H
#ifndef __EBASICATTACKSUCCESSTYPES__H__
#define __EBASICATTACKSUCCESSTYPES__H__
#include <cstdint>
@@ -9,4 +9,4 @@ enum class eBasicAttackSuccessTypes : uint8_t {
FAILIMMUNE
};
#endif //!EBASICATTACKSUCCESSTYPES_H
#endif //!__EBASICATTACKSUCCESSTYPES__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EBLUEPRINTSAVERESPONSETYPE_H
#define EBLUEPRINTSAVERESPONSETYPE_H
#ifndef __EBLUEPRINTSAVERESPONSETYPE__H__
#define __EBLUEPRINTSAVERESPONSETYPE__H__
#include <cstdint>
@@ -23,4 +23,4 @@ enum class eBlueprintSaveResponseType : uint32_t {
FindMatchesFailed
};
#endif //!EBLUEPRINTSAVERESPONSETYPE_H
#endif //!__EBLUEPRINTSAVERESPONSETYPE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EBUBBLETYPE_H
#define EBUBBLETYPE_H
#ifndef __EBUBBLETYPE__H__
#define __EBUBBLETYPE__H__
#include <cstdint>
@@ -11,4 +11,4 @@ enum class eBubbleType : uint32_t {
SKUNK
};
#endif //!EBUBBLETYPE_H
#endif //!__EBUBBLETYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EBUILDTYPE_H
#define EBUILDTYPE_H
#ifndef __EBUILDTYPE__H__
#define __EBUILDTYPE__H__
#include <cstdint>
@@ -9,4 +9,4 @@ enum class eBuildType :uint32_t {
ON_PROPERTY
};
#endif //!EBUILDTYPE_H
#endif //!__EBUILDTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef ECHARACTERCREATIONRESPONSE_H
#define ECHARACTERCREATIONRESPONSE_H
#ifndef __ECHARACTERCREATIONRESPONSE__H__
#define __ECHARACTERCREATIONRESPONSE__H__
#include <cstdint>
@@ -11,4 +11,4 @@ enum class eCharacterCreationResponse : uint8_t {
CUSTOM_NAME_IN_USE
};
#endif //!ECHARACTERCREATIONRESPONSE_H
#endif //!__ECHARACTERCREATIONRESPONSE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef ECHARACTERVERSION_H
#define ECHARACTERVERSION_H
#ifndef __ECHARACTERVERSION__H__
#define __ECHARACTERVERSION__H__
#include <cstdint>
@@ -18,4 +18,4 @@ enum class eCharacterVersion : uint32_t {
UP_TO_DATE, // will become SPEED_BASE
};
#endif //!ECHARACTERVERSION_H
#endif //!__ECHARACTERVERSION__H__

View File

@@ -0,0 +1,31 @@
#ifndef __ECHATINTERNALMESSAGETYPE__H__
#define __ECHATINTERNALMESSAGETYPE__H__
#include <cstdint>
enum eChatInternalMessageType : uint32_t {
PLAYER_ADDED_NOTIFICATION = 0,
PLAYER_REMOVED_NOTIFICATION,
ADD_FRIEND,
ADD_BEST_FRIEND,
ADD_TO_TEAM,
ADD_BLOCK,
REMOVE_FRIEND,
REMOVE_BLOCK,
REMOVE_FROM_TEAM,
DELETE_TEAM,
REPORT,
PRIVATE_CHAT,
PRIVATE_CHAT_RESPONSE,
ANNOUNCEMENT,
MAIL_COUNT_UPDATE,
MAIL_SEND_NOTIFY,
REQUEST_USER_LIST,
FRIEND_LIST,
ROUTE_TO_PLAYER,
TEAM_UPDATE,
MUTE_UPDATE,
CREATE_TEAM,
};
#endif //!__ECHATINTERNALMESSAGETYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef ECHATMESSAGETYPE_H
#define ECHATMESSAGETYPE_H
#ifndef __ECHATMESSAGETYPE__H__
#define __ECHATMESSAGETYPE__H__
#include <cstdint>
@@ -72,9 +72,7 @@ enum class eChatMessageType :uint32_t {
UPDATE_DONATION,
PRG_CSR_COMMAND,
HEARTBEAT_REQUEST_FROM_WORLD,
UPDATE_FREE_TRIAL_STATUS,
// CUSTOM DLU MESSAGE ID FOR INTERNAL USE
CREATE_TEAM,
UPDATE_FREE_TRIAL_STATUS
};
#endif //!ECHATMESSAGETYPE_H
#endif //!__ECHATMESSAGETYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef ECINEMATICEVENT_H
#define ECINEMATICEVENT_H
#ifndef __ECINEMATICEVENT__H__
#define __ECINEMATICEVENT__H__
#include <cstdint>
@@ -9,4 +9,4 @@ enum class eCinematicEvent : uint32_t {
ENDED,
};
#endif //!ECINEMATICEVENT_H
#endif //!__ECINEMATICEVENT__H__

View File

@@ -1,5 +1,5 @@
#ifndef ECLIENTMESSAGETYPE_H
#define ECLIENTMESSAGETYPE_H
#ifndef __ECLIENTMESSAGETYPE__H__
#define __ECLIENTMESSAGETYPE__H__
#include <cstdint>
@@ -73,4 +73,4 @@ enum class eClientMessageType : uint32_t {
UGC_DOWNLOAD_FAILED = 120
};
#endif //!ECLIENTMESSAGETYPE_H
#endif //!__ECLIENTMESSAGETYPE__H__

View File

@@ -1,13 +1,14 @@
#ifndef ECONNECTIONTYPE_H
#define ECONNECTIONTYPE_H
#ifndef __ECONNECTIONTYPE__H__
#define __ECONNECTIONTYPE__H__
enum class eConnectionType : uint16_t {
SERVER = 0,
AUTH,
CHAT,
WORLD = 4,
CHAT_INTERNAL,
WORLD,
CLIENT,
MASTER
};
#endif //!ECONNECTIONTYPE_H
#endif //!__ECONNECTIONTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef ECONTROLSCHEME_H
#define ECONTROLSCHEME_H
#ifndef __ECONTROLSCHEME__H__
#define __ECONTROLSCHEME__H__
#include <cstdint>
@@ -15,4 +15,4 @@ enum class eControlScheme : uint32_t {
SCHEME_WEAR_A_ROBOT //== freecam?
};
#endif //!ECONTROLSCHEME_H
#endif //!__ECONTROLSCHEME__H__

View File

@@ -1,5 +1,5 @@
#ifndef ECYCLINGMODE_H
#define ECYCLINGMODE_H
#ifndef __ECYCLINGMODE__H__
#define __ECYCLINGMODE__H__
#include <cstdint>
@@ -8,4 +8,4 @@ enum class eCyclingMode : uint32_t {
DISALLOW_CYCLING
};
#endif //!ECYCLINGMODE_H
#endif //!__ECYCLINGMODE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EENDBEHAVIOR_H
#define EENDBEHAVIOR_H
#ifndef __EENDBEHAVIOR__H__
#define __EENDBEHAVIOR__H__
#include <cstdint>
@@ -8,4 +8,4 @@ enum class eEndBehavior : uint32_t {
WAIT
};
#endif //!EENDBEHAVIOR_H
#endif //!__EENDBEHAVIOR__H__

View File

@@ -1,5 +1,5 @@
#ifndef EGAMEACTIVITY_H
#define EGAMEACTIVITY_H
#ifndef __EGAMEACTIVITY__H__
#define __EGAMEACTIVITY__H__
#include <cstdint>
@@ -12,4 +12,4 @@ enum class eGameActivity : uint32_t {
PET_TAMING
};
#endif //!EGAMEACTIVITY_H
#endif //!__EGAMEACTIVITY__H__

View File

@@ -1,5 +1,5 @@
#ifndef EGAMEMASTERLEVEL_H
#define EGAMEMASTERLEVEL_H
#ifndef __EGAMEMASTERLEVEL__H__
#define __EGAMEMASTERLEVEL__H__
#include <cstdint>
@@ -17,4 +17,4 @@ enum class eGameMasterLevel : uint8_t {
};
#endif //!EGAMEMASTERLEVEL_H
#endif //!__EGAMEMASTERLEVEL__H__

View File

@@ -1,5 +1,5 @@
#ifndef EGAMEMESSAGETYPE_H
#define EGAMEMESSAGETYPE_H
#ifndef __EGAMEMESSAGETYPE__H__
#define __EGAMEMESSAGETYPE__H__
#include <cstdint>
@@ -790,10 +790,9 @@ enum class eGameMessageType : uint16_t {
GET_MISSION_TYPE_STATES = 853,
GET_TIME_PLAYED = 854,
SET_MISSION_VIEWED = 855,
HKX_VEHICLE_LOADED = 856,
SLASH_COMMAND_TEXT_FEEDBACK = 857,
SLASH_COMMAND_TEXT_FEEDBACK = 856,
HANDLE_SLASH_COMMAND_KORE_DEBUGGER = 857,
BROADCAST_TEXT_TO_CHATBOX = 858,
HANDLE_SLASH_COMMAND_KORE_DEBUGGER = 859,
OPEN_PROPERTY_MANAGEMENT = 860,
OPEN_PROPERTY_VENDOR = 861,
VOTE_ON_PROPERTY = 862,
@@ -1611,4 +1610,4 @@ struct magic_enum::customize::enum_range<eGameMessageType> {
static constexpr int max = 1772;
};
#endif //!EGAMEMESSAGETYPE_H
#endif //!__EGAMEMESSAGETYPE__H__

View File

@@ -1,6 +1,6 @@
#ifndef EHELPTYPE_H
#define EHELPTYPE_H
#ifndef __EHELPTYPE__H__
#define __EHELPTYPE__H__
#include <cstdint>
@@ -38,4 +38,4 @@ enum class eHelpType : int32_t {
UI_INVENTORY_FULL_CANNOT_PICKUP_ITEM = 86
};
#endif //!EHELPTYPE_H
#endif //!__EHELPTYPE__H__

View File

@@ -1,12 +1,9 @@
#pragma once
#ifndef EINVENTORYTYPE_H
#define EINVENTORYTYPE_H
#ifndef __EINVENTORYTYPE__H__
#define __EINVENTORYTYPE__H__
#include <cstdint>
#include "magic_enum.hpp"
static const uint8_t NUMBER_OF_INVENTORIES = 17;
/**
* Represents the different types of inventories an entity may have
@@ -59,10 +56,4 @@ public:
};
};
template <>
struct magic_enum::customize::enum_range<eInventoryType> {
static constexpr int min = 0;
static constexpr int max = 16;
};
#endif //!EINVENTORYTYPE_H
#endif //!__EINVENTORYTYPE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EITEMSETPASSIVEABILITYID_H
#define EITEMSETPASSIVEABILITYID_H
#ifndef __EITEMSETPASSIVEABILITYID__H__
#define __EITEMSETPASSIVEABILITYID__H__
enum class eItemSetPassiveAbilityID {
EngineerRank1 = 2,
@@ -55,4 +55,4 @@ enum class eItemSetPassiveAbilityID {
LightningSpinjitzu = 52
};
#endif //!EITEMSETPASSIVEABILITYID_H
#endif //!__EITEMSETPASSIVEABILITYID__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EITEMTYPE_H
#define EITEMTYPE_H
#ifndef __EITEMTYPE__H__
#define __EITEMTYPE__H__
#include <cstdint>
@@ -33,4 +33,4 @@ enum class eItemType : int32_t {
MOUNT
};
#endif //!EITEMTYPE_H
#endif //!__EITEMTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EKILLTYPE_H
#define EKILLTYPE_H
#ifndef __EKILLTYPE__H__
#define __EKILLTYPE__H__
#include <cstdint>
@@ -8,4 +8,4 @@ enum class eKillType : uint32_t {
SILENT
};
#endif //!EKILLTYPE_H
#endif //!__EKILLTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef ELOGINRESPONSE_H
#define ELOGINRESPONSE_H
#ifndef __ELOGINRESPONSE__H__
#define __ELOGINRESPONSE__H__
#include <cstdint>
@@ -21,4 +21,4 @@ enum class eLoginResponse : uint8_t {
ACCOUNT_NOT_ACTIVATED
};
#endif //!ELOGINRESPONSE_H
#endif //!__ELOGINRESPONSE__H__

View File

@@ -1,5 +1,5 @@
#ifndef ELOOTSOURCETYPE_H
#define ELOOTSOURCETYPE_H
#ifndef __ELOOTSOURCETYPE__H__
#define __ELOOTSOURCETYPE__H__
#include <cstdint>
@@ -28,4 +28,4 @@ enum class eLootSourceType : uint32_t {
RELOCATE
};
#endif //!ELOOTSOURCETYPE_H
#endif //!__ELOOTSOURCETYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EMASTERMESSAGETYPE_H
#define EMASTERMESSAGETYPE_H
#ifndef __EMASTERMESSAGETYPE__H__
#define __EMASTERMESSAGETYPE__H__
#include <cstdint>
@@ -33,4 +33,4 @@ enum class eMasterMessageType : uint32_t {
NEW_SESSION_ALERT
};
#endif //!EMASTERMESSAGETYPE_H
#endif //!__EMASTERMESSAGETYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EMATCHUPDATE_H
#define EMATCHUPDATE_H
#ifndef __EMATCHUPDATE__H__
#define __EMATCHUPDATE__H__
#include <cstdint>
@@ -14,4 +14,4 @@ enum class eMatchUpdate : int32_t {
PLAYER_UPDATE
};
#endif //!EMATCHUPDATE_H
#endif //!__EMATCHUPDATE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EMISSIONLOCKSTATE_H
#define EMISSIONLOCKSTATE_H
#ifndef __EMISSIONLOCKSTATE__H__
#define __EMISSIONLOCKSTATE__H__
enum class eMissionLockState : int {
LOCKED,
@@ -9,4 +9,4 @@ enum class eMissionLockState : int {
UNLOCKED,
};
#endif //!EMISSIONLOCKSTATE_H
#endif //!__EMISSIONLOCKSTATE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef MISSIONSTATE_H
#define MISSIONSTATE_H
#ifndef __MISSIONSTATE__H__
#define __MISSIONSTATE__H__
/**
* Represents the possible states a mission can be in
@@ -53,4 +53,4 @@ enum class eMissionState : int {
COMPLETE_READY_TO_COMPLETE = 12
};
#endif //!MISSIONSTATE_H
#endif //!__MISSIONSTATE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef EMISSIONTASKTYPE_H
#define EMISSIONTASKTYPE_H
#ifndef __EMISSIONTASKTYPE__H__
#define __EMISSIONTASKTYPE__H__
enum class eMissionTaskType : int {
UNKNOWN = -1,
@@ -40,4 +40,4 @@ enum class eMissionTaskType : int {
DONATION
};
#endif //!EMISSIONTASKTYPE_H
#endif //!__EMISSIONTASKTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EMOVEMENTPLATFORMSTATE_H
#define EMOVEMENTPLATFORMSTATE_H
#ifndef __EMOVEMENTPLATFORMSTATE__H__
#define __EMOVEMENTPLATFORMSTATE__H__
#include <cstdint>
@@ -13,4 +13,4 @@ enum class eMovementPlatformState : uint32_t
Stopped = 0b01100
};
#endif //!EMOVEMENTPLATFORMSTATE_H
#endif //!__EMOVEMENTPLATFORMSTATE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EOBJECTBITS_H
#define EOBJECTBITS_H
#ifndef __EOBJECTBITS__H__
#define __EOBJECTBITS__H__
#include <cstdint>
@@ -10,4 +10,4 @@ enum class eObjectBits : size_t {
CHARACTER = 60
};
#endif //!EOBJECTBITS_H
#endif //!__EOBJECTBITS__H__

View File

@@ -1,5 +1,5 @@
#ifndef EOBJECTWORLDSTATE_H
#define EOBJECTWORLDSTATE_H
#ifndef __EOBJECTWORLDSTATE__H__
#define __EOBJECTWORLDSTATE__H__
#include <cstdint>
@@ -9,4 +9,4 @@ enum class eObjectWorldState : uint32_t {
INVENTORY
};
#endif //!EOBJECTWORLDSTATE_H
#endif //!__EOBJECTWORLDSTATE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EPACKAGETYPE_H
#define EPACKAGETYPE_H
#ifndef __EPACKAGETYPE__H__
#define __EPACKAGETYPE__H__
enum class ePackageType {
INVALID = -1,
@@ -10,4 +10,4 @@ enum class ePackageType {
};
#endif //!EPACKAGETYPE_H
#endif //!__EPACKAGETYPE__H__

View File

@@ -2,8 +2,8 @@
#include <cstdint>
#ifndef EPERMISSIONMAP_H
#define EPERMISSIONMAP_H
#ifndef __EPERMISSIONMAP__H__
#define __EPERMISSIONMAP__H__
/**
* Bitmap of permissions and restrictions for characters.
@@ -29,4 +29,4 @@ enum class ePermissionMap : uint64_t {
RestrictedChatAccess = 0x1 << 6,
};
#endif //!EPERMISSIONMAP_H
#endif //!__EPERMISSIONMAP__H__

View File

@@ -1,5 +1,5 @@
#ifndef EPETABILITYTYPE_H
#define EPETABILITYTYPE_H
#ifndef __EPETABILITYTYPE__H__
#define __EPETABILITYTYPE__H__
#include <cstdint>
@@ -10,4 +10,4 @@ enum class ePetAbilityType : uint32_t {
DigAtPosition
};
#endif //!EPETABILITYTYPE_H
#endif //!__EPETABILITYTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EPETTAMINGNOTIFYTYPE_H
#define EPETTAMINGNOTIFYTYPE_H
#ifndef __EPETTAMINGNOTIFYTYPE__H__
#define __EPETTAMINGNOTIFYTYPE__H__
#include <cstdint>
@@ -12,4 +12,4 @@ enum class ePetTamingNotifyType : uint32_t {
NAMINGPET
};
#endif //!EPETTAMINGNOTIFYTYPE_H
#endif //!__EPETTAMINGNOTIFYTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EPHYSICSEFFECTTYPE_H
#define EPHYSICSEFFECTTYPE_H
#ifndef __EPHYSICSEFFECTTYPE__H__
#define __EPHYSICSEFFECTTYPE__H__
#include <cstdint>
@@ -12,4 +12,4 @@ enum class ePhysicsEffectType : uint32_t {
FRICTION
};
#endif //!EPHYSICSEFFECTTYPE_H
#endif //!__EPHYSICSEFFECTTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EPLAYERFLAG_H
#define EPLAYERFLAG_H
#ifndef __EPLAYERFLAG__H__
#define __EPLAYERFLAG__H__
#include <cstdint>
@@ -170,4 +170,4 @@ enum ePlayerFlag : int32_t {
DLU_SKIP_CINEMATICS = 1'000'000,
};
#endif //!EPLAYERFLAG_H
#endif //!__EPLAYERFLAG__H__

View File

@@ -1,5 +1,5 @@
#ifndef EQUICKBUILDFAILREASON_H
#define EQUICKBUILDFAILREASON_H
#ifndef __EQUICKBUILDFAILREASON__H__
#define __EQUICKBUILDFAILREASON__H__
#include <cstdint>
@@ -10,4 +10,4 @@ enum class eQuickBuildFailReason : uint32_t {
BUILD_ENDED
};
#endif //!EQUICKBUILDFAILREASON_H
#endif //!__EQUICKBUILDFAILREASON__H__

View File

@@ -1,5 +1,5 @@
#ifndef EQUICKBUILDSTATE_H
#define EQUICKBUILDSTATE_H
#ifndef __EQUICKBUILDSTATE__H__
#define __EQUICKBUILDSTATE__H__
#include <cstdint>
@@ -12,4 +12,4 @@ enum class eQuickBuildState : uint32_t {
};
#endif //!EQUICKBUILDSTATE_H
#endif //!__EQUICKBUILDSTATE__H__

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef ERACINGTASKPARAM_H
#define ERACINGTASKPARAM_H
#ifndef __ERACINGTASKPARAM__H__
#define __ERACINGTASKPARAM__H__
#include <cstdint>
@@ -22,4 +22,4 @@ enum class eRacingTaskParam : int32_t {
SMASH_SPECIFIC_SMASHABLE
};
#endif //!ERACINGTASKPARAM_H
#endif //!__ERACINGTASKPARAM__H__

View File

@@ -1,5 +1,5 @@
#ifndef ERENAMERESPONSE_H
#define ERENAMERESPONSE_H
#ifndef __ERENAMERESPONSE__H__
#define __ERENAMERESPONSE__H__
#include <cstdint>
@@ -12,4 +12,4 @@ enum class eRenameResponse : uint8_t {
};
#endif //!ERENAMERESPONSE_H
#endif //!__ERENAMERESPONSE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EREPLICACOMPONENTTYPE_H
#define EREPLICACOMPONENTTYPE_H
#ifndef __EREPLICACOMPONENTTYPE__H__
#define __EREPLICACOMPONENTTYPE__H__
#include <cstdint>
@@ -106,7 +106,7 @@ enum class eReplicaComponentType : uint32_t {
INTERACTION_MANAGER,
DONATION_VENDOR,
COMBAT_MEDIATOR,
ACHIEVEMENT_VENDOR,
COMMENDATION_VENDOR,
GATE_RUSH_CONTROL,
RAIL_ACTIVATOR,
ROLLER,
@@ -124,4 +124,4 @@ enum class eReplicaComponentType : uint32_t {
DESTROYABLE = 1000 // Actually 7
};
#endif //!EREPLICACOMPONENTTYPE_H
#endif //!__EREPLICACOMPONENTTYPE__H__

View File

@@ -1,5 +1,5 @@
#ifndef EREPLICAPACKETTYPE_H
#define EREPLICAPACKETTYPE_H
#ifndef __EREPLICAPACKETTYPE__H__
#define __EREPLICAPACKETTYPE__H__
#include <cstdint>
@@ -9,4 +9,4 @@ enum class eReplicaPacketType : uint8_t {
DESTRUCTION
};
#endif //!EREPLICAPACKETTYPE_H
#endif //!__EREPLICAPACKETTYPE__H__

View File

@@ -1,21 +0,0 @@
#ifndef EREPONSEMOVEITEMBETWEENINVENTORYTYPECODE_H
#define EREPONSEMOVEITEMBETWEENINVENTORYTYPECODE_H
#include <cstdint>
enum class eReponseMoveItemBetweenInventoryTypeCode : int32_t {
SUCCESS,
FAIL_GENERIC,
FAIL_INV_FULL,
FAIL_ITEM_NOT_FOUND,
FAIL_CANT_MOVE_TO_THAT_INV_TYPE,
FAIL_NOT_NEAR_BANK,
FAIL_CANT_SWAP_ITEMS,
FAIL_SOURCE_TYPE,
FAIL_WRONG_DEST_TYPE,
FAIL_SWAP_DEST_TYPE,
FAIL_CANT_MOVE_THINKING_HAT,
FAIL_DISMOUNT_BEFORE_MOVING
};
#endif //!EREPONSEMOVEITEMBETWEENINVENTORYTYPECODE_H

View File

@@ -1,5 +1,5 @@
#ifndef ESERVERDISCONNECTIDENTIFIERS_H
#define ESERVERDISCONNECTIDENTIFIERS_H
#ifndef __ESERVERDISCONNECTIDENTIFIERS__H__
#define __ESERVERDISCONNECTIDENTIFIERS__H__
#include <cstdint>
@@ -21,4 +21,4 @@ enum class eServerDisconnectIdentifiers : uint32_t {
PLAY_SCHEDULE_TIME_DONE
};
#endif //!ESERVERDISCONNECTIDENTIFIERS_H
#endif //!__ESERVERDISCONNECTIDENTIFIERS__H__

View File

@@ -1,5 +1,5 @@
#ifndef ESERVERMESSAGETYPE_H
#define ESERVERMESSAGETYPE_H
#ifndef __ESERVERMESSAGETYPE__H__
#define __ESERVERMESSAGETYPE__H__
#include <cstdint>
//! The Internal Server Packet Identifiers
@@ -9,4 +9,4 @@ enum class eServerMessageType : uint32_t {
GENERAL_NOTIFY
};
#endif //!ESERVERMESSAGETYPE_H
#endif //!__ESERVERMESSAGETYPE__H__

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