mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-16 20:24:39 -06:00
Compare commits
3 Commits
script-deb
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec37c4fd78 | ||
|
|
42327a1b8e | ||
|
|
578799464e |
154
.github/copilot-instructions.md
vendored
Normal file
154
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
# Darkflame Universe Server Development Instructions
|
||||
|
||||
Darkflame Universe (DLU) is a LEGO Universe server emulator written in C++ with a multi-server architecture (AuthServer, ChatServer, MasterServer, WorldServer). Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
|
||||
|
||||
## Working Effectively
|
||||
|
||||
### Bootstrap, Build, and Test - REQUIRED STEPS
|
||||
Execute these commands in order for ANY development work. NEVER CANCEL builds - they take time but work reliably:
|
||||
|
||||
```bash
|
||||
# 1. Install system dependencies (Ubuntu/Debian)
|
||||
sudo apt update && sudo apt install -y build-essential gcc zlib1g-dev libssl-dev openssl mariadb-server cmake
|
||||
|
||||
# 2. Initialize git submodules (CRITICAL - project won't build without this)
|
||||
git submodule update --init --recursive
|
||||
|
||||
# 3. Build using the provided script
|
||||
./build.sh -j2
|
||||
```
|
||||
- **Build time: ~6 minutes. NEVER CANCEL. Set timeout to 720+ seconds (12+ minutes).**
|
||||
- **Uses CMake 3.25-3.31 (confirmed working with 3.31.6)**
|
||||
- **Requires g++11+ (confirmed working with g++ 13.3.0)**
|
||||
|
||||
### Alternative Build Methods
|
||||
```bash
|
||||
# Using CMake presets (CI-style)
|
||||
cmake --workflow --preset ci-ubuntu-22.04
|
||||
|
||||
# Manual CMake (for custom configurations)
|
||||
mkdir -p build && cd build
|
||||
cmake -DCMAKE_BUILD_TYPE="Release" ..
|
||||
cmake --build . --config Release -j2
|
||||
```
|
||||
- **Same timing: ~6 minutes. NEVER CANCEL. Set timeout to 720+ seconds.**
|
||||
|
||||
### Run Tests
|
||||
```bash
|
||||
cd build
|
||||
ctest --output-on-failure
|
||||
```
|
||||
- **Test time: <4 seconds. Set timeout to 30+ seconds.**
|
||||
- **91 tests run, all should pass**
|
||||
- **Tests are built automatically when ENABLE_TESTING=1 in CMakeVariables.txt**
|
||||
|
||||
### Database Setup (for runtime testing)
|
||||
```bash
|
||||
# Start MariaDB
|
||||
sudo systemctl start mysql
|
||||
|
||||
# Create test database and user
|
||||
sudo mysql -e "CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'testpass'; GRANT ALL ON *.* TO 'testuser'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES; CREATE DATABASE testdarkflame;"
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
### Build Validation
|
||||
- **ALWAYS run the bootstrapping steps first** before making any code changes
|
||||
- **ALWAYS build and test your changes** before considering them complete
|
||||
- Build output should include all server binaries: AuthServer, ChatServer, MasterServer, WorldServer
|
||||
- Build directory contains required files: `*.ini` configs, `navmeshes/`, `migrations/`, `vanity/`, `blocklist.dcf`, `libmariadbcpp.so`
|
||||
|
||||
### Runtime Validation
|
||||
The servers can be started for basic validation:
|
||||
```bash
|
||||
cd build
|
||||
./MasterServer
|
||||
```
|
||||
- **Server will start but complain about missing client files (this is expected)**
|
||||
- **Database connections work with proper configuration in sharedconfig.ini**
|
||||
- **For full server testing, LEGO Universe client files are required (not available in this repository)**
|
||||
|
||||
### Code Validation
|
||||
**ALWAYS validate your changes by**:
|
||||
1. Building successfully with no new compilation errors
|
||||
2. Running the test suite and confirming all tests pass
|
||||
3. Starting MasterServer to verify basic functionality
|
||||
4. **Use .editorconfig** - code style uses tabs (width=4), Unix line endings, trailing whitespace removal
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Project Structure
|
||||
```
|
||||
/home/runner/work/DarkflameServer/DarkflameServer/
|
||||
├── dAuthServer/ # Authentication server code
|
||||
├── dChatServer/ # Chat server code
|
||||
├── dMasterServer/ # Master server (main coordinator)
|
||||
├── dWorldServer/ # World/game server code
|
||||
├── dCommon/ # Shared common utilities
|
||||
├── dDatabase/ # Database abstraction layer
|
||||
├── dGame/ # Core game logic, components, behaviors
|
||||
├── dScripts/ # Game scripts (NPCs, quests, etc.)
|
||||
├── dNet/ # Network utilities
|
||||
├── dPhysics/ # Physics integration
|
||||
├── tests/ # Unit tests (GoogleTest)
|
||||
├── migrations/ # Database schema migrations
|
||||
├── thirdparty/ # External dependencies
|
||||
├── build.sh # Main build script
|
||||
├── CMakeVariables.txt # Build configuration variables
|
||||
└── CMakePresets.json # CMake preset configurations
|
||||
```
|
||||
|
||||
### Key Files to Know
|
||||
- **CMakeVariables.txt**: Build configuration (testing enabled, MariaDB jobs, etc.)
|
||||
- **build/sharedconfig.ini**: Database connection, client location, server settings
|
||||
- **build/masterconfig.ini**: Master server port and startup configuration
|
||||
- **CONTRIBUTING.md**: Code style guidelines and commit message format
|
||||
- **docs/Commands.md**: Complete list of in-game server commands
|
||||
|
||||
### Build Configuration
|
||||
Located in `CMakeVariables.txt`:
|
||||
- `ENABLE_TESTING=1` - Unit tests enabled (keep enabled)
|
||||
- `MARIADB_CONNECTOR_COMPILE_JOBS=1` - Parallel compilation jobs for MariaDB connector
|
||||
- `CDCLIENT_CACHE_ALL=0` - Database caching strategy
|
||||
|
||||
### Common Commands Reference
|
||||
```bash
|
||||
# Build from clean state
|
||||
rm -rf build && ./build.sh -j2
|
||||
|
||||
# Run specific test
|
||||
cd build && ctest -R "TestName" --output-on-failure
|
||||
|
||||
# Check which servers were built
|
||||
cd build && ls -la *Server
|
||||
|
||||
# View build configuration
|
||||
cat CMakeVariables.txt
|
||||
|
||||
# Check git submodules status
|
||||
git submodule status
|
||||
```
|
||||
|
||||
### Important Notes
|
||||
- **Client files are NOT included** - this is only the server emulator
|
||||
- **Database can use SQLite or MariaDB** - SQLite recommended for development since it's lighter and doesn't require an external service
|
||||
- **Multi-server architecture** requires all 4 servers to run a complete setup
|
||||
- **Network ports**: Auth (1001), Chat (2005), Master (2000), World (3000+)
|
||||
- **Development uses Debug builds**, production uses Release builds
|
||||
- **GM level 0** = normal player, **GM level 8-9** = admin privileges
|
||||
|
||||
## Troubleshooting
|
||||
- **"Asset bundle not found"**: Expected without LEGO Universe client files
|
||||
- **"Submodule errors"**: Run `git submodule update --init --recursive`
|
||||
- **"CMake version errors"**: Requires CMake 3.25-3.31
|
||||
- **"MariaDB connection errors"**: Check database setup and sharedconfig.ini
|
||||
- **"Permission denied on port"**: Run `sudo setcap 'cap_net_bind_service=+ep' AuthServer` for ports <1024
|
||||
|
||||
### CI Information
|
||||
- **GitHub Actions** runs builds on Windows, Ubuntu, and macOS
|
||||
- **Build matrix** tests multiple configurations via CMake presets
|
||||
- **All tests must pass** for CI to succeed
|
||||
- **Build artifacts** are automatically generated and uploaded
|
||||
|
||||
**Remember: This is a complex game server requiring LEGO Universe client files for full functionality, but the server has the capability to mock everything that's needed to test without the client since cdclient can be mocked and the database can be mocked as well.**
|
||||
@@ -19,7 +19,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Export the compile commands for debuggi
|
||||
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")
|
||||
set(FETCHCONTENT_QUIET FALSE) # GLM takes a long time to clone, this will at least show _something_ while its downloading
|
||||
|
||||
# Read variables from file
|
||||
FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables)
|
||||
@@ -307,7 +306,7 @@ add_subdirectory(dServer)
|
||||
add_subdirectory(dWeb)
|
||||
|
||||
# Create a list of common libraries shared between all binaries
|
||||
set(COMMON_LIBRARIES glm::glm "dCommon" "dDatabase" "dNet" "raknet" "magic_enum")
|
||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "magic_enum")
|
||||
|
||||
# Add platform specific common libraries
|
||||
if(UNIX)
|
||||
|
||||
@@ -6,8 +6,6 @@ FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG release-1.12.1
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW 1
|
||||
)
|
||||
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
|
||||
@@ -52,7 +52,6 @@ int main(int argc, char** argv) {
|
||||
//Create all the objects we need to run our service:
|
||||
Server::SetupLogger("AuthServer");
|
||||
if (!Game::logger) return EXIT_FAILURE;
|
||||
Game::config->LogSettings();
|
||||
|
||||
LOG("Starting Auth server...");
|
||||
LOG("Version: %s", PROJECT_VERSION);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
set(DCHATFILTER_SOURCES "dChatFilter.cpp")
|
||||
|
||||
add_library(dChatFilter STATIC ${DCHATFILTER_SOURCES})
|
||||
target_link_libraries(dChatFilter dDatabase glm::glm)
|
||||
target_link_libraries(dChatFilter dDatabase)
|
||||
|
||||
@@ -14,6 +14,6 @@ add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}
|
||||
add_library(dChatServer ${DCHATSERVER_SOURCES})
|
||||
target_include_directories(dChatServer PRIVATE "${PROJECT_SOURCE_DIR}/dServer" "${PROJECT_SOURCE_DIR}/dChatFilter")
|
||||
|
||||
target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter glm::glm)
|
||||
target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter)
|
||||
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer mongoose dWeb)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
|
||||
if (!receiver.ignoredPlayers.empty()) {
|
||||
LOG_DEBUG("Player %llu already has an ignore list, but is requesting it again.", playerId);
|
||||
} else {
|
||||
auto ignoreList = Database::Get()->GetIgnoreList(playerId);
|
||||
auto ignoreList = Database::Get()->GetIgnoreList(static_cast<uint32_t>(playerId));
|
||||
if (ignoreList.empty()) {
|
||||
LOG_DEBUG("Player %llu has no ignores", playerId);
|
||||
return;
|
||||
@@ -43,6 +43,7 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
|
||||
for (auto& ignoredPlayer : ignoreList) {
|
||||
receiver.ignoredPlayers.emplace_back(ignoredPlayer.name, ignoredPlayer.id);
|
||||
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::PERSISTENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,8 +114,9 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
|
||||
}
|
||||
|
||||
if (ignoredPlayerId != LWOOBJID_EMPTY) {
|
||||
Database::Get()->AddIgnore(playerId, ignoredPlayerId);
|
||||
Database::Get()->AddIgnore(static_cast<uint32_t>(playerId), static_cast<uint32_t>(ignoredPlayerId));
|
||||
GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::PERSISTENT);
|
||||
|
||||
receiver.ignoredPlayers.emplace_back(toIgnoreStr, ignoredPlayerId);
|
||||
LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str());
|
||||
@@ -155,7 +157,7 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
Database::Get()->RemoveIgnore(playerId, toRemove->playerId);
|
||||
Database::Get()->RemoveIgnore(static_cast<uint32_t>(playerId), static_cast<uint32_t>(toRemove->playerId));
|
||||
receiver.ignoredPlayers.erase(toRemove, receiver.ignoredPlayers.end());
|
||||
|
||||
CBITSTREAM;
|
||||
|
||||
@@ -35,6 +35,7 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
||||
FriendData fd;
|
||||
fd.isFTP = false; // not a thing in DLU
|
||||
fd.friendID = friendData.friendID;
|
||||
GeneralUtils::SetBit(fd.friendID, eObjectBits::PERSISTENT);
|
||||
GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER);
|
||||
|
||||
fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
|
||||
@@ -160,7 +161,9 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
|
||||
|
||||
// Set the bits
|
||||
GeneralUtils::SetBit(queryPlayerID, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(queryPlayerID, eObjectBits::PERSISTENT);
|
||||
GeneralUtils::SetBit(queryFriendID, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(queryFriendID, eObjectBits::PERSISTENT);
|
||||
|
||||
// Since this player can either be the friend of someone else or be friends with someone else
|
||||
// their column in the database determines what bit gets set. When the value hits 3, they
|
||||
@@ -315,6 +318,7 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
|
||||
}
|
||||
|
||||
// Convert friendID to LWOOBJID
|
||||
GeneralUtils::SetBit(friendID, eObjectBits::PERSISTENT);
|
||||
GeneralUtils::SetBit(friendID, eObjectBits::CHARACTER);
|
||||
|
||||
Database::Get()->RemoveFriend(playerID, friendID);
|
||||
|
||||
@@ -59,7 +59,6 @@ int main(int argc, char** argv) {
|
||||
//Create all the objects we need to run our service:
|
||||
Server::SetupLogger("ChatServer");
|
||||
if (!Game::logger) return EXIT_FAILURE;
|
||||
Game::config->LogSettings();
|
||||
|
||||
//Read our config:
|
||||
|
||||
|
||||
@@ -54,8 +54,6 @@ elseif (WIN32)
|
||||
zlib
|
||||
URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip
|
||||
URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW 1
|
||||
)
|
||||
|
||||
# Disable warning about no project version.
|
||||
@@ -76,6 +74,5 @@ else ()
|
||||
endif ()
|
||||
|
||||
target_link_libraries(dCommon
|
||||
PUBLIC glm::glm
|
||||
PRIVATE ZLIB::ZLIB bcrypt tinyxml2
|
||||
INTERFACE dDatabase)
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include "Game.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
|
||||
enum eInventoryType : uint32_t;
|
||||
enum class eObjectBits : size_t;
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
@@ -246,7 +244,7 @@ namespace GeneralUtils {
|
||||
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
|
||||
*/
|
||||
template <typename T>
|
||||
[[nodiscard]] std::optional<T> TryParse(const std::string_view strX, const std::string_view strY, const std::string_view strZ) {
|
||||
[[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;
|
||||
|
||||
@@ -254,7 +252,7 @@ namespace GeneralUtils {
|
||||
if (!y) return std::nullopt;
|
||||
|
||||
const auto z = TryParse<float>(strZ);
|
||||
return z ? std::make_optional<T>(x.value(), y.value(), z.value()) : std::nullopt;
|
||||
return z ? std::make_optional<NiPoint3>(x.value(), y.value(), z.value()) : std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,8 +261,8 @@ namespace GeneralUtils {
|
||||
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
|
||||
*/
|
||||
template <typename T>
|
||||
[[nodiscard]] std::optional<T> TryParse(const std::span<const std::string> str) {
|
||||
return (str.size() == 3) ? TryParse<T>(str[0], str[1], str[2]) : std::nullopt;
|
||||
[[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>
|
||||
|
||||
@@ -6,14 +6,10 @@
|
||||
\brief Defines a point in space in XYZ coordinates
|
||||
*/
|
||||
|
||||
|
||||
class NiPoint3;
|
||||
class NiQuaternion;
|
||||
typedef NiPoint3 Vector3; //!< The Vector3 class is technically the NiPoint3 class, but typedef'd for clarity in some cases
|
||||
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
//! A custom class the defines a point in space
|
||||
class NiPoint3 {
|
||||
public:
|
||||
@@ -25,12 +21,6 @@ public:
|
||||
//! Initializer
|
||||
constexpr NiPoint3() = default;
|
||||
|
||||
constexpr NiPoint3(const glm::vec3& vec) noexcept
|
||||
: x{ vec.x }
|
||||
, y{ vec.y }
|
||||
, z{ vec.z } {
|
||||
}
|
||||
|
||||
//! Initializer
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#endif
|
||||
|
||||
#include "NiQuaternion.h"
|
||||
#include <glm/ext/quaternion_float.hpp>
|
||||
|
||||
// MARK: Getters / Setters
|
||||
|
||||
|
||||
@@ -3,18 +3,37 @@
|
||||
// C++
|
||||
#include <cmath>
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
Vector3 QuatUtils::Euler(const NiQuaternion& quat) {
|
||||
return glm::eulerAngles(quat);
|
||||
Vector3 NiQuaternion::GetEulerAngles() const {
|
||||
Vector3 angles;
|
||||
|
||||
// roll (x-axis rotation)
|
||||
const float sinr_cosp = 2 * (w * x + y * z);
|
||||
const float cosr_cosp = 1 - 2 * (x * x + y * y);
|
||||
angles.x = std::atan2(sinr_cosp, cosr_cosp);
|
||||
|
||||
// pitch (y-axis rotation)
|
||||
const float sinp = 2 * (w * y - z * x);
|
||||
|
||||
if (std::abs(sinp) >= 1) {
|
||||
angles.y = std::copysign(3.14 / 2, sinp); // use 90 degrees if out of range
|
||||
} else {
|
||||
angles.y = std::asin(sinp);
|
||||
}
|
||||
|
||||
// yaw (z-axis rotation)
|
||||
const float siny_cosp = 2 * (w * z + x * y);
|
||||
const float cosy_cosp = 1 - 2 * (y * y + z * z);
|
||||
angles.z = std::atan2(siny_cosp, cosy_cosp);
|
||||
|
||||
return angles;
|
||||
}
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Look from a specific point in space to another point in space (Y-locked)
|
||||
NiQuaternion QuatUtils::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
//To make sure we don't orient around the X/Z axis:
|
||||
NiPoint3 source = sourcePoint;
|
||||
NiPoint3 dest = destPoint;
|
||||
@@ -32,11 +51,11 @@ NiQuaternion QuatUtils::LookAt(const NiPoint3& sourcePoint, const NiPoint3& dest
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return glm::angleAxis(rotAngle, glm::vec3{vecA.x, vecA.y, vecA.z});
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
}
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
NiQuaternion QuatUtils::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3Constant::UNIT_Z;
|
||||
@@ -48,26 +67,37 @@ NiQuaternion QuatUtils::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoin
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return glm::angleAxis(rotAngle, glm::vec3{vecA.x, vecA.y, vecA.z});
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
}
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
NiQuaternion QuatUtils::AxisAngle(const Vector3& axis, float angle) {
|
||||
return glm::angleAxis(angle, glm::vec3(axis.x, axis.y, axis.z));
|
||||
NiQuaternion NiQuaternion::CreateFromAxisAngle(const Vector3& axis, float angle) {
|
||||
float halfAngle = angle * 0.5f;
|
||||
float s = static_cast<float>(sin(halfAngle));
|
||||
|
||||
NiQuaternion q;
|
||||
q.x = axis.GetX() * s;
|
||||
q.y = axis.GetY() * s;
|
||||
q.z = axis.GetZ() * s;
|
||||
q.w = static_cast<float>(cos(halfAngle));
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
NiQuaternion QuatUtils::FromEuler(const NiPoint3& eulerAngles) {
|
||||
return glm::quat(glm::vec3(eulerAngles.x, eulerAngles.y, eulerAngles.z));
|
||||
}
|
||||
NiQuaternion NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles) {
|
||||
// Abbreviations for the various angular functions
|
||||
float cy = cos(eulerAngles.z * 0.5);
|
||||
float sy = sin(eulerAngles.z * 0.5);
|
||||
float cp = cos(eulerAngles.y * 0.5);
|
||||
float sp = sin(eulerAngles.y * 0.5);
|
||||
float cr = cos(eulerAngles.x * 0.5);
|
||||
float sr = sin(eulerAngles.x * 0.5);
|
||||
|
||||
Vector3 QuatUtils::Forward(const NiQuaternion& quat) {
|
||||
return quat * glm::vec3(0, 0, 1);
|
||||
}
|
||||
NiQuaternion q;
|
||||
q.w = cr * cp * cy + sr * sp * sy;
|
||||
q.x = sr * cp * cy - cr * sp * sy;
|
||||
q.y = cr * sp * cy + sr * cp * sy;
|
||||
q.z = cr * cp * sy - sr * sp * cy;
|
||||
|
||||
Vector3 QuatUtils::Up(const NiQuaternion& quat) {
|
||||
return quat * glm::vec3(0, 1, 0);
|
||||
}
|
||||
|
||||
Vector3 QuatUtils::Right(const NiQuaternion& quat) {
|
||||
return quat * glm::vec3(1, 0, 0);
|
||||
return q;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,158 @@
|
||||
#ifndef NIQUATERNION_H
|
||||
#define NIQUATERNION_H
|
||||
#ifndef __NIQUATERNION_H__
|
||||
#define __NIQUATERNION_H__
|
||||
|
||||
// Custom Classes
|
||||
#include "NiPoint3.h"
|
||||
|
||||
#define GLM_FORCE_QUAT_DATA_WXYZ
|
||||
/*!
|
||||
\file NiQuaternion.hpp
|
||||
\brief Defines a quaternion in space in WXYZ coordinates
|
||||
*/
|
||||
|
||||
#include <glm/ext/quaternion_float.hpp>
|
||||
class NiQuaternion;
|
||||
typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version of NiQuaternion
|
||||
|
||||
using Quaternion = glm::quat;
|
||||
using NiQuaternion = Quaternion;
|
||||
//! 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
|
||||
|
||||
namespace QuatUtils {
|
||||
constexpr NiQuaternion IDENTITY = glm::identity<NiQuaternion>();
|
||||
Vector3 Forward(const NiQuaternion& quat);
|
||||
Vector3 Up(const NiQuaternion& quat);
|
||||
Vector3 Right(const NiQuaternion& quat);
|
||||
NiQuaternion LookAt(const NiPoint3& from, const NiPoint3& to);
|
||||
NiQuaternion LookAtUnlocked(const NiPoint3& from, const NiPoint3& to);
|
||||
Vector3 Euler(const NiQuaternion& quat);
|
||||
NiQuaternion AxisAngle(const Vector3& axis, float angle);
|
||||
NiQuaternion FromEuler(const NiPoint3& eulerAngles);
|
||||
constexpr float PI_OVER_180 = glm::pi<float>() / 180.0f;
|
||||
|
||||
//! The initializer
|
||||
constexpr NiQuaternion() = default;
|
||||
|
||||
//! The initializer
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
\param x The x coordinate
|
||||
\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 } {
|
||||
}
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
//! Gets the W coordinate
|
||||
/*!
|
||||
\return The w coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetW() const noexcept;
|
||||
|
||||
//! Sets the W coordinate
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
*/
|
||||
constexpr void SetW(const float w) noexcept;
|
||||
|
||||
//! Gets the X coordinate
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetX() const noexcept;
|
||||
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
constexpr void SetX(const float x) noexcept;
|
||||
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetY() const noexcept;
|
||||
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
constexpr void SetY(const float y) noexcept;
|
||||
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetZ() const noexcept;
|
||||
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
constexpr void SetZ(const float z) noexcept;
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
/*!
|
||||
\return The forward vector of the quaternion
|
||||
*/
|
||||
[[nodiscard]] constexpr Vector3 GetForwardVector() const noexcept;
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
/*!
|
||||
\return The up vector fo the quaternion
|
||||
*/
|
||||
[[nodiscard]] constexpr Vector3 GetUpVector() const noexcept;
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
/*!
|
||||
\return The right vector of the quaternion
|
||||
*/
|
||||
[[nodiscard]] constexpr Vector3 GetRightVector() const noexcept;
|
||||
|
||||
[[nodiscard]] Vector3 GetEulerAngles() const;
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
constexpr bool operator==(const NiQuaternion& rot) const noexcept;
|
||||
|
||||
//! Operator to check for inequality
|
||||
constexpr bool operator!=(const NiQuaternion& rot) const noexcept;
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Look from a specific point in space to another point in space (Y-locked)
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
[[nodiscard]] static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
[[nodiscard]] static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
/*!
|
||||
\param axis The axis that is used
|
||||
\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);
|
||||
|
||||
[[nodiscard]] static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
|
||||
};
|
||||
|
||||
#endif // !NIQUATERNION_H
|
||||
// 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__
|
||||
|
||||
75
dCommon/NiQuaternion.inl
Normal file
75
dCommon/NiQuaternion.inl
Normal file
@@ -0,0 +1,75 @@
|
||||
#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);
|
||||
}
|
||||
@@ -24,7 +24,7 @@ struct LocalSpaceInfo {
|
||||
|
||||
struct PositionUpdate {
|
||||
NiPoint3 position = NiPoint3Constant::ZERO;
|
||||
NiQuaternion rotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion rotation = NiQuaternionConstant::IDENTITY;
|
||||
bool onGround = false;
|
||||
bool onRail = false;
|
||||
NiPoint3 velocity = NiPoint3Constant::ZERO;
|
||||
|
||||
@@ -47,8 +47,6 @@ void dConfig::LoadConfig() {
|
||||
void dConfig::ReloadConfig() {
|
||||
this->m_ConfigValues.clear();
|
||||
LoadConfig();
|
||||
for (const auto& handler : m_ConfigHandlers) handler();
|
||||
LogSettings();
|
||||
}
|
||||
|
||||
const std::string& dConfig::GetValue(std::string key) {
|
||||
@@ -60,18 +58,6 @@ const std::string& dConfig::GetValue(std::string key) {
|
||||
return this->m_ConfigValues[key];
|
||||
}
|
||||
|
||||
void dConfig::AddConfigHandler(std::function<void()> handler) {
|
||||
m_ConfigHandlers.push_back(handler);
|
||||
}
|
||||
|
||||
void dConfig::LogSettings() const {
|
||||
LOG("Configuration settings:");
|
||||
for (const auto& [key, value] : m_ConfigValues) {
|
||||
const auto& valueLog = key.find("password") != std::string::npos ? "<HIDDEN>" : value;
|
||||
LOG(" %s = %s", key.c_str(), valueLog.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void dConfig::ProcessLine(const std::string& line) {
|
||||
auto splitLoc = line.find('=');
|
||||
auto key = line.substr(0, splitLoc);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
@@ -31,15 +29,10 @@ public:
|
||||
* Reloads the config file to reset values
|
||||
*/
|
||||
void ReloadConfig();
|
||||
|
||||
// Adds a function to be called when the config is (re)loaded
|
||||
void AddConfigHandler(std::function<void()> handler);
|
||||
void LogSettings() const;
|
||||
|
||||
private:
|
||||
void ProcessLine(const std::string& line);
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> m_ConfigValues;
|
||||
std::vector<std::function<void()>> m_ConfigHandlers;
|
||||
std::string m_ConfigFilePath;
|
||||
};
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
namespace MessageType {
|
||||
enum class Master : uint32_t {
|
||||
REQUEST_ZONE_TRANSFER = 1,
|
||||
REQUEST_PERSISTENT_ID = 1,
|
||||
REQUEST_PERSISTENT_ID_RESPONSE,
|
||||
REQUEST_ZONE_TRANSFER,
|
||||
REQUEST_ZONE_TRANSFER_RESPONSE,
|
||||
SERVER_INFO,
|
||||
REQUEST_SESSION_KEY,
|
||||
|
||||
@@ -18,9 +18,7 @@ enum class eCharacterVersion : uint32_t {
|
||||
SPEED_BASE,
|
||||
// Fixes nexus force explorer missions
|
||||
NJ_JAYMISSIONS,
|
||||
NEXUS_FORCE_EXPLORER, // Fixes pet ids in player inventories
|
||||
PET_IDS, // Fixes pet ids in player inventories
|
||||
UP_TO_DATE, // will become INVENTORY_PERSISTENT_IDS
|
||||
UP_TO_DATE, // will become NEXUS_FORCE_EXPLORER
|
||||
};
|
||||
|
||||
#endif //!__ECHARACTERVERSION__H__
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#ifndef EOBJECTBITS_H
|
||||
#define EOBJECTBITS_H
|
||||
#ifndef __EOBJECTBITS__H__
|
||||
#define __EOBJECTBITS__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eObjectBits : size_t {
|
||||
PERSISTENT = 32,
|
||||
CLIENT = 46,
|
||||
SPAWNED = 58,
|
||||
CHARACTER = 60
|
||||
};
|
||||
|
||||
#endif //!EOBJECTBITS_H
|
||||
#endif //!__EOBJECTBITS__H__
|
||||
|
||||
@@ -15,7 +15,7 @@ target_include_directories(dDatabaseCDClient PUBLIC "."
|
||||
"${PROJECT_SOURCE_DIR}/dCommon"
|
||||
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
|
||||
)
|
||||
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3 glm::glm)
|
||||
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3)
|
||||
|
||||
if (${CDCLIENT_CACHE_ALL})
|
||||
add_compile_definitions(dDatabaseCDClient PRIVATE CDCLIENT_CACHE_ALL=${CDCLIENT_CACHE_ALL})
|
||||
|
||||
@@ -10,5 +10,4 @@ add_dependencies(dDatabase conncpp_dylib)
|
||||
|
||||
target_include_directories(dDatabase PUBLIC ".")
|
||||
target_link_libraries(dDatabase
|
||||
PUBLIC dDatabaseCDClient dDatabaseGame
|
||||
PRIVATE glm::glm)
|
||||
PUBLIC dDatabaseCDClient dDatabaseGame)
|
||||
|
||||
@@ -29,7 +29,7 @@ target_include_directories(dDatabaseGame PUBLIC "."
|
||||
|
||||
target_link_libraries(dDatabaseGame
|
||||
INTERFACE dCommon
|
||||
PRIVATE sqlite3 MariaDB::ConnCpp glm::glm)
|
||||
PRIVATE sqlite3 MariaDB::ConnCpp)
|
||||
|
||||
# Glob together all headers that need to be precompiled
|
||||
file(
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
virtual void Commit() = 0;
|
||||
virtual bool GetAutoCommit() = 0;
|
||||
virtual void SetAutoCommit(bool value) = 0;
|
||||
virtual void DeleteCharacter(const LWOOBJID characterId) = 0;
|
||||
virtual void DeleteCharacter(const uint32_t characterId) = 0;
|
||||
};
|
||||
|
||||
#endif //!__GAMEDATABASE__H__
|
||||
|
||||
@@ -14,7 +14,6 @@ public:
|
||||
std::string bcryptPassword;
|
||||
uint32_t id{};
|
||||
uint32_t playKeyId{};
|
||||
uint64_t muteExpire{};
|
||||
bool banned{};
|
||||
bool locked{};
|
||||
eGameMasterLevel maxGmLevel{};
|
||||
|
||||
@@ -14,7 +14,7 @@ enum class eActivityType : uint32_t {
|
||||
class IActivityLog {
|
||||
public:
|
||||
// Update the activity log for the given account.
|
||||
virtual void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) = 0;
|
||||
virtual void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IACTIVITYLOG__H__
|
||||
|
||||
@@ -9,7 +9,7 @@ class IBehaviors {
|
||||
public:
|
||||
struct Info {
|
||||
LWOOBJID behaviorId{};
|
||||
LWOOBJID characterId{};
|
||||
uint32_t characterId{};
|
||||
std::string behaviorInfo;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public:
|
||||
std::string clientVersion;
|
||||
std::string otherPlayer;
|
||||
std::string selection;
|
||||
LWOOBJID characterId{};
|
||||
uint32_t characterId{};
|
||||
};
|
||||
|
||||
// Add a new bug report to the database.
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
struct Info {
|
||||
std::string name;
|
||||
std::string pendingName;
|
||||
LWOOBJID id{};
|
||||
uint32_t id{};
|
||||
uint32_t accountId{};
|
||||
bool needsRename{};
|
||||
LWOCLONEID cloneId{};
|
||||
@@ -25,25 +25,25 @@ public:
|
||||
virtual std::vector<std::string> GetApprovedCharacterNames() = 0;
|
||||
|
||||
// Get the character info for the given character id.
|
||||
virtual std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) = 0;
|
||||
virtual std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) = 0;
|
||||
|
||||
// Get the character info for the given character name.
|
||||
virtual std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view name) = 0;
|
||||
|
||||
// Get the character ids for the given account.
|
||||
virtual std::vector<LWOOBJID> GetAccountCharacterIds(const LWOOBJID accountId) = 0;
|
||||
virtual std::vector<uint32_t> GetAccountCharacterIds(const uint32_t accountId) = 0;
|
||||
|
||||
// Insert a new character into the database.
|
||||
virtual void InsertNewCharacter(const ICharInfo::Info info) = 0;
|
||||
|
||||
// Set the name of the given character.
|
||||
virtual void SetCharacterName(const LWOOBJID characterId, const std::string_view name) = 0;
|
||||
virtual void SetCharacterName(const uint32_t characterId, const std::string_view name) = 0;
|
||||
|
||||
// Set the pending name of the given character.
|
||||
virtual void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) = 0;
|
||||
virtual void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) = 0;
|
||||
|
||||
// Updates the given character ids last login to be right now.
|
||||
virtual void UpdateLastLoggedInCharacter(const LWOOBJID characterId) = 0;
|
||||
virtual void UpdateLastLoggedInCharacter(const uint32_t characterId) = 0;
|
||||
|
||||
virtual bool IsNameInUse(const std::string_view name) = 0;
|
||||
};
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
class ICharXml {
|
||||
public:
|
||||
// Get the character xml for the given character id.
|
||||
virtual std::string GetCharacterXml(const LWOOBJID charId) = 0;
|
||||
virtual std::string GetCharacterXml(const uint32_t charId) = 0;
|
||||
|
||||
// Update the character xml for the given character id.
|
||||
virtual void UpdateCharacterXml(const LWOOBJID charId, const std::string_view lxfml) = 0;
|
||||
virtual void UpdateCharacterXml(const uint32_t charId, const std::string_view lxfml) = 0;
|
||||
|
||||
// Insert the character xml for the given character id.
|
||||
virtual void InsertCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) = 0;
|
||||
virtual void InsertCharacterXml(const uint32_t characterId, const std::string_view lxfml) = 0;
|
||||
};
|
||||
|
||||
#endif //!__ICHARXML__H__
|
||||
|
||||
@@ -8,7 +8,7 @@ class ICommandLog {
|
||||
public:
|
||||
|
||||
// Insert a new slash command log entry.
|
||||
virtual void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) = 0;
|
||||
virtual void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) = 0;
|
||||
};
|
||||
|
||||
#endif //!__ICOMMANDLOG__H__
|
||||
|
||||
@@ -8,25 +8,25 @@
|
||||
class IFriends {
|
||||
public:
|
||||
struct BestFriendStatus {
|
||||
LWOOBJID playerCharacterId{};
|
||||
LWOOBJID friendCharacterId{};
|
||||
uint32_t playerCharacterId{};
|
||||
uint32_t friendCharacterId{};
|
||||
uint32_t bestFriendStatus{};
|
||||
};
|
||||
|
||||
// Get the friends list for the given character id.
|
||||
virtual std::vector<FriendData> GetFriendsList(const LWOOBJID charId) = 0;
|
||||
virtual std::vector<FriendData> GetFriendsList(const uint32_t charId) = 0;
|
||||
|
||||
// Get the best friend status for the given player and friend character ids.
|
||||
virtual std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) = 0;
|
||||
virtual std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) = 0;
|
||||
|
||||
// Set the best friend status for the given player and friend character ids.
|
||||
virtual void SetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId, const uint32_t bestFriendStatus) = 0;
|
||||
virtual void SetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId, const uint32_t bestFriendStatus) = 0;
|
||||
|
||||
// Add a friend to the given character id.
|
||||
virtual void AddFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) = 0;
|
||||
virtual void AddFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) = 0;
|
||||
|
||||
// Remove a friend from the given character id.
|
||||
virtual void RemoveFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) = 0;
|
||||
virtual void RemoveFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IFRIENDS__H__
|
||||
|
||||
@@ -9,12 +9,12 @@ class IIgnoreList {
|
||||
public:
|
||||
struct Info {
|
||||
std::string name;
|
||||
LWOOBJID id;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
virtual std::vector<Info> GetIgnoreList(const LWOOBJID playerId) = 0;
|
||||
virtual void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) = 0;
|
||||
virtual void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) = 0;
|
||||
virtual std::vector<Info> GetIgnoreList(const uint32_t playerId) = 0;
|
||||
virtual void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) = 0;
|
||||
virtual void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IIGNORELIST__H__
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "dCommonVars.h"
|
||||
|
||||
class ILeaderboard {
|
||||
public:
|
||||
|
||||
struct Entry {
|
||||
LWOOBJID charId{};
|
||||
uint32_t charId{};
|
||||
uint32_t lastPlayedTimestamp{};
|
||||
float primaryScore{};
|
||||
float secondaryScore{};
|
||||
@@ -37,12 +36,12 @@ public:
|
||||
virtual std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) = 0;
|
||||
virtual std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) = 0;
|
||||
virtual std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) = 0;
|
||||
virtual std::optional<Score> GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) = 0;
|
||||
virtual std::optional<Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) = 0;
|
||||
|
||||
virtual void SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) = 0;
|
||||
virtual void UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) = 0;
|
||||
virtual void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) = 0;
|
||||
virtual void IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) = 0;
|
||||
virtual void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) = 0;
|
||||
virtual void UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) = 0;
|
||||
virtual void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) = 0;
|
||||
virtual void IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) = 0;
|
||||
};
|
||||
|
||||
#endif //!__ILEADERBOARD__H__
|
||||
|
||||
@@ -16,13 +16,13 @@ public:
|
||||
virtual void InsertNewMail(const MailInfo& mail) = 0;
|
||||
|
||||
// Get the mail for the given character id.
|
||||
virtual std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) = 0;
|
||||
virtual std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) = 0;
|
||||
|
||||
// Get the mail for the given mail id.
|
||||
virtual std::optional<MailInfo> GetMail(const uint64_t mailId) = 0;
|
||||
|
||||
// Get the number of unread mail for the given character id.
|
||||
virtual uint32_t GetUnreadMailCount(const LWOOBJID characterId) = 0;
|
||||
virtual uint32_t GetUnreadMailCount(const uint32_t characterId) = 0;
|
||||
|
||||
// Mark the given mail as read.
|
||||
virtual void MarkMailRead(const uint64_t mailId) = 0;
|
||||
|
||||
@@ -6,19 +6,14 @@
|
||||
|
||||
class IObjectIdTracker {
|
||||
public:
|
||||
// Only the first 48 bits of the ids are the id, the last 16 bits are reserved for flags.
|
||||
struct Range {
|
||||
uint64_t minID{}; // Only the first 48 bits are the id, the last 16 bits are reserved for flags.
|
||||
uint64_t maxID{}; // Only the first 48 bits are the id, the last 16 bits are reserved for flags.
|
||||
};
|
||||
|
||||
// Get the current persistent id.
|
||||
virtual std::optional<uint64_t> GetCurrentPersistentId() = 0;
|
||||
virtual std::optional<uint32_t> GetCurrentPersistentId() = 0;
|
||||
|
||||
// Insert the default persistent id.
|
||||
virtual void InsertDefaultPersistentId() = 0;
|
||||
|
||||
virtual Range GetPersistentIdRange() = 0;
|
||||
// Update the persistent id.
|
||||
virtual void UpdatePersistentId(const uint32_t newId) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IOBJECTIDTRACKER__H__
|
||||
|
||||
@@ -13,7 +13,7 @@ public:
|
||||
std::string description;
|
||||
std::string rejectionReason;
|
||||
LWOOBJID id{};
|
||||
LWOOBJID ownerId{};
|
||||
uint32_t ownerId{};
|
||||
LWOCLONEID cloneId{};
|
||||
int32_t privacyOption{};
|
||||
uint32_t modApproved{};
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
uint32_t mapId{};
|
||||
std::string searchString;
|
||||
ePropertySortType sortChoice{};
|
||||
LWOOBJID playerId{};
|
||||
uint32_t playerId{};
|
||||
uint32_t numResults{};
|
||||
uint32_t startIndex{};
|
||||
uint32_t playerSort{};
|
||||
@@ -39,9 +39,6 @@ public:
|
||||
std::vector<IProperty::Info> entries;
|
||||
};
|
||||
|
||||
// Get the property info for the given property id.
|
||||
virtual std::optional<IProperty::Info> GetPropertyInfo(const LWOOBJID id) = 0;
|
||||
|
||||
// Get the property info for the given property id.
|
||||
virtual std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) = 0;
|
||||
|
||||
|
||||
@@ -13,19 +13,19 @@ public:
|
||||
}
|
||||
|
||||
NiPoint3 position;
|
||||
NiQuaternion rotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion rotation;
|
||||
LWOOBJID id{};
|
||||
LOT lot{};
|
||||
LWOOBJID ugcId{};
|
||||
uint32_t ugcId{};
|
||||
std::array<LWOOBJID, 5> behaviors{};
|
||||
};
|
||||
|
||||
// Inserts a new UGC model into the database.
|
||||
virtual void InsertNewUgcModel(
|
||||
std::stringstream& sd0Data,
|
||||
const uint64_t blueprintId,
|
||||
const uint32_t blueprintId,
|
||||
const uint32_t accountId,
|
||||
const LWOOBJID characterId) = 0;
|
||||
const uint32_t characterId) = 0;
|
||||
|
||||
// Get the property models for the given property id.
|
||||
virtual std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) = 0;
|
||||
@@ -45,6 +45,6 @@ public:
|
||||
virtual void RemoveModel(const LWOOBJID& modelId) = 0;
|
||||
|
||||
// Gets a model by ID
|
||||
virtual std::optional<Model> GetModel(const LWOOBJID modelID) = 0;
|
||||
virtual Model GetModel(const LWOOBJID modelID) = 0;
|
||||
};
|
||||
#endif //!__IPROPERTIESCONTENTS__H__
|
||||
|
||||
@@ -29,7 +29,5 @@ public:
|
||||
|
||||
// Inserts a new UGC model into the database.
|
||||
virtual void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) = 0;
|
||||
|
||||
virtual std::optional<IUgc::Model> GetUgcModel(const LWOOBJID ugcId) = 0;
|
||||
};
|
||||
#endif //!__IUGC__H__
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
class IUgcModularBuild {
|
||||
public:
|
||||
virtual void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) = 0;
|
||||
virtual void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) = 0;
|
||||
virtual void DeleteUgcBuild(const LWOOBJID bigId) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ void MySQLDatabase::SetAutoCommit(bool value) {
|
||||
con->setAutoCommit(value);
|
||||
}
|
||||
|
||||
void MySQLDatabase::DeleteCharacter(const LWOOBJID characterId) {
|
||||
void MySQLDatabase::DeleteCharacter(const uint32_t characterId) {
|
||||
ExecuteDelete("DELETE FROM charxml WHERE id=? LIMIT 1;", characterId);
|
||||
ExecuteDelete("DELETE FROM command_log WHERE character_id=?;", characterId);
|
||||
ExecuteDelete("DELETE FROM friends WHERE player_id=? OR friend_id=?;", characterId, characterId);
|
||||
|
||||
@@ -40,31 +40,31 @@ public:
|
||||
|
||||
std::vector<std::string> GetApprovedCharacterNames() override;
|
||||
|
||||
std::vector<FriendData> GetFriendsList(LWOOBJID charID) override;
|
||||
std::vector<FriendData> GetFriendsList(uint32_t charID) override;
|
||||
|
||||
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) override;
|
||||
void SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) override;
|
||||
void AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
|
||||
void RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
|
||||
void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) override;
|
||||
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override;
|
||||
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override;
|
||||
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
|
||||
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
|
||||
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override;
|
||||
void DeleteUgcModelData(const LWOOBJID& modelId) override;
|
||||
void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override;
|
||||
std::vector<IUgc::Model> GetAllUgcModels() override;
|
||||
void CreateMigrationHistoryTable() override;
|
||||
bool IsMigrationRun(const std::string_view str) override;
|
||||
void InsertMigration(const std::string_view str) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
|
||||
std::string GetCharacterXml(const LWOOBJID accountId) override;
|
||||
void UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) override;
|
||||
std::string GetCharacterXml(const uint32_t accountId) override;
|
||||
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override;
|
||||
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
|
||||
void InsertNewCharacter(const ICharInfo::Info info) override;
|
||||
void InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) override;
|
||||
std::vector<LWOOBJID> GetAccountCharacterIds(LWOOBJID accountId) override;
|
||||
void DeleteCharacter(const LWOOBJID characterId) override;
|
||||
void SetCharacterName(const LWOOBJID characterId, const std::string_view name) override;
|
||||
void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) override;
|
||||
void UpdateLastLoggedInCharacter(const LWOOBJID characterId) override;
|
||||
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override;
|
||||
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override;
|
||||
void DeleteCharacter(const uint32_t characterId) override;
|
||||
void SetCharacterName(const uint32_t characterId, const std::string_view name) override;
|
||||
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override;
|
||||
void UpdateLastLoggedInCharacter(const uint32_t characterId) override;
|
||||
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
|
||||
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
|
||||
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
|
||||
@@ -83,30 +83,30 @@ public:
|
||||
void InsertNewMail(const MailInfo& mail) override;
|
||||
void InsertNewUgcModel(
|
||||
std::stringstream& sd0Data,
|
||||
const uint64_t blueprintId,
|
||||
const uint32_t blueprintId,
|
||||
const uint32_t accountId,
|
||||
const LWOOBJID characterId) override;
|
||||
std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) override;
|
||||
const uint32_t characterId) override;
|
||||
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
||||
std::optional<MailInfo> GetMail(const uint64_t mailId) override;
|
||||
uint32_t GetUnreadMailCount(const LWOOBJID characterId) override;
|
||||
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
||||
void MarkMailRead(const uint64_t mailId) override;
|
||||
void DeleteMail(const uint64_t mailId) override;
|
||||
void ClaimMailItem(const uint64_t mailId) override;
|
||||
void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) override;
|
||||
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override;
|
||||
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
|
||||
void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
|
||||
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
|
||||
void InsertNewAccount(const std::string_view username, const std::string_view bcryptpassword) override;
|
||||
void SetMasterInfo(const IServers::MasterInfo& info) override;
|
||||
std::optional<uint64_t> GetCurrentPersistentId() override;
|
||||
IObjectIdTracker::Range GetPersistentIdRange() override;
|
||||
std::optional<uint32_t> GetCurrentPersistentId() override;
|
||||
void InsertDefaultPersistentId() override;
|
||||
void UpdatePersistentId(const uint32_t id) override;
|
||||
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
|
||||
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
|
||||
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
|
||||
void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
|
||||
void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
|
||||
std::vector<IIgnoreList::Info> GetIgnoreList(const LWOOBJID playerId) override;
|
||||
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
|
||||
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
|
||||
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override;
|
||||
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
|
||||
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
|
||||
void AddBehavior(const IBehaviors::Info& info) override;
|
||||
@@ -118,18 +118,16 @@ public:
|
||||
std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override;
|
||||
std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) override;
|
||||
std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override;
|
||||
void SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override;
|
||||
void UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override;
|
||||
std::optional<ILeaderboard::Score> GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) override;
|
||||
void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) override;
|
||||
void IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) override;
|
||||
void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) override;
|
||||
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override;
|
||||
void UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override;
|
||||
std::optional<ILeaderboard::Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) override;
|
||||
void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override;
|
||||
void IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) override;
|
||||
void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) override;
|
||||
void DeleteUgcBuild(const LWOOBJID bigId) override;
|
||||
uint32_t GetAccountCount() override;
|
||||
bool IsNameInUse(const std::string_view name) override;
|
||||
std::optional<IPropertyContents::Model> GetModel(const LWOOBJID modelID) override;
|
||||
std::optional<IUgc::Model> GetUgcModel(const LWOOBJID ugcId) override;
|
||||
std::optional<IProperty::Info> GetPropertyInfo(const LWOOBJID id) override;
|
||||
IPropertyContents::Model GetModel(const LWOOBJID modelID) override;
|
||||
sql::PreparedStatement* CreatePreppedStmt(const std::string& query);
|
||||
private:
|
||||
|
||||
@@ -170,91 +168,91 @@ private:
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::string_view param) {
|
||||
LOG_DEBUG("%s", param.data());
|
||||
// LOG("%s", param.data());
|
||||
stmt->setString(index, param.data());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const char* param) {
|
||||
LOG_DEBUG("%s", param);
|
||||
// LOG("%s", param);
|
||||
stmt->setString(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::string param) {
|
||||
LOG_DEBUG("%s", param.c_str());
|
||||
// LOG("%s", param.c_str());
|
||||
stmt->setString(index, param.c_str());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const int8_t param) {
|
||||
LOG_DEBUG("%u", param);
|
||||
// LOG("%u", param);
|
||||
stmt->setByte(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const uint8_t param) {
|
||||
LOG_DEBUG("%d", param);
|
||||
// LOG("%d", param);
|
||||
stmt->setByte(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const int16_t param) {
|
||||
LOG_DEBUG("%u", param);
|
||||
// LOG("%u", param);
|
||||
stmt->setShort(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const uint16_t param) {
|
||||
LOG_DEBUG("%d", param);
|
||||
// LOG("%d", param);
|
||||
stmt->setShort(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const uint32_t param) {
|
||||
LOG_DEBUG("%u", param);
|
||||
// LOG("%u", param);
|
||||
stmt->setUInt(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const int32_t param) {
|
||||
LOG_DEBUG("%d", param);
|
||||
// LOG("%d", param);
|
||||
stmt->setInt(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const int64_t param) {
|
||||
LOG_DEBUG("%llu", param);
|
||||
// LOG("%llu", param);
|
||||
stmt->setInt64(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const uint64_t param) {
|
||||
LOG_DEBUG("%llu", param);
|
||||
// LOG("%llu", param);
|
||||
stmt->setUInt64(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const float param) {
|
||||
LOG_DEBUG("%f", param);
|
||||
// LOG("%f", param);
|
||||
stmt->setFloat(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const double param) {
|
||||
LOG_DEBUG("%f", param);
|
||||
// LOG("%f", param);
|
||||
stmt->setDouble(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const bool param) {
|
||||
LOG_DEBUG("%s", param ? "true" : "false");
|
||||
// LOG("%d", param);
|
||||
stmt->setBoolean(index, param);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::istream* param) {
|
||||
LOG_DEBUG("Blob");
|
||||
// LOG("Blob");
|
||||
// This is the one time you will ever see me use const_cast.
|
||||
stmt->setBlob(index, const_cast<std::istream*>(param));
|
||||
}
|
||||
@@ -262,21 +260,10 @@ inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::istr
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::optional<uint32_t> param) {
|
||||
if (param) {
|
||||
LOG_DEBUG("%d", param.value());
|
||||
// LOG("%d", param.value());
|
||||
stmt->setInt(index, param.value());
|
||||
} else {
|
||||
LOG_DEBUG("Null");
|
||||
stmt->setNull(index, sql::DataType::SQLNULL);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::optional<LWOOBJID> param) {
|
||||
if (param) {
|
||||
LOG_DEBUG("%d", param.value());
|
||||
stmt->setInt64(index, param.value());
|
||||
} else {
|
||||
LOG_DEBUG("Null");
|
||||
// LOG("Null");
|
||||
stmt->setNull(index, sql::DataType::SQLNULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "eGameMasterLevel.h"
|
||||
|
||||
std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_view username) {
|
||||
auto result = ExecuteSelect("SELECT id, password, banned, locked, play_key_id, gm_level, mute_expire FROM accounts WHERE name = ? LIMIT 1;", username);
|
||||
auto result = ExecuteSelect("SELECT id, password, banned, locked, play_key_id, gm_level FROM accounts WHERE name = ? LIMIT 1;", username);
|
||||
|
||||
if (!result->next()) {
|
||||
return std::nullopt;
|
||||
@@ -16,7 +16,6 @@ std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_v
|
||||
toReturn.banned = result->getBoolean("banned");
|
||||
toReturn.locked = result->getBoolean("locked");
|
||||
toReturn.playKeyId = result->getUInt("play_key_id");
|
||||
toReturn.muteExpire = result->getUInt64("mute_expire");
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
void MySQLDatabase::UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) {
|
||||
void MySQLDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) {
|
||||
ExecuteInsert("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);",
|
||||
characterId, static_cast<uint32_t>(activityType), static_cast<uint32_t>(time(NULL)), mapId);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(std::unique_ptr<sql::Resu
|
||||
|
||||
ICharInfo::Info toReturn;
|
||||
|
||||
toReturn.id = stmt->getInt64("id");
|
||||
toReturn.id = stmt->getUInt("id");
|
||||
toReturn.name = stmt->getString("name").c_str();
|
||||
toReturn.pendingName = stmt->getString("pending_name").c_str();
|
||||
toReturn.needsRename = stmt->getBoolean("needs_rename");
|
||||
@@ -30,7 +30,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(std::unique_ptr<sql::Resu
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const LWOOBJID charId) {
|
||||
std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const uint32_t charId) {
|
||||
return CharInfoFromQueryResult(
|
||||
ExecuteSelect("SELECT name, pending_name, needs_rename, prop_clone_id, permission_map, id, account_id FROM charinfo WHERE id = ? LIMIT 1;", charId)
|
||||
);
|
||||
@@ -42,13 +42,13 @@ std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const std::string
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<LWOOBJID> MySQLDatabase::GetAccountCharacterIds(const LWOOBJID accountId) {
|
||||
std::vector<uint32_t> MySQLDatabase::GetAccountCharacterIds(const uint32_t accountId) {
|
||||
auto result = ExecuteSelect("SELECT id FROM charinfo WHERE account_id = ? ORDER BY last_login DESC LIMIT 4;", accountId);
|
||||
|
||||
std::vector<LWOOBJID> toReturn;
|
||||
std::vector<uint32_t> toReturn;
|
||||
toReturn.reserve(result->rowsCount());
|
||||
while (result->next()) {
|
||||
toReturn.push_back(result->getInt64("id"));
|
||||
toReturn.push_back(result->getUInt("id"));
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
@@ -65,15 +65,15 @@ void MySQLDatabase::InsertNewCharacter(const ICharInfo::Info info) {
|
||||
static_cast<uint32_t>(time(NULL)));
|
||||
}
|
||||
|
||||
void MySQLDatabase::SetCharacterName(const LWOOBJID characterId, const std::string_view name) {
|
||||
void MySQLDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) {
|
||||
ExecuteUpdate("UPDATE charinfo SET name = ?, pending_name = '', needs_rename = 0, last_login = ? WHERE id = ? LIMIT 1;", name, static_cast<uint32_t>(time(NULL)), characterId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) {
|
||||
void MySQLDatabase::SetPendingCharacterName(const uint32_t characterId, const std::string_view name) {
|
||||
ExecuteUpdate("UPDATE charinfo SET pending_name = ?, needs_rename = 0, last_login = ? WHERE id = ? LIMIT 1", name, static_cast<uint32_t>(time(NULL)), characterId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::UpdateLastLoggedInCharacter(const LWOOBJID characterId) {
|
||||
void MySQLDatabase::UpdateLastLoggedInCharacter(const uint32_t characterId) {
|
||||
ExecuteUpdate("UPDATE charinfo SET last_login = ? WHERE id = ? LIMIT 1", static_cast<uint32_t>(time(NULL)), characterId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
std::string MySQLDatabase::GetCharacterXml(const LWOOBJID charId) {
|
||||
std::string MySQLDatabase::GetCharacterXml(const uint32_t charId) {
|
||||
auto result = ExecuteSelect("SELECT xml_data FROM charxml WHERE id = ? LIMIT 1;", charId);
|
||||
|
||||
if (!result->next()) {
|
||||
@@ -10,10 +10,10 @@ std::string MySQLDatabase::GetCharacterXml(const LWOOBJID charId) {
|
||||
return result->getString("xml_data").c_str();
|
||||
}
|
||||
|
||||
void MySQLDatabase::UpdateCharacterXml(const LWOOBJID charId, const std::string_view lxfml) {
|
||||
void MySQLDatabase::UpdateCharacterXml(const uint32_t charId, const std::string_view lxfml) {
|
||||
ExecuteUpdate("UPDATE charxml SET xml_data = ? WHERE id = ?;", lxfml, charId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::InsertCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) {
|
||||
void MySQLDatabase::InsertCharacterXml(const uint32_t characterId, const std::string_view lxfml) {
|
||||
ExecuteInsert("INSERT INTO `charxml` (`id`, `xml_data`) VALUES (?,?)", characterId, lxfml);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
void MySQLDatabase::InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) {
|
||||
void MySQLDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) {
|
||||
ExecuteInsert("INSERT INTO command_log (character_id, command) VALUES (?, ?);", characterId, command);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
std::vector<FriendData> MySQLDatabase::GetFriendsList(const LWOOBJID charId) {
|
||||
std::vector<FriendData> MySQLDatabase::GetFriendsList(const uint32_t charId) {
|
||||
auto friendsList = ExecuteSelect(
|
||||
R"QUERY(
|
||||
SELECT fr.requested_player AS player, best_friend AS bff, ci.name AS name FROM
|
||||
@@ -19,7 +19,7 @@ std::vector<FriendData> MySQLDatabase::GetFriendsList(const LWOOBJID charId) {
|
||||
|
||||
while (friendsList->next()) {
|
||||
FriendData fd;
|
||||
fd.friendID = friendsList->getUInt64("player");
|
||||
fd.friendID = friendsList->getUInt("player");
|
||||
fd.isBestFriend = friendsList->getInt("bff") == 3; // 0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
|
||||
fd.friendName = friendsList->getString("name").c_str();
|
||||
|
||||
@@ -29,7 +29,7 @@ std::vector<FriendData> MySQLDatabase::GetFriendsList(const LWOOBJID charId) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
std::optional<IFriends::BestFriendStatus> MySQLDatabase::GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
|
||||
std::optional<IFriends::BestFriendStatus> MySQLDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
|
||||
auto result = ExecuteSelect("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
|
||||
playerCharacterId,
|
||||
friendCharacterId,
|
||||
@@ -42,14 +42,14 @@ std::optional<IFriends::BestFriendStatus> MySQLDatabase::GetBestFriendStatus(con
|
||||
}
|
||||
|
||||
IFriends::BestFriendStatus toReturn;
|
||||
toReturn.playerCharacterId = result->getUInt64("player_id");
|
||||
toReturn.friendCharacterId = result->getUInt64("friend_id");
|
||||
toReturn.playerCharacterId = result->getUInt("player_id");
|
||||
toReturn.friendCharacterId = result->getUInt("friend_id");
|
||||
toReturn.bestFriendStatus = result->getUInt("best_friend");
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void MySQLDatabase::SetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId, const uint32_t bestFriendStatus) {
|
||||
void MySQLDatabase::SetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId, const uint32_t bestFriendStatus) {
|
||||
ExecuteUpdate("UPDATE friends SET best_friend = ? WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
|
||||
bestFriendStatus,
|
||||
playerCharacterId,
|
||||
@@ -59,11 +59,11 @@ void MySQLDatabase::SetBestFriendStatus(const LWOOBJID playerCharacterId, const
|
||||
);
|
||||
}
|
||||
|
||||
void MySQLDatabase::AddFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
|
||||
void MySQLDatabase::AddFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
|
||||
ExecuteInsert("INSERT IGNORE INTO friends (player_id, friend_id, best_friend) VALUES (?, ?, 0);", playerCharacterId, friendCharacterId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::RemoveFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
|
||||
void MySQLDatabase::RemoveFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
|
||||
ExecuteDelete("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
|
||||
playerCharacterId,
|
||||
friendCharacterId,
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
std::vector<IIgnoreList::Info> MySQLDatabase::GetIgnoreList(const LWOOBJID playerId) {
|
||||
std::vector<IIgnoreList::Info> MySQLDatabase::GetIgnoreList(const uint32_t playerId) {
|
||||
auto result = ExecuteSelect("SELECT ci.name AS name, il.ignored_player_id AS ignore_id FROM ignore_list AS il JOIN charinfo AS ci ON il.ignored_player_id = ci.id WHERE il.player_id = ?", playerId);
|
||||
|
||||
std::vector<IIgnoreList::Info> ignoreList;
|
||||
|
||||
ignoreList.reserve(result->rowsCount());
|
||||
while (result->next()) {
|
||||
ignoreList.push_back(IIgnoreList::Info{ result->getString("name").c_str(), result->getInt64("ignore_id") });
|
||||
ignoreList.push_back(IIgnoreList::Info{ result->getString("name").c_str(), result->getUInt("ignore_id") });
|
||||
}
|
||||
|
||||
return ignoreList;
|
||||
}
|
||||
|
||||
void MySQLDatabase::AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
|
||||
void MySQLDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
|
||||
ExecuteInsert("INSERT IGNORE INTO ignore_list (player_id, ignored_player_id) VALUES (?, ?)", playerId, ignoredPlayerId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
|
||||
void MySQLDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
|
||||
ExecuteDelete("DELETE FROM ignore_list WHERE player_id = ? AND ignored_player_id = ?", playerId, ignoredPlayerId);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ std::vector<ILeaderboard::Entry> ProcessQuery(UniqueResultSet& rows) {
|
||||
while (rows->next()) {
|
||||
auto& entry = entries.emplace_back();
|
||||
|
||||
entry.charId = rows->getUInt64("character_id");
|
||||
entry.charId = rows->getUInt("character_id");
|
||||
entry.lastPlayedTimestamp = rows->getUInt("lp_unix");
|
||||
entry.primaryScore = rows->getFloat("primaryScore");
|
||||
entry.secondaryScore = rows->getFloat("secondaryScore");
|
||||
@@ -58,21 +58,21 @@ std::vector<ILeaderboard::Entry> MySQLDatabase::GetNsLeaderboard(const uint32_t
|
||||
return ProcessQuery(leaderboard);
|
||||
}
|
||||
|
||||
void MySQLDatabase::SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) {
|
||||
void MySQLDatabase::SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) {
|
||||
ExecuteInsert("INSERT leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, character_id = ?, game_id = ?;",
|
||||
score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) {
|
||||
void MySQLDatabase::UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) {
|
||||
ExecuteInsert("UPDATE leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;",
|
||||
score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) {
|
||||
void MySQLDatabase::IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) {
|
||||
ExecuteUpdate("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId);
|
||||
}
|
||||
|
||||
std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) {
|
||||
std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) {
|
||||
std::optional<ILeaderboard::Score> toReturn = std::nullopt;
|
||||
auto res = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId);
|
||||
if (res->next()) {
|
||||
@@ -86,6 +86,6 @@ std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const LWOOBJID
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void MySQLDatabase::IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) {
|
||||
void MySQLDatabase::IncrementNumWins(const uint32_t playerId, const uint32_t gameId) {
|
||||
ExecuteUpdate("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ void MySQLDatabase::InsertNewMail(const MailInfo& mail) {
|
||||
mail.itemCount);
|
||||
}
|
||||
|
||||
std::vector<MailInfo> MySQLDatabase::GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) {
|
||||
std::vector<MailInfo> MySQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
||||
auto res = ExecuteSelect(
|
||||
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
|
||||
" FROM mail WHERE receiver_id=? limit ?;",
|
||||
@@ -61,7 +61,7 @@ std::optional<MailInfo> MySQLDatabase::GetMail(const uint64_t mailId) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
uint32_t MySQLDatabase::GetUnreadMailCount(const LWOOBJID characterId) {
|
||||
uint32_t MySQLDatabase::GetUnreadMailCount(const uint32_t characterId) {
|
||||
auto res = ExecuteSelect("SELECT COUNT(*) AS number_unread FROM mail WHERE receiver_id=? AND was_read=0;", characterId);
|
||||
|
||||
if (!res->next()) {
|
||||
|
||||
@@ -1,42 +1,17 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
std::optional<uint64_t> MySQLDatabase::GetCurrentPersistentId() {
|
||||
std::optional<uint32_t> MySQLDatabase::GetCurrentPersistentId() {
|
||||
auto result = ExecuteSelect("SELECT last_object_id FROM object_id_tracker");
|
||||
if (!result->next()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return result->getUInt64("last_object_id");
|
||||
return result->getUInt("last_object_id");
|
||||
}
|
||||
|
||||
void MySQLDatabase::InsertDefaultPersistentId() {
|
||||
ExecuteInsert("INSERT INTO object_id_tracker VALUES (1);");
|
||||
}
|
||||
|
||||
IObjectIdTracker::Range MySQLDatabase::GetPersistentIdRange() {
|
||||
IObjectIdTracker::Range range;
|
||||
auto prevCommit = GetAutoCommit();
|
||||
SetAutoCommit(false);
|
||||
|
||||
// THIS MUST ABSOLUTELY NOT FAIL. These IDs are expected to be unique. As such a transactional select is used to safely get a range
|
||||
// of IDs that will never be used again. A separate feature could track unused IDs and recycle them, but that is not implemented.
|
||||
ExecuteCustomQuery("START TRANSACTION;");
|
||||
// 200 seems like a good range to reserve at once. Only way this would be noticable is if a player
|
||||
// added hundreds of items at once.
|
||||
// Doing the update first ensures that all other connections are blocked from accessing this table until we commit.
|
||||
auto result = ExecuteUpdate("UPDATE object_id_tracker SET last_object_id = last_object_id + 200;");
|
||||
// If no rows were updated, it means the table is empty, so we need to insert the default row first.
|
||||
if (result == 0) {
|
||||
InsertDefaultPersistentId();
|
||||
result = ExecuteUpdate("UPDATE object_id_tracker SET last_object_id = last_object_id + 200;");
|
||||
}
|
||||
|
||||
// At this point all connections are waiting on us to finish the transaction, so we can safely select the ID we just set.
|
||||
auto selectRes = ExecuteSelect("SELECT last_object_id FROM object_id_tracker;");
|
||||
selectRes->next();
|
||||
range.maxID = selectRes->getUInt64("last_object_id");
|
||||
range.minID = range.maxID - 199;
|
||||
|
||||
ExecuteCustomQuery("COMMIT;");
|
||||
SetAutoCommit(prevCommit);
|
||||
return range;
|
||||
void MySQLDatabase::UpdatePersistentId(const uint32_t newId) {
|
||||
ExecuteUpdate("UPDATE object_id_tracker SET last_object_id = ?;", newId);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,6 @@
|
||||
#include "MySQLDatabase.h"
|
||||
#include "ePropertySortType.h"
|
||||
|
||||
IProperty::Info ReadPropertyInfo(UniqueResultSet& result) {
|
||||
IProperty::Info info;
|
||||
info.id = result->getUInt64("id");
|
||||
info.ownerId = result->getInt64("owner_id");
|
||||
info.cloneId = result->getUInt64("clone_id");
|
||||
info.name = result->getString("name").c_str();
|
||||
info.description = result->getString("description").c_str();
|
||||
info.privacyOption = result->getInt("privacy_option");
|
||||
info.rejectionReason = result->getString("rejection_reason").c_str();
|
||||
info.lastUpdatedTime = result->getUInt("last_updated");
|
||||
info.claimedTime = result->getUInt("time_claimed");
|
||||
info.reputation = result->getUInt("reputation");
|
||||
info.modApproved = result->getUInt("mod_approved");
|
||||
info.performanceCost = result->getFloat("performance_cost");
|
||||
return info;
|
||||
}
|
||||
|
||||
std::optional<IProperty::PropertyEntranceResult> MySQLDatabase::GetProperties(const IProperty::PropertyLookup& params) {
|
||||
std::optional<IProperty::PropertyEntranceResult> result;
|
||||
std::string query;
|
||||
@@ -134,7 +117,19 @@ std::optional<IProperty::PropertyEntranceResult> MySQLDatabase::GetProperties(co
|
||||
|
||||
while (properties->next()) {
|
||||
if (!result) result = IProperty::PropertyEntranceResult();
|
||||
result->entries.push_back(ReadPropertyInfo(properties));
|
||||
auto& entry = result->entries.emplace_back();
|
||||
entry.id = properties->getUInt64("id");
|
||||
entry.ownerId = properties->getUInt64("owner_id");
|
||||
entry.cloneId = properties->getUInt64("clone_id");
|
||||
entry.name = properties->getString("name").c_str();
|
||||
entry.description = properties->getString("description").c_str();
|
||||
entry.privacyOption = properties->getInt("privacy_option");
|
||||
entry.rejectionReason = properties->getString("rejection_reason").c_str();
|
||||
entry.lastUpdatedTime = properties->getUInt("last_updated");
|
||||
entry.claimedTime = properties->getUInt("time_claimed");
|
||||
entry.reputation = properties->getUInt("reputation");
|
||||
entry.modApproved = properties->getUInt("mod_approved");
|
||||
entry.performanceCost = properties->getFloat("performance_cost");
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -149,7 +144,21 @@ std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOMAPID map
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return ReadPropertyInfo(propertyEntry);
|
||||
IProperty::Info toReturn;
|
||||
toReturn.id = propertyEntry->getUInt64("id");
|
||||
toReturn.ownerId = propertyEntry->getUInt64("owner_id");
|
||||
toReturn.cloneId = propertyEntry->getUInt64("clone_id");
|
||||
toReturn.name = propertyEntry->getString("name").c_str();
|
||||
toReturn.description = propertyEntry->getString("description").c_str();
|
||||
toReturn.privacyOption = propertyEntry->getInt("privacy_option");
|
||||
toReturn.rejectionReason = propertyEntry->getString("rejection_reason").c_str();
|
||||
toReturn.lastUpdatedTime = propertyEntry->getUInt("last_updated");
|
||||
toReturn.claimedTime = propertyEntry->getUInt("time_claimed");
|
||||
toReturn.reputation = propertyEntry->getUInt("reputation");
|
||||
toReturn.modApproved = propertyEntry->getUInt("mod_approved");
|
||||
toReturn.performanceCost = propertyEntry->getFloat("performance_cost");
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void MySQLDatabase::UpdatePropertyModerationInfo(const IProperty::Info& info) {
|
||||
@@ -186,15 +195,3 @@ void MySQLDatabase::InsertNewProperty(const IProperty::Info& info, const uint32_
|
||||
zoneId.GetMapID()
|
||||
);
|
||||
}
|
||||
|
||||
std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOOBJID id) {
|
||||
auto propertyEntry = ExecuteSelect(
|
||||
"SELECT id, owner_id, clone_id, name, description, privacy_option, rejection_reason, last_updated, time_claimed, reputation, mod_approved, performance_cost "
|
||||
"FROM properties WHERE id = ?;", id);
|
||||
|
||||
if (!propertyEntry->next()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return ReadPropertyInfo(propertyEntry);
|
||||
}
|
||||
|
||||
@@ -64,27 +64,26 @@ void MySQLDatabase::RemoveModel(const LWOOBJID& modelId) {
|
||||
ExecuteDelete("DELETE FROM properties_contents WHERE id = ?;", modelId);
|
||||
}
|
||||
|
||||
std::optional<IPropertyContents::Model> MySQLDatabase::GetModel(const LWOOBJID modelID) {
|
||||
IPropertyContents::Model MySQLDatabase::GetModel(const LWOOBJID modelID) {
|
||||
auto result = ExecuteSelect("SELECT * FROM properties_contents WHERE id = ?", modelID);
|
||||
|
||||
std::optional<IPropertyContents::Model> model = std::nullopt;
|
||||
IPropertyContents::Model model{};
|
||||
while (result->next()) {
|
||||
model = IPropertyContents::Model{};
|
||||
model->id = result->getUInt64("id");
|
||||
model->lot = static_cast<LOT>(result->getUInt("lot"));
|
||||
model->position.x = result->getFloat("x");
|
||||
model->position.y = result->getFloat("y");
|
||||
model->position.z = result->getFloat("z");
|
||||
model->rotation.w = result->getFloat("rw");
|
||||
model->rotation.x = result->getFloat("rx");
|
||||
model->rotation.y = result->getFloat("ry");
|
||||
model->rotation.z = result->getFloat("rz");
|
||||
model->ugcId = result->getUInt64("ugc_id");
|
||||
model->behaviors[0] = result->getUInt64("behavior_1");
|
||||
model->behaviors[1] = result->getUInt64("behavior_2");
|
||||
model->behaviors[2] = result->getUInt64("behavior_3");
|
||||
model->behaviors[3] = result->getUInt64("behavior_4");
|
||||
model->behaviors[4] = result->getUInt64("behavior_5");
|
||||
model.id = result->getUInt64("id");
|
||||
model.lot = static_cast<LOT>(result->getUInt("lot"));
|
||||
model.position.x = result->getFloat("x");
|
||||
model.position.y = result->getFloat("y");
|
||||
model.position.z = result->getFloat("z");
|
||||
model.rotation.w = result->getFloat("rw");
|
||||
model.rotation.x = result->getFloat("rx");
|
||||
model.rotation.y = result->getFloat("ry");
|
||||
model.rotation.z = result->getFloat("rz");
|
||||
model.ugcId = result->getUInt64("ugc_id");
|
||||
model.behaviors[0] = result->getUInt64("behavior_1");
|
||||
model.behaviors[1] = result->getUInt64("behavior_2");
|
||||
model.behaviors[2] = result->getUInt64("behavior_3");
|
||||
model.behaviors[3] = result->getUInt64("behavior_4");
|
||||
model.behaviors[4] = result->getUInt64("behavior_5");
|
||||
}
|
||||
|
||||
return model;
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
IUgc::Model ReadModel(UniqueResultSet& result) {
|
||||
IUgc::Model model;
|
||||
|
||||
// blob is owned by the query, so we need to do a deep copy :/
|
||||
std::unique_ptr<std::istream> blob(result->getBlob("lxfml"));
|
||||
model.lxfmlData << blob->rdbuf();
|
||||
model.id = result->getUInt64("ugcID");
|
||||
model.modelID = result->getUInt64("modelID");
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
std::vector<IUgc::Model> MySQLDatabase::GetUgcModels(const LWOOBJID& propertyId) {
|
||||
auto result = ExecuteSelect(
|
||||
"SELECT lxfml, u.id as ugcID, pc.id as modelID FROM ugc AS u JOIN properties_contents AS pc ON u.id = pc.ugc_id WHERE lot = 14 AND property_id = ? AND pc.ugc_id IS NOT NULL;",
|
||||
@@ -20,7 +8,14 @@ std::vector<IUgc::Model> MySQLDatabase::GetUgcModels(const LWOOBJID& propertyId)
|
||||
std::vector<IUgc::Model> toReturn;
|
||||
|
||||
while (result->next()) {
|
||||
toReturn.push_back(ReadModel(result));
|
||||
IUgc::Model model;
|
||||
|
||||
// blob is owned by the query, so we need to do a deep copy :/
|
||||
std::unique_ptr<std::istream> blob(result->getBlob("lxfml"));
|
||||
model.lxfmlData << blob->rdbuf();
|
||||
model.id = result->getUInt64("ugcID");
|
||||
model.modelID = result->getUInt64("modelID");
|
||||
toReturn.push_back(std::move(model));
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
@@ -32,7 +27,14 @@ std::vector<IUgc::Model> MySQLDatabase::GetAllUgcModels() {
|
||||
std::vector<IUgc::Model> models;
|
||||
models.reserve(result->rowsCount());
|
||||
while (result->next()) {
|
||||
models.push_back(ReadModel(result));
|
||||
IUgc::Model model;
|
||||
model.id = result->getInt64("ugcID");
|
||||
model.modelID = result->getUInt64("modelID");
|
||||
|
||||
// blob is owned by the query, so we need to do a deep copy :/
|
||||
std::unique_ptr<std::istream> blob(result->getBlob("lxfml"));
|
||||
model.lxfmlData << blob->rdbuf();
|
||||
models.push_back(std::move(model));
|
||||
}
|
||||
|
||||
return models;
|
||||
@@ -43,10 +45,10 @@ void MySQLDatabase::RemoveUnreferencedUgcModels() {
|
||||
}
|
||||
|
||||
void MySQLDatabase::InsertNewUgcModel(
|
||||
std::stringstream& sd0Data, // cant be const sad
|
||||
const uint64_t blueprintId,
|
||||
std:: stringstream& sd0Data, // cant be const sad
|
||||
const uint32_t blueprintId,
|
||||
const uint32_t accountId,
|
||||
const LWOOBJID characterId) {
|
||||
const uint32_t characterId) {
|
||||
const std::istream stream(sd0Data.rdbuf());
|
||||
ExecuteInsert(
|
||||
"INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?)",
|
||||
@@ -69,14 +71,3 @@ void MySQLDatabase::UpdateUgcModelData(const LWOOBJID& modelId, std::stringstrea
|
||||
const std::istream stream(lxfml.rdbuf());
|
||||
ExecuteUpdate("UPDATE ugc SET lxfml = ? WHERE id = ?;", &stream, modelId);
|
||||
}
|
||||
|
||||
std::optional<IUgc::Model> MySQLDatabase::GetUgcModel(const LWOOBJID ugcId) {
|
||||
auto result = ExecuteSelect("SELECT u.id AS ugcID, lxfml, pc.id AS modelID FROM ugc AS u JOIN properties_contents AS pc ON pc.ugc_id = u.id WHERE u.id = ?", ugcId);
|
||||
|
||||
std::optional<IUgc::Model> toReturn = std::nullopt;
|
||||
if (result->next()) {
|
||||
toReturn = ReadModel(result);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
void MySQLDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) {
|
||||
void MySQLDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) {
|
||||
ExecuteInsert("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)", bigId, modules, characterId);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,13 +61,13 @@ bool SQLiteDatabase::GetAutoCommit() {
|
||||
|
||||
void SQLiteDatabase::SetAutoCommit(bool value) {
|
||||
if (value) {
|
||||
if (!GetAutoCommit()) con->compileStatement("COMMIT;").execDML();
|
||||
} else {
|
||||
if (GetAutoCommit()) con->compileStatement("BEGIN;").execDML();
|
||||
} else {
|
||||
if (!GetAutoCommit()) con->compileStatement("COMMIT;").execDML();
|
||||
}
|
||||
}
|
||||
|
||||
void SQLiteDatabase::DeleteCharacter(const LWOOBJID characterId) {
|
||||
void SQLiteDatabase::DeleteCharacter(const uint32_t characterId) {
|
||||
ExecuteDelete("DELETE FROM charxml WHERE id=?;", characterId);
|
||||
ExecuteDelete("DELETE FROM command_log WHERE character_id=?;", characterId);
|
||||
ExecuteDelete("DELETE FROM friends WHERE player_id=? OR friend_id=?;", characterId, characterId);
|
||||
|
||||
@@ -38,31 +38,31 @@ public:
|
||||
|
||||
std::vector<std::string> GetApprovedCharacterNames() override;
|
||||
|
||||
std::vector<FriendData> GetFriendsList(LWOOBJID charID) override;
|
||||
std::vector<FriendData> GetFriendsList(uint32_t charID) override;
|
||||
|
||||
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) override;
|
||||
void SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) override;
|
||||
void AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
|
||||
void RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
|
||||
void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) override;
|
||||
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override;
|
||||
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override;
|
||||
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
|
||||
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
|
||||
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override;
|
||||
void DeleteUgcModelData(const LWOOBJID& modelId) override;
|
||||
void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override;
|
||||
std::vector<IUgc::Model> GetAllUgcModels() override;
|
||||
void CreateMigrationHistoryTable() override;
|
||||
bool IsMigrationRun(const std::string_view str) override;
|
||||
void InsertMigration(const std::string_view str) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
|
||||
std::string GetCharacterXml(const LWOOBJID accountId) override;
|
||||
void UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) override;
|
||||
std::string GetCharacterXml(const uint32_t accountId) override;
|
||||
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override;
|
||||
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
|
||||
void InsertNewCharacter(const ICharInfo::Info info) override;
|
||||
void InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) override;
|
||||
std::vector<LWOOBJID> GetAccountCharacterIds(LWOOBJID accountId) override;
|
||||
void DeleteCharacter(const LWOOBJID characterId) override;
|
||||
void SetCharacterName(const LWOOBJID characterId, const std::string_view name) override;
|
||||
void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) override;
|
||||
void UpdateLastLoggedInCharacter(const LWOOBJID characterId) override;
|
||||
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override;
|
||||
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override;
|
||||
void DeleteCharacter(const uint32_t characterId) override;
|
||||
void SetCharacterName(const uint32_t characterId, const std::string_view name) override;
|
||||
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override;
|
||||
void UpdateLastLoggedInCharacter(const uint32_t characterId) override;
|
||||
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
|
||||
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
|
||||
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
|
||||
@@ -81,30 +81,30 @@ public:
|
||||
void InsertNewMail(const MailInfo& mail) override;
|
||||
void InsertNewUgcModel(
|
||||
std::stringstream& sd0Data,
|
||||
const uint64_t blueprintId,
|
||||
const uint32_t blueprintId,
|
||||
const uint32_t accountId,
|
||||
const LWOOBJID characterId) override;
|
||||
std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) override;
|
||||
const uint32_t characterId) override;
|
||||
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
||||
std::optional<MailInfo> GetMail(const uint64_t mailId) override;
|
||||
uint32_t GetUnreadMailCount(const LWOOBJID characterId) override;
|
||||
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
||||
void MarkMailRead(const uint64_t mailId) override;
|
||||
void DeleteMail(const uint64_t mailId) override;
|
||||
void ClaimMailItem(const uint64_t mailId) override;
|
||||
void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) override;
|
||||
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override;
|
||||
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
|
||||
void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
|
||||
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
|
||||
void InsertNewAccount(const std::string_view username, const std::string_view bcryptpassword) override;
|
||||
void SetMasterInfo(const IServers::MasterInfo& info) override;
|
||||
std::optional<uint64_t> GetCurrentPersistentId() override;
|
||||
IObjectIdTracker::Range GetPersistentIdRange() override;
|
||||
std::optional<uint32_t> GetCurrentPersistentId() override;
|
||||
void InsertDefaultPersistentId() override;
|
||||
void UpdatePersistentId(const uint32_t id) override;
|
||||
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
|
||||
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
|
||||
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
|
||||
void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
|
||||
void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
|
||||
std::vector<IIgnoreList::Info> GetIgnoreList(const LWOOBJID playerId) override;
|
||||
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
|
||||
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
|
||||
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override;
|
||||
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
|
||||
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
|
||||
void AddBehavior(const IBehaviors::Info& info) override;
|
||||
@@ -116,18 +116,16 @@ public:
|
||||
std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override;
|
||||
std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) override;
|
||||
std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override;
|
||||
void SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override;
|
||||
void UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override;
|
||||
std::optional<ILeaderboard::Score> GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) override;
|
||||
void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) override;
|
||||
void IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) override;
|
||||
void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) override;
|
||||
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override;
|
||||
void UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override;
|
||||
std::optional<ILeaderboard::Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) override;
|
||||
void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override;
|
||||
void IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) override;
|
||||
void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) override;
|
||||
void DeleteUgcBuild(const LWOOBJID bigId) override;
|
||||
uint32_t GetAccountCount() override;
|
||||
bool IsNameInUse(const std::string_view name) override;
|
||||
std::optional<IPropertyContents::Model> GetModel(const LWOOBJID modelID) override;
|
||||
std::optional<IUgc::Model> GetUgcModel(const LWOOBJID ugcId) override;
|
||||
std::optional<IProperty::Info> GetPropertyInfo(const LWOOBJID id) override;
|
||||
IPropertyContents::Model GetModel(const LWOOBJID modelID) override;
|
||||
private:
|
||||
CppSQLite3Statement CreatePreppedStmt(const std::string& query);
|
||||
|
||||
@@ -272,15 +270,4 @@ inline void SetParam(PreppedStmtRef stmt, const int index, const std::optional<u
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void SetParam(PreppedStmtRef stmt, const int index, const std::optional<LWOOBJID> param) {
|
||||
if (param) {
|
||||
LOG("%d", param.value());
|
||||
stmt.bind(index, static_cast<sqlite_int64>(param.value()));
|
||||
} else {
|
||||
LOG("Null");
|
||||
stmt.bindNull(index);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //!SQLITEDATABASE_H
|
||||
|
||||
@@ -17,7 +17,6 @@ std::optional<IAccounts::Info> SQLiteDatabase::GetAccountInfo(const std::string_
|
||||
toReturn.banned = result.getIntField("banned");
|
||||
toReturn.locked = result.getIntField("locked");
|
||||
toReturn.playKeyId = result.getIntField("play_key_id");
|
||||
toReturn.muteExpire = static_cast<uint64_t>(result.getInt64Field("mute_expire"));
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
void SQLiteDatabase::UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) {
|
||||
void SQLiteDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) {
|
||||
ExecuteInsert("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);",
|
||||
characterId, static_cast<uint32_t>(activityType), static_cast<uint32_t>(time(NULL)), mapId);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(CppSQLite3Query stmt) {
|
||||
|
||||
ICharInfo::Info toReturn;
|
||||
|
||||
toReturn.id = stmt.getInt64Field("id");
|
||||
toReturn.id = stmt.getIntField("id");
|
||||
toReturn.name = stmt.getStringField("name");
|
||||
toReturn.pendingName = stmt.getStringField("pending_name");
|
||||
toReturn.needsRename = stmt.getIntField("needs_rename");
|
||||
@@ -31,7 +31,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(CppSQLite3Query stmt) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const LWOOBJID charId) {
|
||||
std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const uint32_t charId) {
|
||||
return CharInfoFromQueryResult(
|
||||
ExecuteSelect("SELECT name, pending_name, needs_rename, prop_clone_id, permission_map, id, account_id FROM charinfo WHERE id = ? LIMIT 1;", charId).second
|
||||
);
|
||||
@@ -43,12 +43,12 @@ std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const std::strin
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<LWOOBJID> SQLiteDatabase::GetAccountCharacterIds(const LWOOBJID accountId) {
|
||||
std::vector<uint32_t> SQLiteDatabase::GetAccountCharacterIds(const uint32_t accountId) {
|
||||
auto [_, result] = ExecuteSelect("SELECT id FROM charinfo WHERE account_id = ? ORDER BY last_login DESC LIMIT 4;", accountId);
|
||||
|
||||
std::vector<LWOOBJID> toReturn;
|
||||
std::vector<uint32_t> toReturn;
|
||||
while (!result.eof()) {
|
||||
toReturn.push_back(result.getInt64Field("id"));
|
||||
toReturn.push_back(result.getIntField("id"));
|
||||
result.nextRow();
|
||||
}
|
||||
|
||||
@@ -66,15 +66,15 @@ void SQLiteDatabase::InsertNewCharacter(const ICharInfo::Info info) {
|
||||
static_cast<uint32_t>(time(NULL)));
|
||||
}
|
||||
|
||||
void SQLiteDatabase::SetCharacterName(const LWOOBJID characterId, const std::string_view name) {
|
||||
void SQLiteDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) {
|
||||
ExecuteUpdate("UPDATE charinfo SET name = ?, pending_name = '', needs_rename = 0, last_login = ? WHERE id = ?;", name, static_cast<uint32_t>(time(NULL)), characterId);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) {
|
||||
void SQLiteDatabase::SetPendingCharacterName(const uint32_t characterId, const std::string_view name) {
|
||||
ExecuteUpdate("UPDATE charinfo SET pending_name = ?, needs_rename = 0, last_login = ? WHERE id = ?;", name, static_cast<uint32_t>(time(NULL)), characterId);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::UpdateLastLoggedInCharacter(const LWOOBJID characterId) {
|
||||
void SQLiteDatabase::UpdateLastLoggedInCharacter(const uint32_t characterId) {
|
||||
ExecuteUpdate("UPDATE charinfo SET last_login = ? WHERE id = ?;", static_cast<uint32_t>(time(NULL)), characterId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
std::string SQLiteDatabase::GetCharacterXml(const LWOOBJID charId) {
|
||||
std::string SQLiteDatabase::GetCharacterXml(const uint32_t charId) {
|
||||
auto [_, result] = ExecuteSelect("SELECT xml_data FROM charxml WHERE id = ? LIMIT 1;", charId);
|
||||
|
||||
if (result.eof()) {
|
||||
@@ -10,10 +10,10 @@ std::string SQLiteDatabase::GetCharacterXml(const LWOOBJID charId) {
|
||||
return result.getStringField("xml_data");
|
||||
}
|
||||
|
||||
void SQLiteDatabase::UpdateCharacterXml(const LWOOBJID charId, const std::string_view lxfml) {
|
||||
void SQLiteDatabase::UpdateCharacterXml(const uint32_t charId, const std::string_view lxfml) {
|
||||
ExecuteUpdate("UPDATE charxml SET xml_data = ? WHERE id = ?;", lxfml, charId);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::InsertCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) {
|
||||
void SQLiteDatabase::InsertCharacterXml(const uint32_t characterId, const std::string_view lxfml) {
|
||||
ExecuteInsert("INSERT INTO `charxml` (`id`, `xml_data`) VALUES (?,?)", characterId, lxfml);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
void SQLiteDatabase::InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) {
|
||||
void SQLiteDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) {
|
||||
ExecuteInsert("INSERT INTO command_log (character_id, command) VALUES (?, ?);", characterId, command);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
std::vector<FriendData> SQLiteDatabase::GetFriendsList(const LWOOBJID charId) {
|
||||
std::vector<FriendData> SQLiteDatabase::GetFriendsList(const uint32_t charId) {
|
||||
auto [_, friendsList] = ExecuteSelect(
|
||||
R"QUERY(
|
||||
SELECT fr.requested_player AS player, best_friend AS bff, ci.name AS name FROM
|
||||
@@ -18,7 +18,7 @@ std::vector<FriendData> SQLiteDatabase::GetFriendsList(const LWOOBJID charId) {
|
||||
|
||||
while (!friendsList.eof()) {
|
||||
FriendData fd;
|
||||
fd.friendID = friendsList.getInt64Field("player");
|
||||
fd.friendID = friendsList.getIntField("player");
|
||||
fd.isBestFriend = friendsList.getIntField("bff") == 3; // 0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
|
||||
fd.friendName = friendsList.getStringField("name");
|
||||
|
||||
@@ -29,7 +29,7 @@ std::vector<FriendData> SQLiteDatabase::GetFriendsList(const LWOOBJID charId) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
std::optional<IFriends::BestFriendStatus> SQLiteDatabase::GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
|
||||
std::optional<IFriends::BestFriendStatus> SQLiteDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
|
||||
auto [_, result] = ExecuteSelect("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
|
||||
playerCharacterId,
|
||||
friendCharacterId,
|
||||
@@ -42,14 +42,14 @@ std::optional<IFriends::BestFriendStatus> SQLiteDatabase::GetBestFriendStatus(co
|
||||
}
|
||||
|
||||
IFriends::BestFriendStatus toReturn;
|
||||
toReturn.playerCharacterId = result.getInt64Field("player_id");
|
||||
toReturn.friendCharacterId = result.getInt64Field("friend_id");
|
||||
toReturn.playerCharacterId = result.getIntField("player_id");
|
||||
toReturn.friendCharacterId = result.getIntField("friend_id");
|
||||
toReturn.bestFriendStatus = result.getIntField("best_friend");
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void SQLiteDatabase::SetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId, const uint32_t bestFriendStatus) {
|
||||
void SQLiteDatabase::SetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId, const uint32_t bestFriendStatus) {
|
||||
ExecuteUpdate("UPDATE friends SET best_friend = ? WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?);",
|
||||
bestFriendStatus,
|
||||
playerCharacterId,
|
||||
@@ -59,11 +59,11 @@ void SQLiteDatabase::SetBestFriendStatus(const LWOOBJID playerCharacterId, const
|
||||
);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::AddFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
|
||||
void SQLiteDatabase::AddFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
|
||||
ExecuteInsert("INSERT OR IGNORE INTO friends (player_id, friend_id, best_friend) VALUES (?, ?, 0);", playerCharacterId, friendCharacterId);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::RemoveFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
|
||||
void SQLiteDatabase::RemoveFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
|
||||
ExecuteDelete("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?);",
|
||||
playerCharacterId,
|
||||
friendCharacterId,
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
std::vector<IIgnoreList::Info> SQLiteDatabase::GetIgnoreList(const LWOOBJID playerId) {
|
||||
std::vector<IIgnoreList::Info> SQLiteDatabase::GetIgnoreList(const uint32_t playerId) {
|
||||
auto [_, result] = ExecuteSelect("SELECT ci.name AS name, il.ignored_player_id AS ignore_id FROM ignore_list AS il JOIN charinfo AS ci ON il.ignored_player_id = ci.id WHERE il.player_id = ?", playerId);
|
||||
|
||||
std::vector<IIgnoreList::Info> ignoreList;
|
||||
|
||||
while (!result.eof()) {
|
||||
ignoreList.push_back(IIgnoreList::Info{ result.getStringField("name"), result.getInt64Field("ignore_id") });
|
||||
ignoreList.push_back(IIgnoreList::Info{ result.getStringField("name"), static_cast<uint32_t>(result.getIntField("ignore_id")) });
|
||||
result.nextRow();
|
||||
}
|
||||
|
||||
return ignoreList;
|
||||
}
|
||||
|
||||
void SQLiteDatabase::AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
|
||||
void SQLiteDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
|
||||
ExecuteInsert("INSERT OR IGNORE INTO ignore_list (player_id, ignored_player_id) VALUES (?, ?)", playerId, ignoredPlayerId);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
|
||||
void SQLiteDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
|
||||
ExecuteDelete("DELETE FROM ignore_list WHERE player_id = ? AND ignored_player_id = ?", playerId, ignoredPlayerId);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ std::vector<ILeaderboard::Entry> ProcessQuery(CppSQLite3Query& rows) {
|
||||
while (!rows.eof()) {
|
||||
auto& entry = entries.emplace_back();
|
||||
|
||||
entry.charId = rows.getInt64Field("character_id");
|
||||
entry.charId = rows.getIntField("character_id");
|
||||
entry.lastPlayedTimestamp = rows.getIntField("lp_unix");
|
||||
entry.primaryScore = rows.getFloatField("primaryScore");
|
||||
entry.secondaryScore = rows.getFloatField("secondaryScore");
|
||||
@@ -58,17 +58,17 @@ std::vector<ILeaderboard::Entry> SQLiteDatabase::GetNsLeaderboard(const uint32_t
|
||||
return ProcessQuery(result);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) {
|
||||
void SQLiteDatabase::SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) {
|
||||
ExecuteInsert("INSERT INTO leaderboard (primaryScore, secondaryScore, tertiaryScore, character_id, game_id, last_played) VALUES (?,?,?,?,?,CURRENT_TIMESTAMP) ;",
|
||||
score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) {
|
||||
void SQLiteDatabase::UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) {
|
||||
ExecuteInsert("UPDATE leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, timesPlayed = timesPlayed + 1, last_played = CURRENT_TIMESTAMP WHERE character_id = ? AND game_id = ?;",
|
||||
score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
|
||||
}
|
||||
|
||||
std::optional<ILeaderboard::Score> SQLiteDatabase::GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) {
|
||||
std::optional<ILeaderboard::Score> SQLiteDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) {
|
||||
std::optional<ILeaderboard::Score> toReturn = std::nullopt;
|
||||
auto [_, res] = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId);
|
||||
if (!res.eof()) {
|
||||
@@ -82,10 +82,10 @@ std::optional<ILeaderboard::Score> SQLiteDatabase::GetPlayerScore(const LWOOBJID
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void SQLiteDatabase::IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) {
|
||||
void SQLiteDatabase::IncrementNumWins(const uint32_t playerId, const uint32_t gameId) {
|
||||
ExecuteUpdate("UPDATE leaderboard SET numWins = numWins + 1, last_played = CURRENT_TIMESTAMP WHERE character_id = ? AND game_id = ?;", playerId, gameId);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) {
|
||||
void SQLiteDatabase::IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) {
|
||||
ExecuteUpdate("UPDATE leaderboard SET timesPlayed = timesPlayed + 1, last_played = CURRENT_TIMESTAMP WHERE character_id = ? AND game_id = ?;", playerId, gameId);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ void SQLiteDatabase::InsertNewMail(const MailInfo& mail) {
|
||||
mail.itemCount);
|
||||
}
|
||||
|
||||
std::vector<MailInfo> SQLiteDatabase::GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) {
|
||||
std::vector<MailInfo> SQLiteDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
||||
auto [_, res] = ExecuteSelect(
|
||||
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
|
||||
" FROM mail WHERE receiver_id=? limit ?;",
|
||||
@@ -60,7 +60,7 @@ std::optional<MailInfo> SQLiteDatabase::GetMail(const uint64_t mailId) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
uint32_t SQLiteDatabase::GetUnreadMailCount(const LWOOBJID characterId) {
|
||||
uint32_t SQLiteDatabase::GetUnreadMailCount(const uint32_t characterId) {
|
||||
auto [_, res] = ExecuteSelect("SELECT COUNT(*) AS number_unread FROM mail WHERE receiver_id=? AND was_read=0;", characterId);
|
||||
|
||||
if (res.eof()) {
|
||||
|
||||
@@ -1,40 +1,17 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
std::optional<uint64_t> SQLiteDatabase::GetCurrentPersistentId() {
|
||||
std::optional<uint32_t> SQLiteDatabase::GetCurrentPersistentId() {
|
||||
auto [_, result] = ExecuteSelect("SELECT last_object_id FROM object_id_tracker");
|
||||
if (result.eof()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return result.getInt64Field("last_object_id");
|
||||
return result.getIntField("last_object_id");
|
||||
}
|
||||
|
||||
void SQLiteDatabase::InsertDefaultPersistentId() {
|
||||
ExecuteInsert("INSERT INTO object_id_tracker VALUES (1);");
|
||||
}
|
||||
|
||||
IObjectIdTracker::Range SQLiteDatabase::GetPersistentIdRange() {
|
||||
IObjectIdTracker::Range range;
|
||||
auto prevCommit = GetAutoCommit();
|
||||
SetAutoCommit(false); // This begins the transaction for us if one is not already in progress
|
||||
|
||||
// THIS MUST ABSOLUTELY NOT FAIL. These IDs are expected to be unique. As such a transactional select is used to safely get a range
|
||||
// of IDs that will never be used again. A separate feature could track unused IDs and recycle them, but that is not implemented.
|
||||
// 200 seems like a good range to reserve at once. Only way this would be noticable is if a player
|
||||
// added hundreds of items at once.
|
||||
// Doing the update first ensures that all other connections are blocked from accessing this table until we commit.
|
||||
auto result = ExecuteUpdate("UPDATE object_id_tracker SET last_object_id = last_object_id + 200;");
|
||||
if (result == 0) {
|
||||
InsertDefaultPersistentId();
|
||||
result = ExecuteUpdate("UPDATE object_id_tracker SET last_object_id = last_object_id + 200;");
|
||||
}
|
||||
|
||||
// At this point all connections are waiting on us to finish the transaction, so we can safely select the ID we just set.
|
||||
auto [_, selectResult] = ExecuteSelect("SELECT last_object_id FROM object_id_tracker;");
|
||||
range.maxID = selectResult.getInt64Field("last_object_id");
|
||||
range.minID = range.maxID - 199;
|
||||
|
||||
// We must commit here manually, this will unlock the database for all other servers
|
||||
ExecuteCustomQuery("COMMIT;");
|
||||
SetAutoCommit(prevCommit);
|
||||
return range;
|
||||
void SQLiteDatabase::UpdatePersistentId(const uint32_t newId) {
|
||||
ExecuteUpdate("UPDATE object_id_tracker SET last_object_id = ?;", newId);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,6 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
#include "ePropertySortType.h"
|
||||
|
||||
IProperty::Info ReadPropertyInfo(CppSQLite3Query& propertyEntry) {
|
||||
IProperty::Info toReturn;
|
||||
toReturn.id = propertyEntry.getInt64Field("id");
|
||||
toReturn.ownerId = propertyEntry.getInt64Field("owner_id");
|
||||
toReturn.cloneId = propertyEntry.getInt64Field("clone_id");
|
||||
toReturn.name = propertyEntry.getStringField("name");
|
||||
toReturn.description = propertyEntry.getStringField("description");
|
||||
toReturn.privacyOption = propertyEntry.getIntField("privacy_option");
|
||||
toReturn.rejectionReason = propertyEntry.getStringField("rejection_reason");
|
||||
toReturn.lastUpdatedTime = propertyEntry.getIntField("last_updated");
|
||||
toReturn.claimedTime = propertyEntry.getIntField("time_claimed");
|
||||
toReturn.reputation = propertyEntry.getIntField("reputation");
|
||||
toReturn.modApproved = propertyEntry.getIntField("mod_approved");
|
||||
toReturn.performanceCost = propertyEntry.getFloatField("performance_cost");
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
std::optional<IProperty::PropertyEntranceResult> SQLiteDatabase::GetProperties(const IProperty::PropertyLookup& params) {
|
||||
std::optional<IProperty::PropertyEntranceResult> result;
|
||||
std::string query;
|
||||
@@ -135,7 +118,19 @@ std::optional<IProperty::PropertyEntranceResult> SQLiteDatabase::GetProperties(c
|
||||
auto& [_, properties] = propertiesRes;
|
||||
if (!properties.eof() && !result.has_value()) result = IProperty::PropertyEntranceResult();
|
||||
while (!properties.eof()) {
|
||||
result->entries.push_back(ReadPropertyInfo(properties));
|
||||
auto& entry = result->entries.emplace_back();
|
||||
entry.id = properties.getInt64Field("id");
|
||||
entry.ownerId = properties.getInt64Field("owner_id");
|
||||
entry.cloneId = properties.getInt64Field("clone_id");
|
||||
entry.name = properties.getStringField("name");
|
||||
entry.description = properties.getStringField("description");
|
||||
entry.privacyOption = properties.getIntField("privacy_option");
|
||||
entry.rejectionReason = properties.getStringField("rejection_reason");
|
||||
entry.lastUpdatedTime = properties.getIntField("last_updated");
|
||||
entry.claimedTime = properties.getIntField("time_claimed");
|
||||
entry.reputation = properties.getIntField("reputation");
|
||||
entry.modApproved = properties.getIntField("mod_approved");
|
||||
entry.performanceCost = properties.getFloatField("performance_cost");
|
||||
properties.nextRow();
|
||||
}
|
||||
|
||||
@@ -151,7 +146,21 @@ std::optional<IProperty::Info> SQLiteDatabase::GetPropertyInfo(const LWOMAPID ma
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return ReadPropertyInfo(propertyEntry);
|
||||
IProperty::Info toReturn;
|
||||
toReturn.id = propertyEntry.getInt64Field("id");
|
||||
toReturn.ownerId = propertyEntry.getInt64Field("owner_id");
|
||||
toReturn.cloneId = propertyEntry.getInt64Field("clone_id");
|
||||
toReturn.name = propertyEntry.getStringField("name");
|
||||
toReturn.description = propertyEntry.getStringField("description");
|
||||
toReturn.privacyOption = propertyEntry.getIntField("privacy_option");
|
||||
toReturn.rejectionReason = propertyEntry.getStringField("rejection_reason");
|
||||
toReturn.lastUpdatedTime = propertyEntry.getIntField("last_updated");
|
||||
toReturn.claimedTime = propertyEntry.getIntField("time_claimed");
|
||||
toReturn.reputation = propertyEntry.getIntField("reputation");
|
||||
toReturn.modApproved = propertyEntry.getIntField("mod_approved");
|
||||
toReturn.performanceCost = propertyEntry.getFloatField("performance_cost");
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void SQLiteDatabase::UpdatePropertyModerationInfo(const IProperty::Info& info) {
|
||||
@@ -188,15 +197,3 @@ void SQLiteDatabase::InsertNewProperty(const IProperty::Info& info, const uint32
|
||||
zoneId.GetMapID()
|
||||
);
|
||||
}
|
||||
|
||||
std::optional<IProperty::Info> SQLiteDatabase::GetPropertyInfo(const LWOOBJID id) {
|
||||
auto [_, propertyEntry] = ExecuteSelect(
|
||||
"SELECT id, owner_id, clone_id, name, description, privacy_option, rejection_reason, last_updated, time_claimed, reputation, mod_approved, performance_cost "
|
||||
"FROM properties WHERE id = ?;", id);
|
||||
|
||||
if (propertyEntry.eof()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return ReadPropertyInfo(propertyEntry);
|
||||
}
|
||||
|
||||
@@ -64,28 +64,27 @@ void SQLiteDatabase::RemoveModel(const LWOOBJID& modelId) {
|
||||
ExecuteDelete("DELETE FROM properties_contents WHERE id = ?;", modelId);
|
||||
}
|
||||
|
||||
std::optional<IPropertyContents::Model> SQLiteDatabase::GetModel(const LWOOBJID modelID) {
|
||||
IPropertyContents::Model SQLiteDatabase::GetModel(const LWOOBJID modelID) {
|
||||
auto [_, result] = ExecuteSelect("SELECT * FROM properties_contents WHERE id = ?", modelID);
|
||||
|
||||
std::optional<IPropertyContents::Model> model = std::nullopt;
|
||||
IPropertyContents::Model model{};
|
||||
if (!result.eof()) {
|
||||
do {
|
||||
model = IPropertyContents::Model{};
|
||||
model->id = result.getInt64Field("id");
|
||||
model->lot = static_cast<LOT>(result.getIntField("lot"));
|
||||
model->position.x = result.getFloatField("x");
|
||||
model->position.y = result.getFloatField("y");
|
||||
model->position.z = result.getFloatField("z");
|
||||
model->rotation.w = result.getFloatField("rw");
|
||||
model->rotation.x = result.getFloatField("rx");
|
||||
model->rotation.y = result.getFloatField("ry");
|
||||
model->rotation.z = result.getFloatField("rz");
|
||||
model->ugcId = result.getInt64Field("ugc_id");
|
||||
model->behaviors[0] = result.getInt64Field("behavior_1");
|
||||
model->behaviors[1] = result.getInt64Field("behavior_2");
|
||||
model->behaviors[2] = result.getInt64Field("behavior_3");
|
||||
model->behaviors[3] = result.getInt64Field("behavior_4");
|
||||
model->behaviors[4] = result.getInt64Field("behavior_5");
|
||||
model.id = result.getInt64Field("id");
|
||||
model.lot = static_cast<LOT>(result.getIntField("lot"));
|
||||
model.position.x = result.getFloatField("x");
|
||||
model.position.y = result.getFloatField("y");
|
||||
model.position.z = result.getFloatField("z");
|
||||
model.rotation.w = result.getFloatField("rw");
|
||||
model.rotation.x = result.getFloatField("rx");
|
||||
model.rotation.y = result.getFloatField("ry");
|
||||
model.rotation.z = result.getFloatField("rz");
|
||||
model.ugcId = result.getInt64Field("ugc_id");
|
||||
model.behaviors[0] = result.getInt64Field("behavior_1");
|
||||
model.behaviors[1] = result.getInt64Field("behavior_2");
|
||||
model.behaviors[2] = result.getInt64Field("behavior_3");
|
||||
model.behaviors[3] = result.getInt64Field("behavior_4");
|
||||
model.behaviors[4] = result.getInt64Field("behavior_5");
|
||||
} while (result.nextRow());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
IUgc::Model ReadModel(CppSQLite3Query& result) {
|
||||
IUgc::Model model;
|
||||
|
||||
int blobSize{};
|
||||
const auto* blob = result.getBlobField("lxfml", blobSize);
|
||||
model.lxfmlData << std::string(reinterpret_cast<const char*>(blob), blobSize);
|
||||
model.id = result.getInt64Field("ugcID");
|
||||
model.modelID = result.getInt64Field("modelID");
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
std::vector<IUgc::Model> SQLiteDatabase::GetUgcModels(const LWOOBJID& propertyId) {
|
||||
auto [_, result] = ExecuteSelect(
|
||||
"SELECT lxfml, u.id AS ugcID, pc.id AS modelID FROM ugc AS u JOIN properties_contents AS pc ON u.id = pc.ugc_id WHERE lot = 14 AND property_id = ? AND pc.ugc_id IS NOT NULL;",
|
||||
@@ -20,7 +8,14 @@ std::vector<IUgc::Model> SQLiteDatabase::GetUgcModels(const LWOOBJID& propertyId
|
||||
std::vector<IUgc::Model> toReturn;
|
||||
|
||||
while (!result.eof()) {
|
||||
toReturn.push_back(ReadModel(result));
|
||||
IUgc::Model model;
|
||||
|
||||
int blobSize{};
|
||||
const auto* blob = result.getBlobField("lxfml", blobSize);
|
||||
model.lxfmlData << std::string(reinterpret_cast<const char*>(blob), blobSize);
|
||||
model.id = result.getInt64Field("ugcID");
|
||||
model.modelID = result.getInt64Field("modelID");
|
||||
toReturn.push_back(std::move(model));
|
||||
result.nextRow();
|
||||
}
|
||||
|
||||
@@ -32,7 +27,14 @@ std::vector<IUgc::Model> SQLiteDatabase::GetAllUgcModels() {
|
||||
|
||||
std::vector<IUgc::Model> models;
|
||||
while (!result.eof()) {
|
||||
models.push_back(ReadModel(result));
|
||||
IUgc::Model model;
|
||||
model.id = result.getInt64Field("ugcID");
|
||||
model.modelID = result.getInt64Field("modelID");
|
||||
|
||||
int blobSize{};
|
||||
const auto* blob = result.getBlobField("lxfml", blobSize);
|
||||
model.lxfmlData << std::string(reinterpret_cast<const char*>(blob), blobSize);
|
||||
models.push_back(std::move(model));
|
||||
result.nextRow();
|
||||
}
|
||||
|
||||
@@ -45,9 +47,9 @@ void SQLiteDatabase::RemoveUnreferencedUgcModels() {
|
||||
|
||||
void SQLiteDatabase::InsertNewUgcModel(
|
||||
std::stringstream& sd0Data, // cant be const sad
|
||||
const uint64_t blueprintId,
|
||||
const uint32_t blueprintId,
|
||||
const uint32_t accountId,
|
||||
const LWOOBJID characterId) {
|
||||
const uint32_t characterId) {
|
||||
const std::istream stream(sd0Data.rdbuf());
|
||||
ExecuteInsert(
|
||||
"INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?)",
|
||||
@@ -70,14 +72,3 @@ void SQLiteDatabase::UpdateUgcModelData(const LWOOBJID& modelId, std::stringstre
|
||||
const std::istream stream(lxfml.rdbuf());
|
||||
ExecuteUpdate("UPDATE ugc SET lxfml = ? WHERE id = ?;", &stream, modelId);
|
||||
}
|
||||
|
||||
std::optional<IUgc::Model> SQLiteDatabase::GetUgcModel(const LWOOBJID ugcId) {
|
||||
auto [_, result] = ExecuteSelect("SELECT u.id AS ugcID, pc.id AS modelID, lxfml FROM ugc AS u JOIN properties_contents AS pc ON pc.id = u.id WHERE u.id = ?;", ugcId);
|
||||
|
||||
std::optional<IUgc::Model> toReturn = std::nullopt;
|
||||
if (!result.eof()) {
|
||||
toReturn = ReadModel(result);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "SQLiteDatabase.h"
|
||||
|
||||
void SQLiteDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) {
|
||||
void SQLiteDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) {
|
||||
ExecuteInsert("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)", bigId, modules, characterId);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,27 +32,27 @@ std::vector<std::string> TestSQLDatabase::GetApprovedCharacterNames() {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<FriendData> TestSQLDatabase::GetFriendsList(LWOOBJID charID) {
|
||||
std::vector<FriendData> TestSQLDatabase::GetFriendsList(uint32_t charID) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<IFriends::BestFriendStatus> TestSQLDatabase::GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
|
||||
std::optional<IFriends::BestFriendStatus> TestSQLDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void TestSQLDatabase::SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) {
|
||||
void TestSQLDatabase::SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) {
|
||||
void TestSQLDatabase::AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) {
|
||||
void TestSQLDatabase::RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) {
|
||||
void TestSQLDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) {
|
||||
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ void TestSQLDatabase::InsertMigration(const std::string_view str) {
|
||||
|
||||
}
|
||||
|
||||
std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const LWOOBJID charId) {
|
||||
std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const uint32_t charId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -88,11 +88,11 @@ std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const std::stri
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string TestSQLDatabase::GetCharacterXml(const LWOOBJID accountId) {
|
||||
std::string TestSQLDatabase::GetCharacterXml(const uint32_t accountId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void TestSQLDatabase::UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) {
|
||||
void TestSQLDatabase::UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) {
|
||||
|
||||
}
|
||||
|
||||
@@ -104,27 +104,27 @@ void TestSQLDatabase::InsertNewCharacter(const ICharInfo::Info info) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) {
|
||||
void TestSQLDatabase::InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) {
|
||||
|
||||
}
|
||||
|
||||
std::vector<LWOOBJID> TestSQLDatabase::GetAccountCharacterIds(LWOOBJID accountId) {
|
||||
std::vector<uint32_t> TestSQLDatabase::GetAccountCharacterIds(uint32_t accountId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void TestSQLDatabase::DeleteCharacter(const LWOOBJID characterId) {
|
||||
void TestSQLDatabase::DeleteCharacter(const uint32_t characterId) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::SetCharacterName(const LWOOBJID characterId, const std::string_view name) {
|
||||
void TestSQLDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) {
|
||||
void TestSQLDatabase::SetPendingCharacterName(const uint32_t characterId, const std::string_view name) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::UpdateLastLoggedInCharacter(const LWOOBJID characterId) {
|
||||
void TestSQLDatabase::UpdateLastLoggedInCharacter(const uint32_t characterId) {
|
||||
|
||||
}
|
||||
|
||||
@@ -192,11 +192,11 @@ void TestSQLDatabase::InsertNewMail(const MailInfo& mail) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::InsertNewUgcModel(std::stringstream& sd0Data, const uint64_t blueprintId, const uint32_t accountId, const LWOOBJID characterId) {
|
||||
void TestSQLDatabase::InsertNewUgcModel(std::stringstream& sd0Data, const uint32_t blueprintId, const uint32_t accountId, const uint32_t characterId) {
|
||||
|
||||
}
|
||||
|
||||
std::vector<MailInfo> TestSQLDatabase::GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) {
|
||||
std::vector<MailInfo> TestSQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ std::optional<MailInfo> TestSQLDatabase::GetMail(const uint64_t mailId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
uint32_t TestSQLDatabase::GetUnreadMailCount(const LWOOBJID characterId) {
|
||||
uint32_t TestSQLDatabase::GetUnreadMailCount(const uint32_t characterId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ void TestSQLDatabase::ClaimMailItem(const uint64_t mailId) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) {
|
||||
void TestSQLDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) {
|
||||
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ void TestSQLDatabase::SetMasterInfo(const IServers::MasterInfo& info) {
|
||||
|
||||
}
|
||||
|
||||
std::optional<uint64_t> TestSQLDatabase::GetCurrentPersistentId() {
|
||||
std::optional<uint32_t> TestSQLDatabase::GetCurrentPersistentId() {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -252,6 +252,10 @@ void TestSQLDatabase::InsertDefaultPersistentId() {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::UpdatePersistentId(const uint32_t id) {
|
||||
|
||||
}
|
||||
|
||||
std::optional<uint32_t> TestSQLDatabase::GetDonationTotal(const uint32_t activityId) {
|
||||
return {};
|
||||
}
|
||||
@@ -264,15 +268,15 @@ std::vector<IUgc::Model> TestSQLDatabase::GetUgcModels(const LWOOBJID& propertyI
|
||||
return {};
|
||||
}
|
||||
|
||||
void TestSQLDatabase::AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
|
||||
void TestSQLDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
|
||||
void TestSQLDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
|
||||
|
||||
}
|
||||
|
||||
std::vector<IIgnoreList::Info> TestSQLDatabase::GetIgnoreList(const LWOOBJID playerId) {
|
||||
std::vector<IIgnoreList::Info> TestSQLDatabase::GetIgnoreList(const uint32_t playerId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -300,6 +304,3 @@ void TestSQLDatabase::UpdateAccountGmLevel(const uint32_t accountId, const eGame
|
||||
|
||||
}
|
||||
|
||||
IObjectIdTracker::Range TestSQLDatabase::GetPersistentIdRange() {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -17,31 +17,31 @@ class TestSQLDatabase : public GameDatabase {
|
||||
|
||||
std::vector<std::string> GetApprovedCharacterNames() override;
|
||||
|
||||
std::vector<FriendData> GetFriendsList(LWOOBJID charID) override;
|
||||
std::vector<FriendData> GetFriendsList(uint32_t charID) override;
|
||||
|
||||
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) override;
|
||||
void SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) override;
|
||||
void AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
|
||||
void RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
|
||||
void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) override;
|
||||
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override;
|
||||
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override;
|
||||
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
|
||||
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
|
||||
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override;
|
||||
void DeleteUgcModelData(const LWOOBJID& modelId) override;
|
||||
void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override;
|
||||
std::vector<IUgc::Model> GetAllUgcModels() override;
|
||||
void CreateMigrationHistoryTable() override;
|
||||
bool IsMigrationRun(const std::string_view str) override;
|
||||
void InsertMigration(const std::string_view str) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override;
|
||||
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
|
||||
std::string GetCharacterXml(const LWOOBJID accountId) override;
|
||||
void UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) override;
|
||||
std::string GetCharacterXml(const uint32_t accountId) override;
|
||||
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override;
|
||||
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
|
||||
void InsertNewCharacter(const ICharInfo::Info info) override;
|
||||
void InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) override;
|
||||
std::vector<LWOOBJID> GetAccountCharacterIds(LWOOBJID accountId) override;
|
||||
void DeleteCharacter(const LWOOBJID characterId) override;
|
||||
void SetCharacterName(const LWOOBJID characterId, const std::string_view name) override;
|
||||
void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) override;
|
||||
void UpdateLastLoggedInCharacter(const LWOOBJID characterId) override;
|
||||
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override;
|
||||
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override;
|
||||
void DeleteCharacter(const uint32_t characterId) override;
|
||||
void SetCharacterName(const uint32_t characterId, const std::string_view name) override;
|
||||
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override;
|
||||
void UpdateLastLoggedInCharacter(const uint32_t characterId) override;
|
||||
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
|
||||
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
|
||||
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
|
||||
@@ -60,30 +60,30 @@ class TestSQLDatabase : public GameDatabase {
|
||||
void InsertNewMail(const MailInfo& mail) override;
|
||||
void InsertNewUgcModel(
|
||||
std::stringstream& sd0Data,
|
||||
const uint64_t blueprintId,
|
||||
const uint32_t blueprintId,
|
||||
const uint32_t accountId,
|
||||
const LWOOBJID characterId) override;
|
||||
std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) override;
|
||||
const uint32_t characterId) override;
|
||||
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
||||
std::optional<MailInfo> GetMail(const uint64_t mailId) override;
|
||||
uint32_t GetUnreadMailCount(const LWOOBJID characterId) override;
|
||||
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
||||
void MarkMailRead(const uint64_t mailId) override;
|
||||
void DeleteMail(const uint64_t mailId) override;
|
||||
void ClaimMailItem(const uint64_t mailId) override;
|
||||
void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) override;
|
||||
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override;
|
||||
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
|
||||
void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
|
||||
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
|
||||
void InsertNewAccount(const std::string_view username, const std::string_view bcryptpassword) override;
|
||||
void SetMasterInfo(const IServers::MasterInfo& info) override;
|
||||
std::optional<uint64_t> GetCurrentPersistentId() override;
|
||||
IObjectIdTracker::Range GetPersistentIdRange() override;
|
||||
std::optional<uint32_t> GetCurrentPersistentId() override;
|
||||
void InsertDefaultPersistentId() override;
|
||||
void UpdatePersistentId(const uint32_t id) override;
|
||||
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
|
||||
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
|
||||
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
|
||||
void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
|
||||
void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
|
||||
std::vector<IIgnoreList::Info> GetIgnoreList(const LWOOBJID playerId) override;
|
||||
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
|
||||
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
|
||||
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override;
|
||||
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
|
||||
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
|
||||
void AddBehavior(const IBehaviors::Info& info) override;
|
||||
@@ -95,19 +95,17 @@ class TestSQLDatabase : public GameDatabase {
|
||||
std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override { return {}; };
|
||||
std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) override { return {}; };
|
||||
std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override { return {}; };
|
||||
void SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override {};
|
||||
void UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override {};
|
||||
std::optional<ILeaderboard::Score> GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) override { return {}; };
|
||||
void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) override {};
|
||||
void IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) override {};
|
||||
void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) override {};
|
||||
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override {};
|
||||
void UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override {};
|
||||
std::optional<ILeaderboard::Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) override { return {}; };
|
||||
void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override {};
|
||||
void IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) override {};
|
||||
void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) override {};
|
||||
void DeleteUgcBuild(const LWOOBJID bigId) override {};
|
||||
uint32_t GetAccountCount() override { return 0; };
|
||||
|
||||
bool IsNameInUse(const std::string_view name) override { return false; };
|
||||
std::optional<IPropertyContents::Model> GetModel(const LWOOBJID modelID) override { return {}; }
|
||||
std::optional<IProperty::Info> GetPropertyInfo(const LWOOBJID id) override { return {}; }
|
||||
std::optional<IUgc::Model> GetUgcModel(const LWOOBJID ugcId) override { return {}; }
|
||||
IPropertyContents::Model GetModel(const LWOOBJID modelID) override { return {}; }
|
||||
};
|
||||
|
||||
#endif //!TESTSQLDATABASE_H
|
||||
|
||||
@@ -10,7 +10,7 @@ void ModelNormalizeMigration::Run() {
|
||||
for (auto& [lxfmlData, id, modelID] : Database::Get()->GetAllUgcModels()) {
|
||||
const auto model = Database::Get()->GetModel(modelID);
|
||||
// only BBB models (lot 14) and models with a position of NiPoint3::ZERO need to have their position fixed.
|
||||
if (!model || model->position != NiPoint3Constant::ZERO || model->lot != 14) continue;
|
||||
if (model.position != NiPoint3Constant::ZERO || model.lot != 14) continue;
|
||||
|
||||
Sd0 sd0(lxfmlData);
|
||||
const auto asStr = sd0.GetAsStringUncompressed();
|
||||
@@ -23,7 +23,7 @@ void ModelNormalizeMigration::Run() {
|
||||
LOG("Updated model %llu to have a center of %f %f %f", modelID, newCenter.x, newCenter.y, newCenter.z);
|
||||
sd0.FromData(reinterpret_cast<const uint8_t*>(newLxfml.data()), newLxfml.size());
|
||||
auto asStream = sd0.GetAsStream();
|
||||
Database::Get()->UpdateModel(model->id, newCenter, model->rotation, model->behaviors);
|
||||
Database::Get()->UpdateModel(model.id, newCenter, model.rotation, model.behaviors);
|
||||
Database::Get()->UpdateUgcModelData(id, asStream);
|
||||
}
|
||||
Database::Get()->SetAutoCommit(oldCommit);
|
||||
@@ -35,15 +35,15 @@ void ModelNormalizeMigration::RunAfterFirstPart() {
|
||||
for (auto& [lxfmlData, id, modelID] : Database::Get()->GetAllUgcModels()) {
|
||||
const auto model = Database::Get()->GetModel(modelID);
|
||||
// only BBB models (lot 14) need to have their position fixed from the above blunder
|
||||
if (!model || model->lot != 14) continue;
|
||||
if (model.lot != 14) continue;
|
||||
|
||||
Sd0 sd0(lxfmlData);
|
||||
const auto asStr = sd0.GetAsStringUncompressed();
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePositionAfterFirstPart(asStr, model->position);
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePositionAfterFirstPart(asStr, model.position);
|
||||
|
||||
sd0.FromData(reinterpret_cast<const uint8_t*>(newLxfml.data()), newLxfml.size());
|
||||
auto asStream = sd0.GetAsStream();
|
||||
Database::Get()->UpdateModel(model->id, newCenter, model->rotation, model->behaviors);
|
||||
Database::Get()->UpdateModel(model.id, newCenter, model.rotation, model.behaviors);
|
||||
Database::Get()->UpdateUgcModelData(id, asStream);
|
||||
}
|
||||
Database::Get()->SetAutoCommit(oldCommit);
|
||||
@@ -55,16 +55,16 @@ void ModelNormalizeMigration::RunBrickBuildGrid() {
|
||||
for (auto& [lxfmlData, id, modelID] : Database::Get()->GetAllUgcModels()) {
|
||||
const auto model = Database::Get()->GetModel(modelID);
|
||||
// only BBB models (lot 14) need to have their position fixed from the above blunder
|
||||
if (!model || model->lot != 14) continue;
|
||||
if (model.lot != 14) continue;
|
||||
|
||||
Sd0 sd0(lxfmlData);
|
||||
const auto asStr = sd0.GetAsStringUncompressed();
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePosition(asStr, model->position);
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePosition(asStr, model.position);
|
||||
|
||||
sd0.FromData(reinterpret_cast<const uint8_t*>(newLxfml.data()), newLxfml.size());
|
||||
LOG("Updated model %llu to have a center of %f %f %f", modelID, newCenter.x, newCenter.y, newCenter.z);
|
||||
auto asStream = sd0.GetAsStream();
|
||||
Database::Get()->UpdateModel(model->id, newCenter, model->rotation, model->behaviors);
|
||||
Database::Get()->UpdateModel(model.id, newCenter, model.rotation, model.behaviors);
|
||||
Database::Get()->UpdateUgcModelData(id, asStream);
|
||||
}
|
||||
Database::Get()->SetAutoCommit(oldCommit);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "ePlayerFlag.h"
|
||||
#include "CDPlayerFlagsTable.h"
|
||||
|
||||
Character::Character(LWOOBJID id, User* parentUser) {
|
||||
Character::Character(uint32_t id, User* parentUser) {
|
||||
//First load the name, etc:
|
||||
m_ID = id;
|
||||
m_ParentUser = parentUser;
|
||||
@@ -50,10 +50,6 @@ void Character::UpdateInfoFromDatabase() {
|
||||
|
||||
//Load the xmlData now:
|
||||
m_XMLData = Database::Get()->GetCharacterXml(m_ID);
|
||||
if (m_XMLData.empty()) {
|
||||
LOG("Character %s (%llu) has no xml data!", m_Name.c_str(), m_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
m_ZoneID = 0; //TEMP! Set back to 0 when done. This is so we can see loading screen progress for testing.
|
||||
m_ZoneInstanceID = 0; //These values don't really matter, these are only used on the char select screen and seem unused.
|
||||
@@ -65,6 +61,7 @@ void Character::UpdateInfoFromDatabase() {
|
||||
//Set our objectID:
|
||||
m_ObjectID = m_ID;
|
||||
GeneralUtils::SetBit(m_ObjectID, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(m_ObjectID, eObjectBits::PERSISTENT);
|
||||
|
||||
m_OurEntity = nullptr;
|
||||
m_BuildMode = false;
|
||||
@@ -78,7 +75,7 @@ void Character::DoQuickXMLDataParse() {
|
||||
if (m_XMLData.size() == 0) return;
|
||||
|
||||
if (m_Doc.Parse(m_XMLData.c_str(), m_XMLData.size()) == 0) {
|
||||
LOG("Loaded xmlData for character %s (%llu)!", m_Name.c_str(), m_ID);
|
||||
LOG("Loaded xmlData for character %s (%i)!", m_Name.c_str(), m_ID);
|
||||
} else {
|
||||
LOG("Failed to load xmlData (%i) (%s) (%s)!", m_Doc.ErrorID(), m_Doc.ErrorIDToName(m_Doc.ErrorID()), m_Doc.ErrorStr());
|
||||
//Server::rakServer->CloseConnection(m_ParentUser->GetSystemAddress(), true);
|
||||
@@ -241,7 +238,7 @@ void Character::SetBuildMode(bool buildMode) {
|
||||
void Character::SaveXMLToDatabase() {
|
||||
// Check that we can actually _save_ before saving
|
||||
if (!m_OurEntity) {
|
||||
LOG("%llu:%s didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!", this->GetID(), this->GetName().c_str());
|
||||
LOG("%i:%s didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!", this->GetID(), this->GetName().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -311,7 +308,7 @@ void Character::SaveXMLToDatabase() {
|
||||
//For metrics, log the time it took to save:
|
||||
auto end = std::chrono::system_clock::now();
|
||||
std::chrono::duration<double> elapsed = end - start;
|
||||
LOG("%llu:%s Saved character to Database in: %fs", this->GetID(), this->GetName().c_str(), elapsed.count());
|
||||
LOG("%i:%s Saved character to Database in: %fs", this->GetID(), this->GetName().c_str(), elapsed.count());
|
||||
}
|
||||
|
||||
void Character::SetIsNewLogin() {
|
||||
@@ -323,7 +320,7 @@ void Character::SetIsNewLogin() {
|
||||
while (currentChild) {
|
||||
auto* nextChild = currentChild->NextSiblingElement();
|
||||
if (currentChild->Attribute("si")) {
|
||||
LOG("Removed session flag (%s) from character %llu:%s, saving character to database", currentChild->Attribute("si"), GetID(), GetName().c_str());
|
||||
LOG("Removed session flag (%s) from character %i:%s, saving character to database", currentChild->Attribute("si"), GetID(), GetName().c_str());
|
||||
flags->DeleteChild(currentChild);
|
||||
WriteToDatabase();
|
||||
}
|
||||
@@ -336,11 +333,8 @@ void Character::WriteToDatabase() {
|
||||
tinyxml2::XMLPrinter printer(0, true, 0);
|
||||
m_Doc.Print(&printer);
|
||||
|
||||
// Update the xml on the character for future use if needed
|
||||
m_XMLData = printer.CStr();
|
||||
|
||||
//Finally, save to db:
|
||||
Database::Get()->UpdateCharacterXml(m_ID, m_XMLData);
|
||||
Database::Get()->UpdateCharacterXml(m_ID, printer.CStr());
|
||||
}
|
||||
|
||||
void Character::SetPlayerFlag(const uint32_t flagId, const bool value) {
|
||||
|
||||
@@ -23,7 +23,7 @@ enum class eLootSourceType : uint32_t;
|
||||
*/
|
||||
class Character {
|
||||
public:
|
||||
Character(LWOOBJID id, User* parentUser);
|
||||
Character(uint32_t id, User* parentUser);
|
||||
~Character();
|
||||
|
||||
/**
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
* Gets the database ID of the character
|
||||
* @return the database ID of the character
|
||||
*/
|
||||
LWOOBJID GetID() const { return m_ID; }
|
||||
uint32_t GetID() const { return m_ID; }
|
||||
|
||||
/**
|
||||
* Gets the (custom) name of the character
|
||||
@@ -467,9 +467,9 @@ public:
|
||||
private:
|
||||
void UpdateInfoFromDatabase();
|
||||
/**
|
||||
* The ID of this character.
|
||||
* The ID of this character. First 32 bits of the ObjectID.
|
||||
*/
|
||||
LWOOBJID m_ID{};
|
||||
uint32_t m_ID{};
|
||||
|
||||
/**
|
||||
* The 64-bit unique ID used in the game.
|
||||
@@ -654,7 +654,7 @@ private:
|
||||
/**
|
||||
* The spawn rotation of this character when loading in
|
||||
*/
|
||||
NiQuaternion m_OriginalRotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_OriginalRotation;
|
||||
|
||||
/**
|
||||
* The respawn points of this character, per world
|
||||
|
||||
@@ -304,7 +304,7 @@ void Entity::Initialize() {
|
||||
//If we came from another zone, put us in the starting loc
|
||||
if (m_Character->GetZoneID() != Game::server->GetZoneID() || mapID == 1603) { // Exception for Moon Base as you tend to spawn on the roof.
|
||||
NiPoint3 pos;
|
||||
NiQuaternion rot = QuatUtils::IDENTITY;
|
||||
NiQuaternion rot;
|
||||
|
||||
const auto& targetSceneName = m_Character->GetTargetScene();
|
||||
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
|
||||
@@ -1882,7 +1882,7 @@ const NiQuaternion& Entity::GetRotation() const {
|
||||
return rigidBodyPhantomPhysicsComponent->GetRotation();
|
||||
}
|
||||
|
||||
return QuatUtils::IDENTITY;
|
||||
return NiQuaternionConstant::IDENTITY;
|
||||
}
|
||||
|
||||
void Entity::SetPosition(const NiPoint3& position) {
|
||||
@@ -2178,7 +2178,7 @@ const NiPoint3& Entity::GetRespawnPosition() const {
|
||||
|
||||
const NiQuaternion& Entity::GetRespawnRotation() const {
|
||||
auto* characterComponent = GetComponent<CharacterComponent>();
|
||||
return characterComponent ? characterComponent->GetRespawnRotation() : QuatUtils::IDENTITY;
|
||||
return characterComponent ? characterComponent->GetRespawnRotation() : NiQuaternionConstant::IDENTITY;
|
||||
}
|
||||
|
||||
void Entity::SetRespawnPos(const NiPoint3& position) const {
|
||||
|
||||
@@ -357,7 +357,7 @@ private:
|
||||
std::vector<LDFBaseData*> m_NetworkSettings;
|
||||
|
||||
NiPoint3 m_DefaultPosition;
|
||||
NiQuaternion m_DefaultRotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_DefaultRotation;
|
||||
float m_Scale;
|
||||
|
||||
Spawner* m_Spawner;
|
||||
|
||||
@@ -52,43 +52,6 @@ std::vector<LOT> EntityManager::m_GhostingExcludedLOTs = {
|
||||
4967
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void ParseDelimSetting(std::set<T>& setting, const std::string_view settingName, const char delim = ',') {
|
||||
const auto str = Game::config->GetValue(settingName.data());
|
||||
setting.clear();
|
||||
for (const auto& strVal : GeneralUtils::SplitString(str, delim)) {
|
||||
const auto val = GeneralUtils::TryParse<T>(strVal);
|
||||
if (val) {
|
||||
setting.insert(val.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityManager::ReloadConfig() {
|
||||
auto hcmode = Game::config->GetValue("hardcore_mode");
|
||||
m_HardcoreMode = hcmode.empty() ? false : (hcmode == "1");
|
||||
auto hcUscorePercent = Game::config->GetValue("hardcore_lose_uscore_on_death_percent");
|
||||
m_HardcoreLoseUscoreOnDeathPercent = hcUscorePercent.empty() ? 10 : GeneralUtils::TryParse<uint32_t>(hcUscorePercent).value_or(10);
|
||||
auto hcUscoreMult = Game::config->GetValue("hardcore_uscore_enemies_multiplier");
|
||||
m_HardcoreUscoreEnemiesMultiplier = hcUscoreMult.empty() ? 2 : GeneralUtils::TryParse<uint32_t>(hcUscoreMult).value_or(2);
|
||||
auto hcDropInv = Game::config->GetValue("hardcore_dropinventory_on_death");
|
||||
m_HardcoreDropinventoryOnDeath = hcDropInv.empty() ? false : (hcDropInv == "1");
|
||||
ParseDelimSetting<LOT>(m_HardcoreExcludedItemDrops, "hardcore_excluded_item_drops");
|
||||
|
||||
// We don't need to save the worlds, just need to check if this one is in the list
|
||||
std::set<LWOMAPID> worlds;
|
||||
ParseDelimSetting<LWOMAPID>(worlds, "hardcore_uscore_reduced_worlds");
|
||||
m_HardcoreUscoreReduced = worlds.contains(Game::zoneManager->GetZoneID().GetMapID());
|
||||
|
||||
ParseDelimSetting<LOT>(m_HardcoreUscoreReducedLots, "hardcore_uscore_reduced_lots");
|
||||
ParseDelimSetting<LOT>(m_HardcoreUscoreExcludedEnemies, "hardcore_uscore_excluded_enemies");
|
||||
ParseDelimSetting<LWOMAPID>(m_HardcoreDisabledWorlds, "hardcore_disabled_worlds");
|
||||
|
||||
auto hcXpReduction = Game::config->GetValue("hardcore_uscore_reduction");
|
||||
m_HardcoreUscoreReduction = hcXpReduction.empty() ? 1.0f : GeneralUtils::TryParse<float>(hcXpReduction).value_or(1.0f);
|
||||
m_HardcoreMode = GetHardcoreDisabledWorlds().contains(Game::zoneManager->GetZoneID().GetMapID()) ? false : m_HardcoreMode;
|
||||
}
|
||||
|
||||
void EntityManager::Initialize() {
|
||||
// Check if this zone has ghosting enabled
|
||||
m_GhostingEnabled = std::find(
|
||||
@@ -98,8 +61,15 @@ void EntityManager::Initialize() {
|
||||
) == m_GhostingExcludedZones.end();
|
||||
|
||||
// grab hardcore mode settings and load them with sane defaults
|
||||
Game::config->AddConfigHandler([]() {Game::entityManager->ReloadConfig();});
|
||||
Game::entityManager->ReloadConfig();
|
||||
auto hcmode = Game::config->GetValue("hardcore_mode");
|
||||
m_HardcoreMode = hcmode.empty() ? false : (hcmode == "1");
|
||||
auto hcUscorePercent = Game::config->GetValue("hardcore_lose_uscore_on_death_percent");
|
||||
m_HardcoreLoseUscoreOnDeathPercent = hcUscorePercent.empty() ? 10 : std::stoi(hcUscorePercent);
|
||||
auto hcUscoreMult = Game::config->GetValue("hardcore_uscore_enemies_multiplier");
|
||||
m_HardcoreUscoreEnemiesMultiplier = hcUscoreMult.empty() ? 2 : std::stoi(hcUscoreMult);
|
||||
auto hcDropInv = Game::config->GetValue("hardcore_dropinventory_on_death");
|
||||
m_HardcoreDropinventoryOnDeath = hcDropInv.empty() ? false : (hcDropInv == "1");
|
||||
|
||||
// If cloneID is not zero, then hardcore mode is disabled
|
||||
// aka minigames and props
|
||||
if (Game::zoneManager->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false;
|
||||
|
||||
@@ -75,18 +75,11 @@ public:
|
||||
const uint32_t GetHardcoreLoseUscoreOnDeathPercent() { return m_HardcoreLoseUscoreOnDeathPercent; };
|
||||
const bool GetHardcoreDropinventoryOnDeath() { return m_HardcoreDropinventoryOnDeath; };
|
||||
const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; };
|
||||
const std::set<LOT>& GetHardcoreExcludedItemDrops() { return m_HardcoreExcludedItemDrops; };
|
||||
const float& GetHardcoreUscoreReduction() const { return m_HardcoreUscoreReduction; };
|
||||
bool GetHardcoreUscoreReduced() const { return m_HardcoreUscoreReduced; };
|
||||
const std::set<LOT>& GetHardcoreUscoreReducedLots() const { return m_HardcoreUscoreReducedLots; };
|
||||
const std::set<LOT>& GetHardcoreUscoreExcludedEnemies() const { return m_HardcoreUscoreExcludedEnemies; };
|
||||
const std::set<LWOMAPID>& GetHardcoreDisabledWorlds() const { return m_HardcoreDisabledWorlds; };
|
||||
|
||||
// Messaging
|
||||
bool SendMessage(GameMessages::GameMsg& msg) const;
|
||||
|
||||
private:
|
||||
void ReloadConfig();
|
||||
void SerializeEntities();
|
||||
void KillEntities();
|
||||
void DeleteEntities();
|
||||
@@ -119,12 +112,6 @@ private:
|
||||
uint32_t m_HardcoreLoseUscoreOnDeathPercent;
|
||||
bool m_HardcoreDropinventoryOnDeath;
|
||||
uint32_t m_HardcoreUscoreEnemiesMultiplier;
|
||||
std::set<LOT> m_HardcoreExcludedItemDrops;
|
||||
float m_HardcoreUscoreReduction{};
|
||||
bool m_HardcoreUscoreReduced{};
|
||||
std::set<LOT> m_HardcoreUscoreReducedLots{};
|
||||
std::set<LOT> m_HardcoreUscoreExcludedEnemies{};
|
||||
std::set<LWOMAPID> m_HardcoreDisabledWorlds{};
|
||||
};
|
||||
|
||||
#endif // ENTITYMANAGER_H
|
||||
|
||||
@@ -145,7 +145,7 @@ void QueryToLdf(Leaderboard& leaderboard, const std::vector<ILeaderboard::Entry>
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ILeaderboard::Entry> FilterToNumResults(const std::vector<ILeaderboard::Entry>& leaderboard, const LWOOBJID relatedPlayer, const Leaderboard::InfoType infoType, const uint32_t numResults) {
|
||||
std::vector<ILeaderboard::Entry> FilterToNumResults(const std::vector<ILeaderboard::Entry>& leaderboard, const uint32_t relatedPlayer, const Leaderboard::InfoType infoType, const uint32_t numResults) {
|
||||
std::vector<ILeaderboard::Entry> toReturn;
|
||||
|
||||
int32_t index = 0;
|
||||
@@ -197,7 +197,7 @@ std::vector<ILeaderboard::Entry> FilterWeeklies(const std::vector<ILeaderboard::
|
||||
return weeklyLeaderboard;
|
||||
}
|
||||
|
||||
std::vector<ILeaderboard::Entry> FilterFriends(const std::vector<ILeaderboard::Entry>& leaderboard, const LWOOBJID relatedPlayer) {
|
||||
std::vector<ILeaderboard::Entry> FilterFriends(const std::vector<ILeaderboard::Entry>& leaderboard, const uint32_t relatedPlayer) {
|
||||
// Filter the leaderboard to only include friends of the player
|
||||
auto friendOfPlayer = Database::Get()->GetFriendsList(relatedPlayer);
|
||||
std::vector<ILeaderboard::Entry> friendsLeaderboard;
|
||||
@@ -217,7 +217,7 @@ std::vector<ILeaderboard::Entry> ProcessLeaderboard(
|
||||
const std::vector<ILeaderboard::Entry>& leaderboard,
|
||||
const bool weekly,
|
||||
const Leaderboard::InfoType infoType,
|
||||
const LWOOBJID relatedPlayer,
|
||||
const uint32_t relatedPlayer,
|
||||
const uint32_t numResults) {
|
||||
std::vector<ILeaderboard::Entry> toReturn;
|
||||
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
#include "dZoneManager.h"
|
||||
#include "eServerDisconnectIdentifiers.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) {
|
||||
m_AccountID = 0;
|
||||
@@ -32,18 +28,18 @@ User::User(const SystemAddress& sysAddr, const std::string& username, const std:
|
||||
if (userInfo) {
|
||||
m_AccountID = userInfo->id;
|
||||
m_MaxGMLevel = userInfo->maxGmLevel;
|
||||
m_MuteExpire = userInfo->muteExpire;
|
||||
m_MuteExpire = 0; //res->getUInt64(3);
|
||||
}
|
||||
|
||||
//If we're loading a zone, we'll load the last used (aka current) character:
|
||||
if (Game::server->GetZoneID() != 0) {
|
||||
auto characterList = Database::Get()->GetAccountCharacterIds(m_AccountID);
|
||||
if (!characterList.empty()) {
|
||||
const auto lastUsedCharacterId = characterList.front();
|
||||
const uint32_t lastUsedCharacterId = characterList.front();
|
||||
Character* character = new Character(lastUsedCharacterId, this);
|
||||
character->UpdateFromDatabase();
|
||||
m_Characters.push_back(character);
|
||||
LOG("Loaded %llu as it is the last used char", lastUsedCharacterId);
|
||||
LOG("Loaded %i as it is the last used char", lastUsedCharacterId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,28 +91,8 @@ Character* User::GetLastUsedChar() {
|
||||
}
|
||||
}
|
||||
|
||||
bool User::GetIsMuted() {
|
||||
using namespace std::chrono;
|
||||
constexpr auto refreshInterval = seconds{ 60 };
|
||||
const auto now = steady_clock::now();
|
||||
if (now - m_LastMuteCheck >= refreshInterval) {
|
||||
m_LastMuteCheck = now;
|
||||
if (const auto info = Database::Get()->GetAccountInfo(m_Username)) {
|
||||
const auto expire = static_cast<time_t>(info->muteExpire);
|
||||
if (expire != m_MuteExpire) {
|
||||
m_MuteExpire = expire;
|
||||
|
||||
if (Game::chatServer && m_LoggedInCharID != 0) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
bitStream.Write(m_LoggedInCharID);
|
||||
bitStream.Write(m_MuteExpire);
|
||||
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_MuteExpire == 1 || m_MuteExpire > std::time(nullptr);
|
||||
bool User::GetIsMuted() const {
|
||||
return m_MuteExpire == 1 || m_MuteExpire > time(NULL);
|
||||
}
|
||||
|
||||
time_t User::GetMuteExpire() const {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include "RakNetTypes.h"
|
||||
#include "dCommonVars.h"
|
||||
|
||||
@@ -47,7 +46,7 @@ public:
|
||||
const std::unordered_map<std::string, bool>& GetIsBestFriendMap() { return m_IsBestFriendMap; }
|
||||
void UpdateBestFriendValue(const std::string_view playerName, const bool newValue);
|
||||
|
||||
bool GetIsMuted();
|
||||
bool GetIsMuted() const;
|
||||
|
||||
time_t GetMuteExpire() const;
|
||||
void SetMuteExpire(time_t value);
|
||||
@@ -73,8 +72,7 @@ private:
|
||||
bool m_LastChatMessageApproved = false;
|
||||
int m_AmountOfTimesOutOfSync = 0;
|
||||
const int m_MaxDesyncAllowed = 12;
|
||||
uint64_t m_MuteExpire;
|
||||
std::chrono::steady_clock::time_point m_LastMuteCheck{};
|
||||
time_t m_MuteExpire;
|
||||
};
|
||||
|
||||
#endif // USER_H
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "BitStreamUtils.h"
|
||||
#include "CheatDetection.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "eCharacterVersion.h"
|
||||
|
||||
UserManager* UserManager::m_Address = nullptr;
|
||||
|
||||
@@ -325,77 +324,79 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
LOG("AccountID: %i is creating a character with name: %s (temporary: %s)", u->GetAccountID(), name.c_str(), predefinedName.c_str());
|
||||
}
|
||||
|
||||
//Now that the name is ok, we can get a persistent ObjectID:
|
||||
LWOOBJID objectID = ObjectIDManager::GetPersistentID();
|
||||
const uint32_t maxRetries = 100;
|
||||
uint32_t tries = 0;
|
||||
while (Database::Get()->GetCharacterInfo(objectID) && tries < maxRetries) {
|
||||
tries++;
|
||||
LOG("Found a duplicate character %llu, getting a new objectID", objectID);
|
||||
objectID = ObjectIDManager::GetPersistentID();
|
||||
}
|
||||
//Now that the name is ok, we can get an objectID from Master:
|
||||
ObjectIDManager::RequestPersistentID([=, this](uint32_t objectID) {
|
||||
if (Database::Get()->GetCharacterInfo(objectID)) {
|
||||
LOG("Character object id unavailable, check object_id_tracker!");
|
||||
WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tries >= maxRetries) {
|
||||
LOG("Failed to get a unique objectID for new character after %i tries, aborting char creation for account %i", maxRetries, u->GetAccountID());
|
||||
WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE);
|
||||
return;
|
||||
}
|
||||
std::stringstream xml;
|
||||
xml << "<obj v=\"1\">";
|
||||
|
||||
std::stringstream xml;
|
||||
xml << "<obj v=\"1\">";
|
||||
xml << "<mf hc=\"" << hairColor << "\" hs=\"" << hairStyle << "\" hd=\"0\" t=\"" << shirtColor << "\" l=\"" << pantsColor;
|
||||
xml << "\" hdc=\"0\" cd=\"" << shirtStyle << "\" lh=\"" << lh << "\" rh=\"" << rh << "\" es=\"" << eyebrows << "\" ";
|
||||
xml << "ess=\"" << eyes << "\" ms=\"" << mouth << "\"/>";
|
||||
|
||||
xml << "<mf hc=\"" << hairColor << "\" hs=\"" << hairStyle << "\" hd=\"0\" t=\"" << shirtColor << "\" l=\"" << pantsColor;
|
||||
xml << "\" hdc=\"0\" cd=\"" << shirtStyle << "\" lh=\"" << lh << "\" rh=\"" << rh << "\" es=\"" << eyebrows << "\" ";
|
||||
xml << "ess=\"" << eyes << "\" ms=\"" << mouth << "\"/>";
|
||||
xml << "<char acct=\"" << u->GetAccountID() << "\" cc=\"0\" gm=\"0\" ft=\"0\" llog=\"" << time(NULL) << "\" ";
|
||||
xml << "ls=\"0\" lzx=\"-626.5847\" lzy=\"613.3515\" lzz=\"-28.6374\" lzrx=\"0.0\" lzry=\"0.7015\" lzrz=\"0.0\" lzrw=\"0.7126\" ";
|
||||
xml << "stt=\"0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;\">";
|
||||
xml << "<vl><l id=\"1000\" cid=\"0\"/></vl>";
|
||||
|
||||
xml << "<char acct=\"" << u->GetAccountID() << "\" cc=\"0\" gm=\"0\" ft=\"0\" llog=\"" << time(NULL) << "\" ";
|
||||
xml << "ls=\"0\" lzx=\"-626.5847\" lzy=\"613.3515\" lzz=\"-28.6374\" lzrx=\"0.0\" lzry=\"0.7015\" lzrz=\"0.0\" lzrw=\"0.7126\" ";
|
||||
xml << "stt=\"0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;\">";
|
||||
xml << "<vl><l id=\"1000\" cid=\"0\"/></vl>";
|
||||
xml << "</char>";
|
||||
|
||||
xml << "</char>";
|
||||
xml << "<dest hm=\"4\" hc=\"4\" im=\"0\" ic=\"0\" am=\"0\" ac=\"0\" d=\"0\"/>";
|
||||
|
||||
xml << "<dest hm=\"4\" hc=\"4\" im=\"0\" ic=\"0\" am=\"0\" ac=\"0\" d=\"0\"/>";
|
||||
xml << "<inv><bag><b t=\"0\" m=\"20\"/><b t=\"1\" m=\"40\"/><b t=\"2\" m=\"240\"/><b t=\"3\" m=\"240\"/><b t=\"14\" m=\"40\"/></bag><items><in t=\"0\">";
|
||||
|
||||
xml << "<inv><bag><b t=\"0\" m=\"20\"/><b t=\"1\" m=\"40\"/><b t=\"2\" m=\"240\"/><b t=\"3\" m=\"240\"/><b t=\"14\" m=\"40\"/></bag><items><in t=\"0\">";
|
||||
LWOOBJID lwoidforshirt = ObjectIDManager::GenerateRandomObjectID();
|
||||
LWOOBJID lwoidforpants;
|
||||
|
||||
LWOOBJID lwoidforshirt = ObjectIDManager::GetPersistentID();
|
||||
LWOOBJID lwoidforpants = ObjectIDManager::GetPersistentID();
|
||||
do {
|
||||
lwoidforpants = ObjectIDManager::GenerateRandomObjectID();
|
||||
} while (lwoidforpants == lwoidforshirt); //Make sure we don't have the same ID for both shirt and pants
|
||||
|
||||
xml << "<i l=\"" << shirtLOT << "\" id=\"" << lwoidforshirt << "\" s=\"0\" c=\"1\" eq=\"1\" b=\"1\"/>";
|
||||
xml << "<i l=\"" << pantsLOT << "\" id=\"" << lwoidforpants << "\" s=\"1\" c=\"1\" eq=\"1\" b=\"1\"/>";
|
||||
GeneralUtils::SetBit(lwoidforshirt, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(lwoidforshirt, eObjectBits::PERSISTENT);
|
||||
GeneralUtils::SetBit(lwoidforpants, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(lwoidforpants, eObjectBits::PERSISTENT);
|
||||
|
||||
xml << "</in></items></inv><lvl l=\"1\" cv=\"" << GeneralUtils::ToUnderlying(eCharacterVersion::UP_TO_DATE) << "\" sb=\"500\"/><flag></flag></obj>";
|
||||
xml << "<i l=\"" << shirtLOT << "\" id=\"" << lwoidforshirt << "\" s=\"0\" c=\"1\" eq=\"1\" b=\"1\"/>";
|
||||
xml << "<i l=\"" << pantsLOT << "\" id=\"" << lwoidforpants << "\" s=\"1\" c=\"1\" eq=\"1\" b=\"1\"/>";
|
||||
|
||||
//Check to see if our name was pre-approved:
|
||||
bool nameOk = IsNamePreapproved(name);
|
||||
if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true;
|
||||
xml << "</in></items></inv><lvl l=\"1\" cv=\"1\" sb=\"500\"/><flag></flag></obj>";
|
||||
|
||||
// If predefined name is invalid, change it to be their object id
|
||||
// that way more than one player can create characters if the predefined name files are not provided
|
||||
auto assignedPredefinedName = predefinedName;
|
||||
if (assignedPredefinedName == "INVALID") {
|
||||
std::stringstream nameObjID;
|
||||
nameObjID << "minifig" << objectID;
|
||||
assignedPredefinedName = nameObjID.str();
|
||||
}
|
||||
//Check to see if our name was pre-approved:
|
||||
bool nameOk = IsNamePreapproved(name);
|
||||
if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true;
|
||||
|
||||
std::string_view nameToAssign = !name.empty() && nameOk ? name : assignedPredefinedName;
|
||||
std::string pendingName = !name.empty() && !nameOk ? name : "";
|
||||
// If predefined name is invalid, change it to be their object id
|
||||
// that way more than one player can create characters if the predefined name files are not provided
|
||||
auto assignedPredefinedName = predefinedName;
|
||||
if (assignedPredefinedName == "INVALID") {
|
||||
std::stringstream nameObjID;
|
||||
nameObjID << "minifig" << objectID;
|
||||
assignedPredefinedName = nameObjID.str();
|
||||
}
|
||||
|
||||
ICharInfo::Info info;
|
||||
info.name = nameToAssign;
|
||||
info.pendingName = pendingName;
|
||||
info.id = objectID;
|
||||
info.accountId = u->GetAccountID();
|
||||
std::string_view nameToAssign = !name.empty() && nameOk ? name : assignedPredefinedName;
|
||||
std::string pendingName = !name.empty() && !nameOk ? name : "";
|
||||
|
||||
Database::Get()->InsertNewCharacter(info);
|
||||
ICharInfo::Info info;
|
||||
info.name = nameToAssign;
|
||||
info.pendingName = pendingName;
|
||||
info.id = objectID;
|
||||
info.accountId = u->GetAccountID();
|
||||
|
||||
//Now finally insert our character xml:
|
||||
Database::Get()->InsertCharacterXml(objectID, xml.str());
|
||||
Database::Get()->InsertNewCharacter(info);
|
||||
|
||||
WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::SUCCESS);
|
||||
UserManager::RequestCharacterList(sysAddr);
|
||||
//Now finally insert our character xml:
|
||||
Database::Get()->InsertCharacterXml(objectID, xml.str());
|
||||
|
||||
WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::SUCCESS);
|
||||
UserManager::RequestCharacterList(sysAddr);
|
||||
});
|
||||
}
|
||||
|
||||
void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) {
|
||||
@@ -408,8 +409,9 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID objectID;
|
||||
inStream.Read(objectID);
|
||||
uint32_t charID = static_cast<uint32_t>(objectID);
|
||||
|
||||
LOG("Received char delete req for ID: %llu", objectID);
|
||||
LOG("Received char delete req for ID: %llu (%u)", objectID, charID);
|
||||
|
||||
bool hasCharacter = CheatDetection::VerifyLwoobjidIsSender(
|
||||
objectID,
|
||||
@@ -421,8 +423,8 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
if (!hasCharacter) {
|
||||
WorldPackets::SendCharacterDeleteResponse(sysAddr, false);
|
||||
} else {
|
||||
LOG("Deleting character %llu", objectID);
|
||||
Database::Get()->DeleteCharacter(objectID);
|
||||
LOG("Deleting character %i", charID);
|
||||
Database::Get()->DeleteCharacter(charID);
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
@@ -443,8 +445,11 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID objectID;
|
||||
inStream.Read(objectID);
|
||||
GeneralUtils::ClearBit(objectID, eObjectBits::CHARACTER);
|
||||
GeneralUtils::ClearBit(objectID, eObjectBits::PERSISTENT);
|
||||
|
||||
LOG("Received char rename request for ID: %llu", objectID);
|
||||
uint32_t charID = static_cast<uint32_t>(objectID);
|
||||
LOG("Received char rename request for ID: %llu (%u)", objectID, charID);
|
||||
|
||||
LUWString LUWStringName;
|
||||
inStream.Read(LUWStringName);
|
||||
@@ -461,7 +466,7 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
u->GetAccountID());
|
||||
|
||||
auto unusedItr = std::find_if(u->GetCharacters().begin(), u->GetCharacters().end(), [&](Character* c) {
|
||||
if (c->GetID() == objectID) {
|
||||
if (c->GetID() == charID) {
|
||||
character = c;
|
||||
return true;
|
||||
}
|
||||
@@ -478,12 +483,12 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
|
||||
if (!Database::Get()->GetCharacterInfo(newName)) {
|
||||
if (IsNamePreapproved(newName)) {
|
||||
Database::Get()->SetCharacterName(objectID, newName);
|
||||
Database::Get()->SetCharacterName(charID, newName);
|
||||
LOG("Character %s now known as %s", character->GetName().c_str(), newName.c_str());
|
||||
WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS);
|
||||
UserManager::RequestCharacterList(sysAddr);
|
||||
} else {
|
||||
Database::Get()->SetPendingCharacterName(objectID, newName);
|
||||
Database::Get()->SetPendingCharacterName(charID, newName);
|
||||
LOG("Character %s has been renamed to %s and is pending approval by a moderator.", character->GetName().c_str(), newName.c_str());
|
||||
WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS);
|
||||
UserManager::RequestCharacterList(sysAddr);
|
||||
@@ -497,7 +502,7 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
}
|
||||
}
|
||||
|
||||
void UserManager::LoginCharacter(const SystemAddress& sysAddr, LWOOBJID playerID) {
|
||||
void UserManager::LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID) {
|
||||
User* u = GetUser(sysAddr);
|
||||
if (!u) {
|
||||
LOG("Couldn't get user to log in character");
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
void CreateCharacter(const SystemAddress& sysAddr, Packet* packet);
|
||||
void DeleteCharacter(const SystemAddress& sysAddr, Packet* packet);
|
||||
void RenameCharacter(const SystemAddress& sysAddr, Packet* packet);
|
||||
void LoginCharacter(const SystemAddress& sysAddr, LWOOBJID playerID);
|
||||
void LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID);
|
||||
|
||||
void SaveAllActiveCharacters();
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "BehaviorContext.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream& bitStream, BehaviorBranchContext branch) {
|
||||
Entity* sourceEntity;
|
||||
if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator);
|
||||
@@ -18,12 +16,12 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS
|
||||
if (!destinationEntity) return;
|
||||
|
||||
sourceEntity->SetRotation(
|
||||
QuatUtils::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition())
|
||||
NiQuaternion::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition())
|
||||
);
|
||||
} else if (this->m_toAngle){
|
||||
auto baseAngle = NiPoint3(0, 0, this->m_angle);
|
||||
if (this->m_relative) baseAngle += QuatUtils::Forward(sourceEntity->GetRotation());
|
||||
sourceEntity->SetRotation(glm::quat(glm::vec3(baseAngle.x, baseAngle.y, baseAngle.z)));
|
||||
if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector();
|
||||
sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle));
|
||||
} else return;
|
||||
Game::entityManager->SerializeEntity(sourceEntity);
|
||||
return;
|
||||
|
||||
@@ -48,7 +48,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
|
||||
if (controllablePhysicsComponent != nullptr) {
|
||||
|
||||
if (m_Forward == 1) {
|
||||
controllablePhysicsComponent->SetVelocity(QuatUtils::Forward(controllablePhysicsComponent->GetRotation()) * 25);
|
||||
controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25);
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(casterEntity);
|
||||
|
||||
@@ -92,7 +92,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
|
||||
|
||||
const auto time = distance / this->m_projectileSpeed;
|
||||
|
||||
const auto rotation = QuatUtils::LookAtUnlocked(position, other->GetPosition());
|
||||
const auto rotation = NiQuaternion::LookAtUnlocked(position, other->GetPosition());
|
||||
|
||||
const auto targetPosition = other->GetPosition();
|
||||
|
||||
@@ -112,13 +112,13 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
|
||||
|
||||
bitStream.Write(id);
|
||||
|
||||
auto eulerAngles = QuatUtils::Euler(rotation);
|
||||
auto eulerAngles = rotation.GetEulerAngles();
|
||||
|
||||
eulerAngles.y += angle * (glm::pi<float>() / 180.0f);
|
||||
eulerAngles.y += angle * (3.14 / 180);
|
||||
|
||||
const auto angledRotation = QuatUtils::FromEuler(eulerAngles);
|
||||
const auto angledRotation = NiQuaternion::FromEulerAngles(eulerAngles);
|
||||
|
||||
const auto direction = QuatUtils::Forward(angledRotation);
|
||||
const auto direction = angledRotation.GetForwardVector();
|
||||
|
||||
const auto destination = position + direction * distance;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStrea
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = context->originator;
|
||||
info.spawnerNodeID = 0;
|
||||
info.pos = info.pos + (QuatUtils::Forward(info.rot) * m_Distance);
|
||||
info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance);
|
||||
|
||||
auto* entity = Game::entityManager->CreateEntity(
|
||||
info,
|
||||
|
||||
@@ -125,7 +125,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream& bitS
|
||||
if (targetPos.y > reference.y && heightDifference > this->m_upperBound || targetPos.y < reference.y && heightDifference > this->m_lowerBound)
|
||||
continue;
|
||||
|
||||
const auto forward = QuatUtils::Forward(self->GetRotation());
|
||||
const auto forward = self->GetRotation().GetForwardVector();
|
||||
|
||||
// forward is a normalized vector of where the caster is facing.
|
||||
// targetPos is the position of the target.
|
||||
|
||||
@@ -353,7 +353,7 @@ private:
|
||||
/**
|
||||
* The database information for this activity
|
||||
*/
|
||||
CDActivities m_ActivityInfo{};
|
||||
CDActivities m_ActivityInfo;
|
||||
|
||||
/**
|
||||
* All the active instances of this activity
|
||||
|
||||
@@ -767,7 +767,7 @@ void BaseCombatAIComponent::LookAt(const NiPoint3& point) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Parent->SetRotation(QuatUtils::LookAt(m_Parent->GetPosition(), point));
|
||||
m_Parent->SetRotation(NiQuaternion::LookAt(m_Parent->GetPosition(), point));
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetDisabled(bool value) {
|
||||
|
||||
@@ -77,4 +77,4 @@ target_include_directories(dComponents PUBLIC "."
|
||||
)
|
||||
target_precompile_headers(dComponents REUSE_FROM dGameBase)
|
||||
|
||||
target_link_libraries(dComponents INTERFACE dBehaviors PRIVATE glm::glm)
|
||||
target_link_libraries(dComponents INTERFACE dBehaviors)
|
||||
|
||||
@@ -622,7 +622,7 @@ private:
|
||||
|
||||
NiPoint3 m_respawnPos;
|
||||
|
||||
NiQuaternion m_respawnRot = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_respawnRot;
|
||||
|
||||
std::map<LWOOBJID, Loot::Info> m_DroppedLoot;
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eStateChangeType.h"
|
||||
#include "eGameActivity.h"
|
||||
#include <ranges>
|
||||
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
|
||||
@@ -667,6 +666,11 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
return;
|
||||
}
|
||||
|
||||
//check if hardcore mode is enabled
|
||||
if (Game::entityManager->GetHardcoreMode()) {
|
||||
DoHardcoreModeDrops(source);
|
||||
}
|
||||
|
||||
Smash(source, eKillType::VIOLENT, u"", skillID);
|
||||
}
|
||||
|
||||
@@ -694,11 +698,6 @@ void DestroyableComponent::NotifySubscribers(Entity* attacker, uint32_t damage)
|
||||
}
|
||||
|
||||
void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType, uint32_t skillID) {
|
||||
//check if hardcore mode is enabled
|
||||
if (Game::entityManager->GetHardcoreMode()) {
|
||||
DoHardcoreModeDrops(source);
|
||||
}
|
||||
|
||||
if (m_iHealth > 0) {
|
||||
SetArmor(0);
|
||||
SetHealth(0);
|
||||
@@ -982,8 +981,7 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
|
||||
auto* character = m_Parent->GetComponent<CharacterComponent>();
|
||||
auto uscore = character->GetUScore();
|
||||
|
||||
auto uscoreToLose = static_cast<uint64_t>(uscore * (Game::entityManager->GetHardcoreLoseUscoreOnDeathPercent() / 100.0f));
|
||||
LOG("Player %llu has lost %llu uscore!", m_Parent->GetObjectID(), uscoreToLose);
|
||||
auto uscoreToLose = uscore * (Game::entityManager->GetHardcoreLoseUscoreOnDeathPercent() / 100);
|
||||
character->SetUScore(uscore - uscoreToLose);
|
||||
|
||||
GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::MISSION);
|
||||
@@ -997,11 +995,13 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
|
||||
if (items) {
|
||||
auto itemMap = items->GetItems();
|
||||
if (!itemMap.empty()) {
|
||||
for (const auto item : itemMap | std::views::values) {
|
||||
// Don't drop excluded items or null ones
|
||||
if (!item || Game::entityManager->GetHardcoreExcludedItemDrops().contains(item->GetLot())) continue;
|
||||
GameMessages::SendDropClientLoot(m_Parent, source, item->GetLot(), 0, m_Parent->GetPosition(), item->GetCount());
|
||||
item->SetCount(0, false, false);
|
||||
for (const auto& item : itemMap) {
|
||||
//drop the item:
|
||||
if (!item.second) continue;
|
||||
// don't drop the thinkng cap
|
||||
if (item.second->GetLot() == 6086) continue;
|
||||
GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount());
|
||||
item.second->SetCount(0, false, false);
|
||||
}
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
@@ -1020,25 +1020,24 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
|
||||
//drop all coins:
|
||||
GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, coins, m_Parent->GetPosition());
|
||||
}
|
||||
|
||||
// Reload the player since we can't normally reduce uscore from the server and we want the UI to update
|
||||
// do this last so we don't get killed.... again
|
||||
Game::entityManager->DestructEntity(m_Parent);
|
||||
Game::entityManager->ConstructEntity(m_Parent);
|
||||
return;
|
||||
}
|
||||
|
||||
//award the player some u-score:
|
||||
auto* player = Game::entityManager->GetEntity(source);
|
||||
if (player && player->IsPlayer()) {
|
||||
const auto lot = m_Parent->GetLOT();
|
||||
auto* playerStats = player->GetComponent<CharacterComponent>();
|
||||
if (playerStats && GetMaxHealth() > 0 && !Game::entityManager->GetHardcoreUscoreExcludedEnemies().contains(lot)) {
|
||||
if (playerStats) {
|
||||
//get the maximum health from this enemy:
|
||||
auto maxHealth = GetMaxHealth();
|
||||
const auto uscoreMultiplier = Game::entityManager->GetHardcoreUscoreEnemiesMultiplier();
|
||||
const bool isUscoreReducedLot =
|
||||
Game::entityManager->GetHardcoreUscoreReducedLots().contains(lot) ||
|
||||
Game::entityManager->GetHardcoreUscoreReduced();
|
||||
const auto uscoreReduction = isUscoreReducedLot ? Game::entityManager->GetHardcoreUscoreReduction() : 1.0f;
|
||||
|
||||
int uscore = maxHealth * Game::entityManager->GetHardcoreUscoreEnemiesMultiplier() * uscoreReduction;
|
||||
LOG("Rewarding player %llu with %i uscore for killing enemy %i", player->GetObjectID(), uscore, lot);
|
||||
int uscore = maxHealth * Game::entityManager->GetHardcoreUscoreEnemiesMultiplier();
|
||||
|
||||
playerStats->SetUScore(playerStats->GetUScore() + uscore);
|
||||
GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::MISSION);
|
||||
|
||||
|
||||
@@ -626,8 +626,7 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument& document) {
|
||||
for (const auto& pair : this->m_Inventories) {
|
||||
auto* inventory = pair.second;
|
||||
|
||||
static const auto EXCLUDED_INVENTORIES = {VENDOR_BUYBACK, MODELS_IN_BBB, ITEM_SETS};
|
||||
if (std::ranges::find(EXCLUDED_INVENTORIES, inventory->GetType()) != EXCLUDED_INVENTORIES.end()) {
|
||||
if (inventory->GetType() == VENDOR_BUYBACK || inventory->GetType() == eInventoryType::MODELS_IN_BBB) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1280,7 +1279,7 @@ void InventoryComponent::SpawnPet(Item* item) {
|
||||
EntityInfo info{};
|
||||
info.lot = item->GetLot();
|
||||
info.pos = m_Parent->GetPosition();
|
||||
info.rot = QuatUtils::IDENTITY;
|
||||
info.rot = NiQuaternionConstant::IDENTITY;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
|
||||
auto* pet = Game::entityManager->CreateEntity(info);
|
||||
@@ -1787,9 +1786,3 @@ void InventoryComponent::LoadGroupXml(const tinyxml2::XMLElement& groups) {
|
||||
groupElement = groupElement->NextSiblingElement("grp");
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::RegenerateItemIDs() {
|
||||
for (auto* const inventory : m_Inventories | std::views::values) {
|
||||
inventory->RegenerateItemIDs();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,14 +402,10 @@ public:
|
||||
bool SetSkill(BehaviorSlot slot, uint32_t skillId);
|
||||
|
||||
void UpdateGroup(const GroupUpdate& groupUpdate);
|
||||
|
||||
std::unordered_map<LWOOBJID, DatabasePet>& GetPetsMut() { return m_Pets; };
|
||||
void RemoveGroup(const std::string& groupId);
|
||||
|
||||
void FixInvisibleItems();
|
||||
|
||||
// Used to migrate a character version, no need to call outside of that context
|
||||
void RegenerateItemIDs();
|
||||
|
||||
~InventoryComponent() override;
|
||||
|
||||
private:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user