Compare commits

...

35 Commits

Author SHA1 Message Date
David Markowitz
7093f27b47 feat: Hardcore mode settings 2025-09-23 00:45:41 -07:00
David Markowitz
4a5dd68e87 fix: hardcore mode fixes (#1882)
fixes hardcore modes uscore drops
adds config option for excluded item drops
2025-09-21 18:36:32 -07:00
David Markowitz
4a577f233d fix: hardcore mode fixes (#1883)
fixes hardcore modes uscore drops
adds config option for excluded item drops

f

feat: Add logging for config options on load and reload

feat: Add logging for config options on load and reload
2025-09-21 20:12:50 -05:00
David Markowitz
bb05b3ac0d feat: Add logging for testing Johnny missions (#1880) 2025-09-20 17:22:16 -07:00
David Markowitz
06022e4b19 fix: use after free in TCPInterface (#1879)
lol
2025-09-19 01:12:34 -05:00
David Markowitz
6389876c6e feat: convert character ids to 64 bits (#1878)
* feat: convert character ids to 64 bits

remove all usages of the PERSISTENT bit with regards to storing of playerIDs on the server.  the bit does not exist and was a phantom in the first place.
Tested that a full playthrough of ag, ns and gf was still doable.  slash commands work, ugc works, friends works, ignore list works, properties work and have names, teaming works.
migrating an old mysql database works . need to test an old sqlite database

* fix sqlite migration

* remove nd specific column migration
2025-09-19 01:12:23 -05:00
David Markowitz
68f2e2dee2 Fix FetchContent_Declare speed (#1875) 2025-09-12 03:32:15 -05:00
HailStorm32
b798da8ef8 fix: Update mute expiry from database (#1871)
* Update mute expiry from database

* Address review comments

* Address review comment

Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>

---------

Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>
2025-09-08 23:07:08 -07:00
Copilot
154112050f feat: Implement Minecraft-style execute command with relative positioning (#1864)
* Initial plan

* Implement Minecraft-style execute command

Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com>

* Add relative positioning support to execute command using ~ syntax

Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com>

* update the parsing and fix chat response

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com>
Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
2025-09-08 22:35:18 -07:00
David Markowitz
6d3bf2fdc3 fix: need to create account twice due to commit latency?? (#1873)
idk fixes the issue
2025-09-08 22:50:22 -05:00
David Markowitz
566a18df38 Show git download progress with FetchContent (#1869)
Some downloads are slower and showing progress is better than sitting there doing nothing
2025-09-07 20:03:00 -05:00
David Markowitz
f6c13d9ee6 Replace Quaternion with glm math (#1868) 2025-09-06 19:18:03 -07:00
David Markowitz
8198ad70f6 fix: zero out component in destructor (#1863) 2025-09-01 19:06:00 -05:00
Gie "Max" Vanommeslaeghe
4c3bace601 Merge pull request #1862 from DarkflameUniverse/fix-item-exploits
fix: item exploits
2025-09-01 22:33:07 +02:00
David Markowitz
6d2a21450b fix item exploits
Update VendorComponent.cpp

Update Mail.cpp
2025-09-01 13:17:44 -07:00
David Markowitz
f9e74e6994 Add more logging around rewarding items (#1861) 2025-08-31 20:33:16 -07:00
jadebenn
21a2ddcfd9 Merge pull request #1856 from DarkflameUniverse/revert-uint8_t
Revert uint8_t in game message tests
2025-08-21 08:57:35 -05:00
jadebenn
50e6cf9059 revert ServiceType test change 2025-08-21 08:00:20 -05:00
jadebenn
3364884126 Consolidate serviceID enums into one enum (#1855)
* merge ServerType and ServiceID enums

* rename eConnectionType to ServiceType in preparation for enum unification

* unify ServiceID and ServiceType enums

* shrink ServiceType to an 8-bit integer

* fix linux compilation error and update gamemsg test

* return to uint16_t

* Update dNet/AuthPackets.cpp

Use cast instead of padding

Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>

* Add default case to MasterServer.cpp

* move ref back to type

* Another formatting fix

* Fix comment to be more accurate

---------

Co-authored-by: jadebenn <9892985+jadebenn@users.noreply.github.com>
Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>
2025-08-20 20:26:48 -07:00
David Markowitz
3890c0a86c fix: clang warnings (#1854) 2025-08-01 13:28:09 -07:00
David Markowitz
c083f21e44 feat: OnAttack behavior (#1853)
Adds the `OnAttack` property behavior starting node.
Tested that having the node allows the model to be attacked to trigger the start of behaviors
2025-08-01 03:09:16 -05:00
HailStorm32
c9e95839ee Update deprecated MYSQL command (#1852) 2025-07-29 09:59:32 -05:00
Terrev
dd957ed0c7 crux prime ninjago ruins ATM (#1851)
i forgor to do this apparently
2025-07-26 20:58:49 -07:00
David Markowitz
12296ce553 feat: activity component debug stuff and fix issues with duplicates in debug ui (#1850)
Tested that duplicate data in ui is no longer hidden and that activity debug stuff is shown
2025-07-24 06:26:51 -05:00
David Markowitz
24f4c9d413 feat: Destroyable component debug info (#1849)
tested that the ui now shows server and client info together if configured to do so
2025-07-23 04:08:39 -05:00
David Markowitz
ba964932b7 feat: debug for all physics components and fix inspect by ldf key (#1848) 2025-07-20 00:08:18 -05:00
David Markowitz
4c42eea819 feat: add despawn command (#1847) 2025-07-19 18:25:14 -05:00
David Markowitz
6b52cf67a0 feat: debug features and implement ObjectDebugger (#1846)
Move the -s and base features of inspect to the object debugger (this file is present in an unmodified, live client)
2025-07-19 05:11:32 -05:00
David Markowitz
71f708f1b5 fix: Let's not ghost zone control (#1845)
* Let's not ghost zone control

* remove zonecontrol stuff
2025-07-18 10:15:45 -07:00
David Markowitz
49aa632d42 feat: WaypointReached notification for MovementAI and don't move the AI when its not built (#1844) 2025-07-12 22:21:45 -07:00
David Markowitz
5ec4142ca1 fix: multiple collection tasks in one mission and remove sanity check on mission rewards (#1843) 2025-07-12 21:04:41 -05:00
David Markowitz
5e9fe40bec feat: Add GetComponents(Mut) functions to Entity (#1842)
Allows for a really neat way of getting components using structured binding.  Tested that powerups still function

do it again because its neat
2025-07-01 07:26:05 -05:00
David Markowitz
9524198044 Update DEVGMCommands.cpp (#1840) 2025-06-29 17:23:11 -04:00
David Markowitz
a5d0788488 feat: barfight (#1839) 2025-06-29 17:18:59 -04:00
David Markowitz
a1ba5b8f12 feat: remove instance pointer management by migrating to unique_ptr (#1838)
Tested that i can join clones, zones and private instances and that the expected zones are loaded into
2025-06-29 05:41:03 -04:00
219 changed files with 1990 additions and 1242 deletions

View File

@@ -19,6 +19,7 @@ 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_POLICY_DEFAULT_CMP0063 NEW) # Set CMAKE visibility policy to NEW on project and subprojects
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) # Set C and C++ symbol visibility to hide inlined functions set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) # Set C and C++ symbol visibility to hide inlined functions
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") 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 # Read variables from file
FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables) FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables)
@@ -306,7 +307,7 @@ add_subdirectory(dServer)
add_subdirectory(dWeb) add_subdirectory(dWeb)
# Create a list of common libraries shared between all binaries # Create a list of common libraries shared between all binaries
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "magic_enum") set(COMMON_LIBRARIES glm::glm "dCommon" "dDatabase" "dNet" "raknet" "magic_enum")
# Add platform specific common libraries # Add platform specific common libraries
if(UNIX) if(UNIX)

View File

@@ -187,7 +187,8 @@ Now that you are logged in, run the following commands.
```bash ```bash
# Creates a user for this computer which uses a password and grant said user all privileges. # Creates a user for this computer which uses a password and grant said user all privileges.
# Change mydarkflameuser to a custom username and password to a custom password. # Change mydarkflameuser to a custom username and password to a custom password.
GRANT ALL ON *.* TO 'mydarkflameuser'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; CREATE USER 'mydarkflameuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON *.* TO 'mydarkflameuser'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
# Then create a database for Darkflame Universe to use. # Then create a database for Darkflame Universe to use.

View File

@@ -6,6 +6,8 @@ FetchContent_Declare(
googletest googletest
GIT_REPOSITORY https://github.com/google/googletest.git GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1 GIT_TAG release-1.12.1
GIT_PROGRESS TRUE
GIT_SHALLOW 1
) )
# For Windows: Prevent overriding the parent project's compiler/linker settings # For Windows: Prevent overriding the parent project's compiler/linker settings

View File

@@ -20,7 +20,7 @@
//Auth includes: //Auth includes:
#include "AuthPackets.h" #include "AuthPackets.h"
#include "eConnectionType.h" #include "ServiceType.h"
#include "MessageType/Server.h" #include "MessageType/Server.h"
#include "MessageType/Auth.h" #include "MessageType/Auth.h"
@@ -52,6 +52,7 @@ int main(int argc, char** argv) {
//Create all the objects we need to run our service: //Create all the objects we need to run our service:
Server::SetupLogger("AuthServer"); Server::SetupLogger("AuthServer");
if (!Game::logger) return EXIT_FAILURE; if (!Game::logger) return EXIT_FAILURE;
Game::config->LogSettings();
LOG("Starting Auth server..."); LOG("Starting Auth server...");
LOG("Version: %s", PROJECT_VERSION); LOG("Version: %s", PROJECT_VERSION);
@@ -92,7 +93,7 @@ int main(int argc, char** argv) {
const auto externalIPString = Game::config->GetValue("external_ip"); const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString; if (!externalIPString.empty()) ourIP = externalIPString;
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal, masterPassword); Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServiceType::AUTH, Game::config, &Game::lastSignal, masterPassword);
//Run it until server gets a kill message from Master: //Run it until server gets a kill message from Master:
auto t = std::chrono::high_resolution_clock::now(); auto t = std::chrono::high_resolution_clock::now();
@@ -167,11 +168,11 @@ void HandlePacket(Packet* packet) {
if (packet->length < 4) return; if (packet->length < 4) return;
if (packet->data[0] == ID_USER_PACKET_ENUM) { if (packet->data[0] == ID_USER_PACKET_ENUM) {
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::SERVER) { if (static_cast<ServiceType>(packet->data[1]) == ServiceType::COMMON) {
if (static_cast<MessageType::Server>(packet->data[3]) == MessageType::Server::VERSION_CONFIRM) { if (static_cast<MessageType::Server>(packet->data[3]) == MessageType::Server::VERSION_CONFIRM) {
AuthPackets::HandleHandshake(Game::server, packet); AuthPackets::HandleHandshake(Game::server, packet);
} }
} else if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::AUTH) { } else if (static_cast<ServiceType>(packet->data[1]) == ServiceType::AUTH) {
if (static_cast<MessageType::Auth>(packet->data[3]) == MessageType::Auth::LOGIN_REQUEST) { if (static_cast<MessageType::Auth>(packet->data[3]) == MessageType::Auth::LOGIN_REQUEST) {
AuthPackets::HandleLoginRequest(Game::server, packet); AuthPackets::HandleLoginRequest(Game::server, packet);
} }

View File

@@ -1,4 +1,4 @@
set(DCHATFILTER_SOURCES "dChatFilter.cpp") set(DCHATFILTER_SOURCES "dChatFilter.cpp")
add_library(dChatFilter STATIC ${DCHATFILTER_SOURCES}) add_library(dChatFilter STATIC ${DCHATFILTER_SOURCES})
target_link_libraries(dChatFilter dDatabase) target_link_libraries(dChatFilter dDatabase glm::glm)

View File

@@ -14,6 +14,6 @@ add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}
add_library(dChatServer ${DCHATSERVER_SOURCES}) add_library(dChatServer ${DCHATSERVER_SOURCES})
target_include_directories(dChatServer PRIVATE "${PROJECT_SOURCE_DIR}/dServer" "${PROJECT_SOURCE_DIR}/dChatFilter") target_include_directories(dChatServer PRIVATE "${PROJECT_SOURCE_DIR}/dServer" "${PROJECT_SOURCE_DIR}/dChatFilter")
target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter) target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter glm::glm)
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer mongoose dWeb) target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer mongoose dWeb)

View File

@@ -13,11 +13,11 @@
// The only thing not auto-handled is instance activities force joining the team on the server. // The only thing not auto-handled is instance activities force joining the team on the server.
void WriteOutgoingReplyHeader(RakNet::BitStream& bitStream, const LWOOBJID& receivingPlayer, const MessageType::Client type) { void WriteOutgoingReplyHeader(RakNet::BitStream& bitStream, const LWOOBJID& receivingPlayer, const MessageType::Client type) {
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receivingPlayer); bitStream.Write(receivingPlayer);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, type); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, type);
} }
void ChatIgnoreList::GetIgnoreList(Packet* packet) { void ChatIgnoreList::GetIgnoreList(Packet* packet) {
@@ -34,7 +34,7 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
if (!receiver.ignoredPlayers.empty()) { if (!receiver.ignoredPlayers.empty()) {
LOG_DEBUG("Player %llu already has an ignore list, but is requesting it again.", playerId); LOG_DEBUG("Player %llu already has an ignore list, but is requesting it again.", playerId);
} else { } else {
auto ignoreList = Database::Get()->GetIgnoreList(static_cast<uint32_t>(playerId)); auto ignoreList = Database::Get()->GetIgnoreList(playerId);
if (ignoreList.empty()) { if (ignoreList.empty()) {
LOG_DEBUG("Player %llu has no ignores", playerId); LOG_DEBUG("Player %llu has no ignores", playerId);
return; return;
@@ -43,7 +43,6 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
for (auto& ignoredPlayer : ignoreList) { for (auto& ignoredPlayer : ignoreList) {
receiver.ignoredPlayers.emplace_back(ignoredPlayer.name, ignoredPlayer.id); receiver.ignoredPlayers.emplace_back(ignoredPlayer.name, ignoredPlayer.id);
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::CHARACTER); GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::CHARACTER);
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::PERSISTENT);
} }
} }
@@ -114,9 +113,8 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
} }
if (ignoredPlayerId != LWOOBJID_EMPTY) { if (ignoredPlayerId != LWOOBJID_EMPTY) {
Database::Get()->AddIgnore(static_cast<uint32_t>(playerId), static_cast<uint32_t>(ignoredPlayerId)); Database::Get()->AddIgnore(playerId, ignoredPlayerId);
GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::CHARACTER); GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::CHARACTER);
GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::PERSISTENT);
receiver.ignoredPlayers.emplace_back(toIgnoreStr, ignoredPlayerId); receiver.ignoredPlayers.emplace_back(toIgnoreStr, ignoredPlayerId);
LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str()); LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str());
@@ -157,7 +155,7 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
return; return;
} }
Database::Get()->RemoveIgnore(static_cast<uint32_t>(playerId), static_cast<uint32_t>(toRemove->playerId)); Database::Get()->RemoveIgnore(playerId, toRemove->playerId);
receiver.ignoredPlayers.erase(toRemove, receiver.ignoredPlayers.end()); receiver.ignoredPlayers.erase(toRemove, receiver.ignoredPlayers.end());
CBITSTREAM; CBITSTREAM;

View File

@@ -12,7 +12,7 @@
#include "RakString.h" #include "RakString.h"
#include "dConfig.h" #include "dConfig.h"
#include "eObjectBits.h" #include "eObjectBits.h"
#include "eConnectionType.h" #include "ServiceType.h"
#include "MessageType/Chat.h" #include "MessageType/Chat.h"
#include "MessageType/Client.h" #include "MessageType/Client.h"
#include "MessageType/Game.h" #include "MessageType/Game.h"
@@ -35,7 +35,6 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
FriendData fd; FriendData fd;
fd.isFTP = false; // not a thing in DLU fd.isFTP = false; // not a thing in DLU
fd.friendID = friendData.friendID; fd.friendID = friendData.friendID;
GeneralUtils::SetBit(fd.friendID, eObjectBits::PERSISTENT);
GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER); GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER);
fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
@@ -61,11 +60,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
//Now, we need to send the friendlist to the server they came from: //Now, we need to send the friendlist to the server they came from:
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(playerID); bitStream.Write(playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::GET_FRIENDS_LIST_RESPONSE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::GET_FRIENDS_LIST_RESPONSE);
bitStream.Write<uint8_t>(0); bitStream.Write<uint8_t>(0);
bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it. bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it.
bitStream.Write<uint16_t>(player.friends.size()); bitStream.Write<uint16_t>(player.friends.size());
@@ -161,9 +160,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
// Set the bits // Set the bits
GeneralUtils::SetBit(queryPlayerID, eObjectBits::CHARACTER); GeneralUtils::SetBit(queryPlayerID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(queryPlayerID, eObjectBits::PERSISTENT);
GeneralUtils::SetBit(queryFriendID, eObjectBits::CHARACTER); 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 // 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 // their column in the database determines what bit gets set. When the value hits 3, they
@@ -318,7 +315,6 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
} }
// Convert friendID to LWOOBJID // Convert friendID to LWOOBJID
GeneralUtils::SetBit(friendID, eObjectBits::PERSISTENT);
GeneralUtils::SetBit(friendID, eObjectBits::CHARACTER); GeneralUtils::SetBit(friendID, eObjectBits::CHARACTER);
Database::Get()->RemoveFriend(playerID, friendID); Database::Get()->RemoveFriend(playerID, friendID);
@@ -375,10 +371,10 @@ void ChatPacketHandler::HandleWho(Packet* packet) {
bool online = player; bool online = player;
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor); bitStream.Write(request.requestor);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::WHO_RESPONSE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::WHO_RESPONSE);
bitStream.Write<uint8_t>(online); bitStream.Write<uint8_t>(online);
bitStream.Write(player.zoneID.GetMapID()); bitStream.Write(player.zoneID.GetMapID());
bitStream.Write(player.zoneID.GetInstanceID()); bitStream.Write(player.zoneID.GetInstanceID());
@@ -398,10 +394,10 @@ void ChatPacketHandler::HandleShowAll(Packet* packet) {
if (!sender) return; if (!sender) return;
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor); bitStream.Write(request.requestor);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::SHOW_ALL_RESPONSE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::SHOW_ALL_RESPONSE);
bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers); bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers);
bitStream.Write(Game::playerContainer.GetPlayerCount()); bitStream.Write(Game::playerContainer.GetPlayerCount());
bitStream.Write(Game::playerContainer.GetSimCount()); bitStream.Write(Game::playerContainer.GetSimCount());
@@ -533,7 +529,7 @@ void ChatPacketHandler::OnAchievementNotify(RakNet::BitStream& bitstream, const
LOG_DEBUG("Sending achievement notify to %s", notify.targetPlayerName.GetAsString().c_str()); LOG_DEBUG("Sending achievement notify to %s", notify.targetPlayerName.GetAsString().c_str());
RakNet::BitStream worldStream; RakNet::BitStream worldStream;
BitStreamUtils::WriteHeader(worldStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(worldStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
worldStream.Write(friendData.playerID); worldStream.Write(friendData.playerID);
notify.WriteHeader(worldStream); notify.WriteHeader(worldStream);
notify.Serialize(worldStream); notify.Serialize(worldStream);
@@ -544,10 +540,10 @@ void ChatPacketHandler::OnAchievementNotify(RakNet::BitStream& bitstream, const
void ChatPacketHandler::SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode) { void ChatPacketHandler::SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(routeTo.playerID); bitStream.Write(routeTo.playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::PRIVATE_CHAT_MESSAGE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::PRIVATE_CHAT_MESSAGE);
bitStream.Write(sender.playerID); bitStream.Write(sender.playerID);
bitStream.Write(channel); bitStream.Write(channel);
bitStream.Write<uint32_t>(0); // not used bitStream.Write<uint32_t>(0); // not used
@@ -579,11 +575,11 @@ void ChatPacketHandler::SendFriendUpdate(const PlayerData& friendData, const Pla
[bool] - is FTP*/ [bool] - is FTP*/
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(friendData.playerID); bitStream.Write(friendData.playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::UPDATE_FRIEND_NOTIFY); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::UPDATE_FRIEND_NOTIFY);
bitStream.Write<uint8_t>(notifyType); bitStream.Write<uint8_t>(notifyType);
std::string playerName = playerData.playerName.c_str(); std::string playerName = playerData.playerName.c_str();
@@ -616,11 +612,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
} }
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::ADD_FRIEND_REQUEST); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::ADD_FRIEND_REQUEST);
bitStream.Write(LUWString(sender.playerName)); bitStream.Write(LUWString(sender.playerName));
bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side. bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side.
@@ -630,11 +626,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const PlayerData& sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) { void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const PlayerData& sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
// Portion that will get routed: // Portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::ADD_FRIEND_RESPONSE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::ADD_FRIEND_RESPONSE);
bitStream.Write(responseCode); bitStream.Write(responseCode);
// For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver. // For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver.
bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender.worldServerSysAddr != UNASSIGNED_SYSTEM_ADDRESS); bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender.worldServerSysAddr != UNASSIGNED_SYSTEM_ADDRESS);
@@ -653,11 +649,11 @@ void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const Pla
void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) { void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::REMOVE_FRIEND_RESPONSE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::REMOVE_FRIEND_RESPONSE);
bitStream.Write<uint8_t>(isSuccessful); //isOnline bitStream.Write<uint8_t>(isSuccessful); //isOnline
bitStream.Write(LUWString(personToRemove)); bitStream.Write(LUWString(personToRemove));

View File

@@ -13,7 +13,7 @@
#include "Diagnostics.h" #include "Diagnostics.h"
#include "AssetManager.h" #include "AssetManager.h"
#include "BinaryPathFinder.h" #include "BinaryPathFinder.h"
#include "eConnectionType.h" #include "ServiceType.h"
#include "PlayerContainer.h" #include "PlayerContainer.h"
#include "ChatPacketHandler.h" #include "ChatPacketHandler.h"
#include "MessageType/Chat.h" #include "MessageType/Chat.h"
@@ -59,6 +59,7 @@ int main(int argc, char** argv) {
//Create all the objects we need to run our service: //Create all the objects we need to run our service:
Server::SetupLogger("ChatServer"); Server::SetupLogger("ChatServer");
if (!Game::logger) return EXIT_FAILURE; if (!Game::logger) return EXIT_FAILURE;
Game::config->LogSettings();
//Read our config: //Read our config:
@@ -123,7 +124,7 @@ int main(int argc, char** argv) {
const auto externalIPString = Game::config->GetValue("external_ip"); const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString; if (!externalIPString.empty()) ourIP = externalIPString;
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal, masterPassword); Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServiceType::CHAT, Game::config, &Game::lastSignal, masterPassword);
const bool dontGenerateDCF = GeneralUtils::TryParse<bool>(Game::config->GetValue("dont_generate_dcf")).value_or(false); const bool dontGenerateDCF = GeneralUtils::TryParse<bool>(Game::config->GetValue("dont_generate_dcf")).value_or(false);
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF);
@@ -218,11 +219,11 @@ void HandlePacket(Packet* packet) {
CINSTREAM; CINSTREAM;
inStream.SetReadOffset(BYTES_TO_BITS(1)); inStream.SetReadOffset(BYTES_TO_BITS(1));
eConnectionType connection; ServiceType connection;
MessageType::Chat chatMessageID;
inStream.Read(connection); inStream.Read(connection);
if (connection != eConnectionType::CHAT) return; if (connection != ServiceType::CHAT) return;
MessageType::Chat chatMessageID;
inStream.Read(chatMessageID); inStream.Read(chatMessageID);
// Our packing byte wasnt there? Probably a false packet // Our packing byte wasnt there? Probably a false packet

View File

@@ -8,7 +8,7 @@
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#include "Database.h" #include "Database.h"
#include "eConnectionType.h" #include "ServiceType.h"
#include "ChatPackets.h" #include "ChatPackets.h"
#include "dConfig.h" #include "dConfig.h"
#include "MessageType/Chat.h" #include "MessageType/Chat.h"
@@ -147,7 +147,7 @@ void PlayerContainer::MuteUpdate(Packet* packet) {
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) { void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_MUTE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_MUTE);
bitStream.Write(player); bitStream.Write(player);
bitStream.Write(time); bitStream.Write(time);

View File

@@ -264,11 +264,11 @@ void TeamContainer::HandleTeamStatusRequest(Packet* packet) {
void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) { void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::TEAM_INVITE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::TEAM_INVITE);
bitStream.Write(LUWString(sender.playerName.c_str())); bitStream.Write(LUWString(sender.playerName.c_str()));
bitStream.Write(sender.playerID); bitStream.Write(sender.playerID);
@@ -279,7 +279,7 @@ void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData&
void TeamContainer::SendTeamInviteConfirm(const PlayerData& receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) { void TeamContainer::SendTeamInviteConfirm(const PlayerData& receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
@@ -306,7 +306,7 @@ void TeamContainer::SendTeamInviteConfirm(const PlayerData& receiver, bool bLead
void TeamContainer::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) { void TeamContainer::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
@@ -331,7 +331,7 @@ void TeamContainer::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64Leade
void TeamContainer::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) { void TeamContainer::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
@@ -348,7 +348,7 @@ void TeamContainer::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64Pl
void TeamContainer::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) { void TeamContainer::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
@@ -377,7 +377,7 @@ void TeamContainer::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTr
void TeamContainer::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) { void TeamContainer::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
@@ -403,7 +403,7 @@ void TeamContainer::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisba
void TeamContainer::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) { void TeamContainer::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID); bitStream.Write(receiver.playerID);
//portion that will get routed: //portion that will get routed:
@@ -652,7 +652,7 @@ void TeamContainer::TeamStatusUpdate(TeamData* team) {
void TeamContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) { void TeamContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::TEAM_GET_STATUS); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::TEAM_GET_STATUS);
bitStream.Write(team->teamID); bitStream.Write(team->teamID);
bitStream.Write(deleteTeam); bitStream.Write(deleteTeam);

View File

@@ -54,6 +54,8 @@ elseif (WIN32)
zlib zlib
URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip
URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1 URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1
GIT_PROGRESS TRUE
GIT_SHALLOW 1
) )
# Disable warning about no project version. # Disable warning about no project version.
@@ -74,5 +76,6 @@ else ()
endif () endif ()
target_link_libraries(dCommon target_link_libraries(dCommon
PUBLIC glm::glm
PRIVATE ZLIB::ZLIB bcrypt tinyxml2 PRIVATE ZLIB::ZLIB bcrypt tinyxml2
INTERFACE dDatabase) INTERFACE dDatabase)

View File

@@ -20,6 +20,8 @@
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "Logger.h"
#include <glm/ext/vector_float3.hpp>
enum eInventoryType : uint32_t; enum eInventoryType : uint32_t;
enum class eObjectBits : size_t; enum class eObjectBits : size_t;
enum class eReplicaComponentType : uint32_t; enum class eReplicaComponentType : uint32_t;
@@ -244,7 +246,7 @@ namespace GeneralUtils {
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters * @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/ */
template <typename T> template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::string_view strX, const std::string_view strY, const std::string_view strZ) { [[nodiscard]] std::optional<T> TryParse(const std::string_view strX, const std::string_view strY, const std::string_view strZ) {
const auto x = TryParse<float>(strX); const auto x = TryParse<float>(strX);
if (!x) return std::nullopt; if (!x) return std::nullopt;
@@ -252,7 +254,7 @@ namespace GeneralUtils {
if (!y) return std::nullopt; if (!y) return std::nullopt;
const auto z = TryParse<float>(strZ); const auto z = TryParse<float>(strZ);
return z ? std::make_optional<NiPoint3>(x.value(), y.value(), z.value()) : std::nullopt; return z ? std::make_optional<T>(x.value(), y.value(), z.value()) : std::nullopt;
} }
/** /**
@@ -261,8 +263,8 @@ namespace GeneralUtils {
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters * @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/ */
template <typename T> template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::span<const std::string> str) { [[nodiscard]] std::optional<T> TryParse(const std::span<const std::string> str) {
return (str.size() == 3) ? TryParse<NiPoint3>(str[0], str[1], str[2]) : std::nullopt; return (str.size() == 3) ? TryParse<T>(str[0], str[1], str[2]) : std::nullopt;
} }
template <typename T> template <typename T>
@@ -300,6 +302,12 @@ namespace GeneralUtils {
return T(); return T();
} }
template<typename Container>
inline Container::value_type GetRandomElement(const Container& container) {
DluAssert(!container.empty());
return container[GenerateRandomNumber<typename Container::value_type>(0, container.size() - 1)];
}
/** /**
* Casts the value of an enum entry to its underlying type * Casts the value of an enum entry to its underlying type
* @param entry Enum entry to cast * @param entry Enum entry to cast

View File

@@ -6,10 +6,14 @@
\brief Defines a point in space in XYZ coordinates \brief Defines a point in space in XYZ coordinates
*/ */
class NiPoint3; class NiPoint3;
class NiQuaternion;
typedef NiPoint3 Vector3; //!< The Vector3 class is technically the NiPoint3 class, but typedef'd for clarity in some cases 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 //! A custom class the defines a point in space
class NiPoint3 { class NiPoint3 {
public: public:
@@ -21,6 +25,12 @@ public:
//! Initializer //! Initializer
constexpr NiPoint3() = default; constexpr NiPoint3() = default;
constexpr NiPoint3(const glm::vec3& vec) noexcept
: x{ vec.x }
, y{ vec.y }
, z{ vec.z } {
}
//! Initializer //! Initializer
/*! /*!
\param x The x coordinate \param x The x coordinate

View File

@@ -4,6 +4,7 @@
#endif #endif
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include <glm/ext/quaternion_float.hpp>
// MARK: Getters / Setters // MARK: Getters / Setters

View File

@@ -3,37 +3,18 @@
// C++ // C++
#include <cmath> #include <cmath>
#include <glm/gtx/quaternion.hpp>
// MARK: Member Functions // MARK: Member Functions
Vector3 NiQuaternion::GetEulerAngles() const { Vector3 QuatUtils::Euler(const NiQuaternion& quat) {
Vector3 angles; return glm::eulerAngles(quat);
// 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 // MARK: Helper Functions
//! Look from a specific point in space to another point in space (Y-locked) //! Look from a specific point in space to another point in space (Y-locked)
NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) { NiQuaternion QuatUtils::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
//To make sure we don't orient around the X/Z axis: //To make sure we don't orient around the X/Z axis:
NiPoint3 source = sourcePoint; NiPoint3 source = sourcePoint;
NiPoint3 dest = destPoint; NiPoint3 dest = destPoint;
@@ -51,11 +32,11 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
NiPoint3 vecB = vecA.CrossProduct(posZ); NiPoint3 vecB = vecA.CrossProduct(posZ);
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle; if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle); return glm::angleAxis(rotAngle, glm::vec3{vecA.x, vecA.y, vecA.z});
} }
//! Look from a specific point in space to another point in space //! Look from a specific point in space to another point in space
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) { NiQuaternion QuatUtils::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize(); NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
NiPoint3 posZ = NiPoint3Constant::UNIT_Z; NiPoint3 posZ = NiPoint3Constant::UNIT_Z;
@@ -67,37 +48,26 @@ NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiP
NiPoint3 vecB = vecA.CrossProduct(posZ); NiPoint3 vecB = vecA.CrossProduct(posZ);
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle; if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle); return glm::angleAxis(rotAngle, glm::vec3{vecA.x, vecA.y, vecA.z});
} }
//! Creates a Quaternion from a specific axis and angle relative to that axis //! Creates a Quaternion from a specific axis and angle relative to that axis
NiQuaternion NiQuaternion::CreateFromAxisAngle(const Vector3& axis, float angle) { NiQuaternion QuatUtils::AxisAngle(const Vector3& axis, float angle) {
float halfAngle = angle * 0.5f; return glm::angleAxis(angle, glm::vec3(axis.x, axis.y, axis.z));
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 NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles) { NiQuaternion QuatUtils::FromEuler(const NiPoint3& eulerAngles) {
// Abbreviations for the various angular functions return glm::quat(glm::vec3(eulerAngles.x, eulerAngles.y, eulerAngles.z));
float cy = cos(eulerAngles.z * 0.5); }
float sy = sin(eulerAngles.z * 0.5);
float cp = cos(eulerAngles.y * 0.5); Vector3 QuatUtils::Forward(const NiQuaternion& quat) {
float sp = sin(eulerAngles.y * 0.5); return quat * glm::vec3(0, 0, 1);
float cr = cos(eulerAngles.x * 0.5); }
float sr = sin(eulerAngles.x * 0.5);
Vector3 QuatUtils::Up(const NiQuaternion& quat) {
NiQuaternion q; return quat * glm::vec3(0, 1, 0);
q.w = cr * cp * cy + sr * sp * sy; }
q.x = sr * cp * cy - cr * sp * sy;
q.y = cr * sp * cy + sr * cp * sy; Vector3 QuatUtils::Right(const NiQuaternion& quat) {
q.z = cr * cp * sy - sr * sp * cy; return quat * glm::vec3(1, 0, 0);
return q;
} }

View File

@@ -1,158 +1,27 @@
#ifndef __NIQUATERNION_H__ #ifndef NIQUATERNION_H
#define __NIQUATERNION_H__ #define NIQUATERNION_H
// Custom Classes // Custom Classes
#include "NiPoint3.h" #include "NiPoint3.h"
/*! #define GLM_FORCE_QUAT_DATA_WXYZ
\file NiQuaternion.hpp
\brief Defines a quaternion in space in WXYZ coordinates
*/
class NiQuaternion; #include <glm/ext/quaternion_float.hpp>
typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version of NiQuaternion
//! A class that defines a rotation in space using Quaternion = glm::quat;
class NiQuaternion { using NiQuaternion = Quaternion;
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 {
//! The initializer constexpr NiQuaternion IDENTITY = glm::identity<NiQuaternion>();
constexpr NiQuaternion() = default; Vector3 Forward(const NiQuaternion& quat);
Vector3 Up(const NiQuaternion& quat);
//! The initializer Vector3 Right(const NiQuaternion& quat);
/*! NiQuaternion LookAt(const NiPoint3& from, const NiPoint3& to);
\param w The w coordinate NiQuaternion LookAtUnlocked(const NiPoint3& from, const NiPoint3& to);
\param x The x coordinate Vector3 Euler(const NiQuaternion& quat);
\param y The y coordinate NiQuaternion AxisAngle(const Vector3& axis, float angle);
\param z The z coordinate NiQuaternion FromEuler(const NiPoint3& eulerAngles);
*/ constexpr float PI_OVER_180 = glm::pi<float>() / 180.0f;
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);
}; };
// Static Variables #endif // !NIQUATERNION_H
namespace NiQuaternionConstant {
constexpr NiQuaternion IDENTITY(1, 0, 0, 0);
}
// Include constexpr and inline function definitions in a seperate file for readability
#include "NiQuaternion.inl"
#endif // !__NIQUATERNION_H__

View File

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

View File

@@ -24,7 +24,7 @@ struct LocalSpaceInfo {
struct PositionUpdate { struct PositionUpdate {
NiPoint3 position = NiPoint3Constant::ZERO; NiPoint3 position = NiPoint3Constant::ZERO;
NiQuaternion rotation = NiQuaternionConstant::IDENTITY; NiQuaternion rotation = QuatUtils::IDENTITY;
bool onGround = false; bool onGround = false;
bool onRail = false; bool onRail = false;
NiPoint3 velocity = NiPoint3Constant::ZERO; NiPoint3 velocity = NiPoint3Constant::ZERO;

View File

@@ -47,6 +47,8 @@ void dConfig::LoadConfig() {
void dConfig::ReloadConfig() { void dConfig::ReloadConfig() {
this->m_ConfigValues.clear(); this->m_ConfigValues.clear();
LoadConfig(); LoadConfig();
for (const auto& handler : m_ConfigHandlers) handler();
LogSettings();
} }
const std::string& dConfig::GetValue(std::string key) { const std::string& dConfig::GetValue(std::string key) {
@@ -58,6 +60,18 @@ const std::string& dConfig::GetValue(std::string key) {
return this->m_ConfigValues[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) { void dConfig::ProcessLine(const std::string& line) {
auto splitLoc = line.find('='); auto splitLoc = line.find('=');
auto key = line.substr(0, splitLoc); auto key = line.substr(0, splitLoc);

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <fstream> #include <fstream>
#include <functional>
#include <map> #include <map>
#include <string> #include <string>
@@ -29,10 +31,15 @@ public:
* Reloads the config file to reset values * Reloads the config file to reset values
*/ */
void ReloadConfig(); void ReloadConfig();
// Adds a function to be called when the config is (re)loaded
void AddConfigHandler(std::function<void()> handler);
void LogSettings() const;
private: private:
void ProcessLine(const std::string& line); void ProcessLine(const std::string& line);
private:
std::map<std::string, std::string> m_ConfigValues; std::map<std::string, std::string> m_ConfigValues;
std::vector<std::function<void()>> m_ConfigHandlers;
std::string m_ConfigFilePath; std::string m_ConfigFilePath;
}; };

View File

@@ -0,0 +1,14 @@
#ifndef __SERVICETYPE__H__
#define __SERVICETYPE__H__
enum class ServiceType : uint16_t {
COMMON = 0,
AUTH,
CHAT,
WORLD = 4,
CLIENT,
MASTER,
UNKNOWN
};
#endif //!__SERVICETYPE__H__

View File

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

View File

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

View File

@@ -15,7 +15,7 @@ target_include_directories(dDatabaseCDClient PUBLIC "."
"${PROJECT_SOURCE_DIR}/dCommon" "${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums" "${PROJECT_SOURCE_DIR}/dCommon/dEnums"
) )
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3) target_link_libraries(dDatabaseCDClient PRIVATE sqlite3 glm::glm)
if (${CDCLIENT_CACHE_ALL}) if (${CDCLIENT_CACHE_ALL})
add_compile_definitions(dDatabaseCDClient PRIVATE CDCLIENT_CACHE_ALL=${CDCLIENT_CACHE_ALL}) add_compile_definitions(dDatabaseCDClient PRIVATE CDCLIENT_CACHE_ALL=${CDCLIENT_CACHE_ALL})

View File

@@ -10,4 +10,5 @@ add_dependencies(dDatabase conncpp_dylib)
target_include_directories(dDatabase PUBLIC ".") target_include_directories(dDatabase PUBLIC ".")
target_link_libraries(dDatabase target_link_libraries(dDatabase
PUBLIC dDatabaseCDClient dDatabaseGame) PUBLIC dDatabaseCDClient dDatabaseGame
PRIVATE glm::glm)

View File

@@ -29,7 +29,7 @@ target_include_directories(dDatabaseGame PUBLIC "."
target_link_libraries(dDatabaseGame target_link_libraries(dDatabaseGame
INTERFACE dCommon INTERFACE dCommon
PRIVATE sqlite3 MariaDB::ConnCpp) PRIVATE sqlite3 MariaDB::ConnCpp glm::glm)
# Glob together all headers that need to be precompiled # Glob together all headers that need to be precompiled
file( file(

View File

@@ -48,7 +48,7 @@ public:
virtual void Commit() = 0; virtual void Commit() = 0;
virtual bool GetAutoCommit() = 0; virtual bool GetAutoCommit() = 0;
virtual void SetAutoCommit(bool value) = 0; virtual void SetAutoCommit(bool value) = 0;
virtual void DeleteCharacter(const uint32_t characterId) = 0; virtual void DeleteCharacter(const LWOOBJID characterId) = 0;
}; };
#endif //!__GAMEDATABASE__H__ #endif //!__GAMEDATABASE__H__

View File

@@ -14,6 +14,7 @@ public:
std::string bcryptPassword; std::string bcryptPassword;
uint32_t id{}; uint32_t id{};
uint32_t playKeyId{}; uint32_t playKeyId{};
uint64_t muteExpire{};
bool banned{}; bool banned{};
bool locked{}; bool locked{};
eGameMasterLevel maxGmLevel{}; eGameMasterLevel maxGmLevel{};

View File

@@ -14,7 +14,7 @@ enum class eActivityType : uint32_t {
class IActivityLog { class IActivityLog {
public: public:
// Update the activity log for the given account. // Update the activity log for the given account.
virtual void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) = 0; virtual void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) = 0;
}; };
#endif //!__IACTIVITYLOG__H__ #endif //!__IACTIVITYLOG__H__

View File

@@ -9,7 +9,7 @@ class IBehaviors {
public: public:
struct Info { struct Info {
LWOOBJID behaviorId{}; LWOOBJID behaviorId{};
uint32_t characterId{}; LWOOBJID characterId{};
std::string behaviorInfo; std::string behaviorInfo;
}; };

View File

@@ -11,7 +11,7 @@ public:
std::string clientVersion; std::string clientVersion;
std::string otherPlayer; std::string otherPlayer;
std::string selection; std::string selection;
uint32_t characterId{}; LWOOBJID characterId{};
}; };
// Add a new bug report to the database. // Add a new bug report to the database.

View File

@@ -14,7 +14,7 @@ public:
struct Info { struct Info {
std::string name; std::string name;
std::string pendingName; std::string pendingName;
uint32_t id{}; LWOOBJID id{};
uint32_t accountId{}; uint32_t accountId{};
bool needsRename{}; bool needsRename{};
LWOCLONEID cloneId{}; LWOCLONEID cloneId{};
@@ -25,25 +25,25 @@ public:
virtual std::vector<std::string> GetApprovedCharacterNames() = 0; virtual std::vector<std::string> GetApprovedCharacterNames() = 0;
// Get the character info for the given character id. // Get the character info for the given character id.
virtual std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) = 0; virtual std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) = 0;
// Get the character info for the given character name. // Get the character info for the given character name.
virtual std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view name) = 0; virtual std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view name) = 0;
// Get the character ids for the given account. // Get the character ids for the given account.
virtual std::vector<uint32_t> GetAccountCharacterIds(const uint32_t accountId) = 0; virtual std::vector<LWOOBJID> GetAccountCharacterIds(const LWOOBJID accountId) = 0;
// Insert a new character into the database. // Insert a new character into the database.
virtual void InsertNewCharacter(const ICharInfo::Info info) = 0; virtual void InsertNewCharacter(const ICharInfo::Info info) = 0;
// Set the name of the given character. // Set the name of the given character.
virtual void SetCharacterName(const uint32_t characterId, const std::string_view name) = 0; virtual void SetCharacterName(const LWOOBJID characterId, const std::string_view name) = 0;
// Set the pending name of the given character. // Set the pending name of the given character.
virtual void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) = 0; virtual void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) = 0;
// Updates the given character ids last login to be right now. // Updates the given character ids last login to be right now.
virtual void UpdateLastLoggedInCharacter(const uint32_t characterId) = 0; virtual void UpdateLastLoggedInCharacter(const LWOOBJID characterId) = 0;
virtual bool IsNameInUse(const std::string_view name) = 0; virtual bool IsNameInUse(const std::string_view name) = 0;
}; };

View File

@@ -8,13 +8,13 @@
class ICharXml { class ICharXml {
public: public:
// Get the character xml for the given character id. // Get the character xml for the given character id.
virtual std::string GetCharacterXml(const uint32_t charId) = 0; virtual std::string GetCharacterXml(const LWOOBJID charId) = 0;
// Update the character xml for the given character id. // Update the character xml for the given character id.
virtual void UpdateCharacterXml(const uint32_t charId, const std::string_view lxfml) = 0; virtual void UpdateCharacterXml(const LWOOBJID charId, const std::string_view lxfml) = 0;
// Insert the character xml for the given character id. // Insert the character xml for the given character id.
virtual void InsertCharacterXml(const uint32_t characterId, const std::string_view lxfml) = 0; virtual void InsertCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) = 0;
}; };
#endif //!__ICHARXML__H__ #endif //!__ICHARXML__H__

View File

@@ -8,7 +8,7 @@ class ICommandLog {
public: public:
// Insert a new slash command log entry. // Insert a new slash command log entry.
virtual void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) = 0; virtual void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) = 0;
}; };
#endif //!__ICOMMANDLOG__H__ #endif //!__ICOMMANDLOG__H__

View File

@@ -8,25 +8,25 @@
class IFriends { class IFriends {
public: public:
struct BestFriendStatus { struct BestFriendStatus {
uint32_t playerCharacterId{}; LWOOBJID playerCharacterId{};
uint32_t friendCharacterId{}; LWOOBJID friendCharacterId{};
uint32_t bestFriendStatus{}; uint32_t bestFriendStatus{};
}; };
// Get the friends list for the given character id. // Get the friends list for the given character id.
virtual std::vector<FriendData> GetFriendsList(const uint32_t charId) = 0; virtual std::vector<FriendData> GetFriendsList(const LWOOBJID charId) = 0;
// Get the best friend status for the given player and friend character ids. // Get the best friend status for the given player and friend character ids.
virtual std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) = 0; virtual std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) = 0;
// Set the best friend status for the given player and friend character ids. // Set the best friend status for the given player and friend character ids.
virtual void SetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId, const uint32_t bestFriendStatus) = 0; virtual void SetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId, const uint32_t bestFriendStatus) = 0;
// Add a friend to the given character id. // Add a friend to the given character id.
virtual void AddFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) = 0; virtual void AddFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) = 0;
// Remove a friend from the given character id. // Remove a friend from the given character id.
virtual void RemoveFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) = 0; virtual void RemoveFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) = 0;
}; };
#endif //!__IFRIENDS__H__ #endif //!__IFRIENDS__H__

View File

@@ -9,12 +9,12 @@ class IIgnoreList {
public: public:
struct Info { struct Info {
std::string name; std::string name;
uint32_t id; LWOOBJID id;
}; };
virtual std::vector<Info> GetIgnoreList(const uint32_t playerId) = 0; virtual std::vector<Info> GetIgnoreList(const LWOOBJID playerId) = 0;
virtual void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) = 0; virtual void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) = 0;
virtual void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) = 0; virtual void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) = 0;
}; };
#endif //!__IIGNORELIST__H__ #endif //!__IIGNORELIST__H__

View File

@@ -5,12 +5,13 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
#include "dCommonVars.h"
class ILeaderboard { class ILeaderboard {
public: public:
struct Entry { struct Entry {
uint32_t charId{}; LWOOBJID charId{};
uint32_t lastPlayedTimestamp{}; uint32_t lastPlayedTimestamp{};
float primaryScore{}; float primaryScore{};
float secondaryScore{}; float secondaryScore{};
@@ -36,12 +37,12 @@ public:
virtual std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) = 0; 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> GetNsLeaderboard(const uint32_t activityId) = 0;
virtual std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) = 0; virtual std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) = 0;
virtual std::optional<Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) = 0; virtual std::optional<Score> GetPlayerScore(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 SaveScore(const LWOOBJID 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 UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) = 0;
virtual void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) = 0; virtual void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) = 0;
virtual void IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) = 0; virtual void IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) = 0;
}; };
#endif //!__ILEADERBOARD__H__ #endif //!__ILEADERBOARD__H__

View File

@@ -16,13 +16,13 @@ public:
virtual void InsertNewMail(const MailInfo& mail) = 0; virtual void InsertNewMail(const MailInfo& mail) = 0;
// Get the mail for the given character id. // Get the mail for the given character id.
virtual std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) = 0; virtual std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) = 0;
// Get the mail for the given mail id. // Get the mail for the given mail id.
virtual std::optional<MailInfo> GetMail(const uint64_t mailId) = 0; virtual std::optional<MailInfo> GetMail(const uint64_t mailId) = 0;
// Get the number of unread mail for the given character id. // Get the number of unread mail for the given character id.
virtual uint32_t GetUnreadMailCount(const uint32_t characterId) = 0; virtual uint32_t GetUnreadMailCount(const LWOOBJID characterId) = 0;
// Mark the given mail as read. // Mark the given mail as read.
virtual void MarkMailRead(const uint64_t mailId) = 0; virtual void MarkMailRead(const uint64_t mailId) = 0;

View File

@@ -13,7 +13,7 @@ public:
std::string description; std::string description;
std::string rejectionReason; std::string rejectionReason;
LWOOBJID id{}; LWOOBJID id{};
uint32_t ownerId{}; LWOOBJID ownerId{};
LWOCLONEID cloneId{}; LWOCLONEID cloneId{};
int32_t privacyOption{}; int32_t privacyOption{};
uint32_t modApproved{}; uint32_t modApproved{};
@@ -27,7 +27,7 @@ public:
uint32_t mapId{}; uint32_t mapId{};
std::string searchString; std::string searchString;
ePropertySortType sortChoice{}; ePropertySortType sortChoice{};
uint32_t playerId{}; LWOOBJID playerId{};
uint32_t numResults{}; uint32_t numResults{};
uint32_t startIndex{}; uint32_t startIndex{};
uint32_t playerSort{}; uint32_t playerSort{};

View File

@@ -13,7 +13,7 @@ public:
} }
NiPoint3 position; NiPoint3 position;
NiQuaternion rotation; NiQuaternion rotation = QuatUtils::IDENTITY;
LWOOBJID id{}; LWOOBJID id{};
LOT lot{}; LOT lot{};
uint32_t ugcId{}; uint32_t ugcId{};
@@ -25,7 +25,7 @@ public:
std::stringstream& sd0Data, std::stringstream& sd0Data,
const uint32_t blueprintId, const uint32_t blueprintId,
const uint32_t accountId, const uint32_t accountId,
const uint32_t characterId) = 0; const LWOOBJID characterId) = 0;
// Get the property models for the given property id. // Get the property models for the given property id.
virtual std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) = 0; virtual std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) = 0;

View File

@@ -7,7 +7,7 @@
class IUgcModularBuild { class IUgcModularBuild {
public: public:
virtual void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) = 0; virtual void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) = 0;
virtual void DeleteUgcBuild(const LWOOBJID bigId) = 0; virtual void DeleteUgcBuild(const LWOOBJID bigId) = 0;
}; };

View File

@@ -100,7 +100,7 @@ void MySQLDatabase::SetAutoCommit(bool value) {
con->setAutoCommit(value); con->setAutoCommit(value);
} }
void MySQLDatabase::DeleteCharacter(const uint32_t characterId) { void MySQLDatabase::DeleteCharacter(const LWOOBJID characterId) {
ExecuteDelete("DELETE FROM charxml WHERE id=? LIMIT 1;", characterId); ExecuteDelete("DELETE FROM charxml WHERE id=? LIMIT 1;", characterId);
ExecuteDelete("DELETE FROM command_log WHERE character_id=?;", characterId); ExecuteDelete("DELETE FROM command_log WHERE character_id=?;", characterId);
ExecuteDelete("DELETE FROM friends WHERE player_id=? OR friend_id=?;", characterId, characterId); ExecuteDelete("DELETE FROM friends WHERE player_id=? OR friend_id=?;", characterId, characterId);

View File

@@ -40,31 +40,31 @@ public:
std::vector<std::string> GetApprovedCharacterNames() override; std::vector<std::string> GetApprovedCharacterNames() override;
std::vector<FriendData> GetFriendsList(uint32_t charID) override; std::vector<FriendData> GetFriendsList(LWOOBJID charID) override;
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override; std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) override;
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override; void SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) override;
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override; void AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override; void RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override; void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) override;
void DeleteUgcModelData(const LWOOBJID& modelId) override; void DeleteUgcModelData(const LWOOBJID& modelId) override;
void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override; void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override;
std::vector<IUgc::Model> GetAllUgcModels() override; std::vector<IUgc::Model> GetAllUgcModels() override;
void CreateMigrationHistoryTable() override; void CreateMigrationHistoryTable() override;
bool IsMigrationRun(const std::string_view str) override; bool IsMigrationRun(const std::string_view str) override;
void InsertMigration(const std::string_view str) override; void InsertMigration(const std::string_view str) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override; std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override; std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
std::string GetCharacterXml(const uint32_t accountId) override; std::string GetCharacterXml(const LWOOBJID accountId) override;
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override; void UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) override;
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override; std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
void InsertNewCharacter(const ICharInfo::Info info) override; void InsertNewCharacter(const ICharInfo::Info info) override;
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override; void InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) override;
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override; std::vector<LWOOBJID> GetAccountCharacterIds(LWOOBJID accountId) override;
void DeleteCharacter(const uint32_t characterId) override; void DeleteCharacter(const LWOOBJID characterId) override;
void SetCharacterName(const uint32_t characterId, const std::string_view name) override; void SetCharacterName(const LWOOBJID characterId, const std::string_view name) override;
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override; void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) override;
void UpdateLastLoggedInCharacter(const uint32_t characterId) override; void UpdateLastLoggedInCharacter(const LWOOBJID characterId) override;
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override; void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override; std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override; std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
@@ -85,14 +85,14 @@ public:
std::stringstream& sd0Data, std::stringstream& sd0Data,
const uint32_t blueprintId, const uint32_t blueprintId,
const uint32_t accountId, const uint32_t accountId,
const uint32_t characterId) override; const LWOOBJID characterId) override;
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override; std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) override;
std::optional<MailInfo> GetMail(const uint64_t mailId) override; std::optional<MailInfo> GetMail(const uint64_t mailId) override;
uint32_t GetUnreadMailCount(const uint32_t characterId) override; uint32_t GetUnreadMailCount(const LWOOBJID characterId) override;
void MarkMailRead(const uint64_t mailId) override; void MarkMailRead(const uint64_t mailId) override;
void DeleteMail(const uint64_t mailId) override; void DeleteMail(const uint64_t mailId) override;
void ClaimMailItem(const uint64_t mailId) override; void ClaimMailItem(const uint64_t mailId) override;
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override; void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) override;
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override; void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
void UpdateAccountBan(const uint32_t accountId, const bool banned) override; void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override; void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
@@ -104,9 +104,9 @@ public:
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override; std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override; std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override; std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override; void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override; void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override; std::vector<IIgnoreList::Info> GetIgnoreList(const LWOOBJID playerId) override;
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) 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; std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
void AddBehavior(const IBehaviors::Info& info) override; void AddBehavior(const IBehaviors::Info& info) override;
@@ -118,12 +118,12 @@ public:
std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override; std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override;
std::vector<ILeaderboard::Entry> GetNsLeaderboard(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; std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override;
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override; void SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override;
void UpdateScore(const uint32_t 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 uint32_t playerId, const uint32_t gameId) override; std::optional<ILeaderboard::Score> GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) override;
void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override; void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) override;
void IncrementTimesPlayed(const uint32_t 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<uint32_t> characterId) override; void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) override;
void DeleteUgcBuild(const LWOOBJID bigId) override; void DeleteUgcBuild(const LWOOBJID bigId) override;
uint32_t GetAccountCount() override; uint32_t GetAccountCount() override;
bool IsNameInUse(const std::string_view name) override; bool IsNameInUse(const std::string_view name) override;
@@ -268,4 +268,15 @@ inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::opti
} }
} }
template<>
inline void SetParam(UniquePreppedStmtRef stmt, const int index, const std::optional<LWOOBJID> param) {
if (param) {
// LOG("%d", param.value());
stmt->setInt64(index, param.value());
} else {
// LOG("Null");
stmt->setNull(index, sql::DataType::SQLNULL);
}
}
#endif //!__MYSQLDATABASE__H__ #endif //!__MYSQLDATABASE__H__

View File

@@ -3,7 +3,7 @@
#include "eGameMasterLevel.h" #include "eGameMasterLevel.h"
std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_view username) { std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_view username) {
auto result = ExecuteSelect("SELECT id, password, banned, locked, play_key_id, gm_level FROM accounts WHERE name = ? LIMIT 1;", username); auto result = ExecuteSelect("SELECT id, password, banned, locked, play_key_id, gm_level, mute_expire FROM accounts WHERE name = ? LIMIT 1;", username);
if (!result->next()) { if (!result->next()) {
return std::nullopt; return std::nullopt;
@@ -16,6 +16,7 @@ std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_v
toReturn.banned = result->getBoolean("banned"); toReturn.banned = result->getBoolean("banned");
toReturn.locked = result->getBoolean("locked"); toReturn.locked = result->getBoolean("locked");
toReturn.playKeyId = result->getUInt("play_key_id"); toReturn.playKeyId = result->getUInt("play_key_id");
toReturn.muteExpire = result->getUInt64("mute_expire");
return toReturn; return toReturn;
} }

View File

@@ -1,6 +1,6 @@
#include "MySQLDatabase.h" #include "MySQLDatabase.h"
void MySQLDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) { void MySQLDatabase::UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) {
ExecuteInsert("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);", 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); characterId, static_cast<uint32_t>(activityType), static_cast<uint32_t>(time(NULL)), mapId);
} }

View File

@@ -19,7 +19,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(std::unique_ptr<sql::Resu
ICharInfo::Info toReturn; ICharInfo::Info toReturn;
toReturn.id = stmt->getUInt("id"); toReturn.id = stmt->getInt64("id");
toReturn.name = stmt->getString("name").c_str(); toReturn.name = stmt->getString("name").c_str();
toReturn.pendingName = stmt->getString("pending_name").c_str(); toReturn.pendingName = stmt->getString("pending_name").c_str();
toReturn.needsRename = stmt->getBoolean("needs_rename"); toReturn.needsRename = stmt->getBoolean("needs_rename");
@@ -30,7 +30,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(std::unique_ptr<sql::Resu
return toReturn; return toReturn;
} }
std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const uint32_t charId) { std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const LWOOBJID charId) {
return CharInfoFromQueryResult( return CharInfoFromQueryResult(
ExecuteSelect("SELECT name, pending_name, needs_rename, prop_clone_id, permission_map, id, account_id FROM charinfo WHERE id = ? LIMIT 1;", charId) 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<uint32_t> MySQLDatabase::GetAccountCharacterIds(const uint32_t accountId) { std::vector<LWOOBJID> MySQLDatabase::GetAccountCharacterIds(const LWOOBJID accountId) {
auto result = ExecuteSelect("SELECT id FROM charinfo WHERE account_id = ? ORDER BY last_login DESC LIMIT 4;", accountId); auto result = ExecuteSelect("SELECT id FROM charinfo WHERE account_id = ? ORDER BY last_login DESC LIMIT 4;", accountId);
std::vector<uint32_t> toReturn; std::vector<LWOOBJID> toReturn;
toReturn.reserve(result->rowsCount()); toReturn.reserve(result->rowsCount());
while (result->next()) { while (result->next()) {
toReturn.push_back(result->getUInt("id")); toReturn.push_back(result->getInt64("id"));
} }
return toReturn; return toReturn;
@@ -65,15 +65,15 @@ void MySQLDatabase::InsertNewCharacter(const ICharInfo::Info info) {
static_cast<uint32_t>(time(NULL))); static_cast<uint32_t>(time(NULL)));
} }
void MySQLDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) { void MySQLDatabase::SetCharacterName(const LWOOBJID 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); 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 uint32_t characterId, const std::string_view name) { void MySQLDatabase::SetPendingCharacterName(const LWOOBJID 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); 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 uint32_t characterId) { void MySQLDatabase::UpdateLastLoggedInCharacter(const LWOOBJID characterId) {
ExecuteUpdate("UPDATE charinfo SET last_login = ? WHERE id = ? LIMIT 1", static_cast<uint32_t>(time(NULL)), characterId); ExecuteUpdate("UPDATE charinfo SET last_login = ? WHERE id = ? LIMIT 1", static_cast<uint32_t>(time(NULL)), characterId);
} }

View File

@@ -1,6 +1,6 @@
#include "MySQLDatabase.h" #include "MySQLDatabase.h"
std::string MySQLDatabase::GetCharacterXml(const uint32_t charId) { std::string MySQLDatabase::GetCharacterXml(const LWOOBJID charId) {
auto result = ExecuteSelect("SELECT xml_data FROM charxml WHERE id = ? LIMIT 1;", charId); auto result = ExecuteSelect("SELECT xml_data FROM charxml WHERE id = ? LIMIT 1;", charId);
if (!result->next()) { if (!result->next()) {
@@ -10,10 +10,10 @@ std::string MySQLDatabase::GetCharacterXml(const uint32_t charId) {
return result->getString("xml_data").c_str(); return result->getString("xml_data").c_str();
} }
void MySQLDatabase::UpdateCharacterXml(const uint32_t charId, const std::string_view lxfml) { void MySQLDatabase::UpdateCharacterXml(const LWOOBJID charId, const std::string_view lxfml) {
ExecuteUpdate("UPDATE charxml SET xml_data = ? WHERE id = ?;", lxfml, charId); ExecuteUpdate("UPDATE charxml SET xml_data = ? WHERE id = ?;", lxfml, charId);
} }
void MySQLDatabase::InsertCharacterXml(const uint32_t characterId, const std::string_view lxfml) { void MySQLDatabase::InsertCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) {
ExecuteInsert("INSERT INTO `charxml` (`id`, `xml_data`) VALUES (?,?)", characterId, lxfml); ExecuteInsert("INSERT INTO `charxml` (`id`, `xml_data`) VALUES (?,?)", characterId, lxfml);
} }

View File

@@ -1,5 +1,5 @@
#include "MySQLDatabase.h" #include "MySQLDatabase.h"
void MySQLDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) { void MySQLDatabase::InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) {
ExecuteInsert("INSERT INTO command_log (character_id, command) VALUES (?, ?);", characterId, command); ExecuteInsert("INSERT INTO command_log (character_id, command) VALUES (?, ?);", characterId, command);
} }

View File

@@ -1,6 +1,6 @@
#include "MySQLDatabase.h" #include "MySQLDatabase.h"
std::vector<FriendData> MySQLDatabase::GetFriendsList(const uint32_t charId) { std::vector<FriendData> MySQLDatabase::GetFriendsList(const LWOOBJID charId) {
auto friendsList = ExecuteSelect( auto friendsList = ExecuteSelect(
R"QUERY( R"QUERY(
SELECT fr.requested_player AS player, best_friend AS bff, ci.name AS name FROM 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 uint32_t charId) {
while (friendsList->next()) { while (friendsList->next()) {
FriendData fd; FriendData fd;
fd.friendID = friendsList->getUInt("player"); fd.friendID = friendsList->getUInt64("player");
fd.isBestFriend = friendsList->getInt("bff") == 3; // 0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs 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(); fd.friendName = friendsList->getString("name").c_str();
@@ -29,7 +29,7 @@ std::vector<FriendData> MySQLDatabase::GetFriendsList(const uint32_t charId) {
return toReturn; return toReturn;
} }
std::optional<IFriends::BestFriendStatus> MySQLDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) { std::optional<IFriends::BestFriendStatus> MySQLDatabase::GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
auto result = ExecuteSelect("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;", auto result = ExecuteSelect("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
playerCharacterId, playerCharacterId,
friendCharacterId, friendCharacterId,
@@ -42,14 +42,14 @@ std::optional<IFriends::BestFriendStatus> MySQLDatabase::GetBestFriendStatus(con
} }
IFriends::BestFriendStatus toReturn; IFriends::BestFriendStatus toReturn;
toReturn.playerCharacterId = result->getUInt("player_id"); toReturn.playerCharacterId = result->getUInt64("player_id");
toReturn.friendCharacterId = result->getUInt("friend_id"); toReturn.friendCharacterId = result->getUInt64("friend_id");
toReturn.bestFriendStatus = result->getUInt("best_friend"); toReturn.bestFriendStatus = result->getUInt("best_friend");
return toReturn; return toReturn;
} }
void MySQLDatabase::SetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId, const uint32_t bestFriendStatus) { void MySQLDatabase::SetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID 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;", ExecuteUpdate("UPDATE friends SET best_friend = ? WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
bestFriendStatus, bestFriendStatus,
playerCharacterId, playerCharacterId,
@@ -59,11 +59,11 @@ void MySQLDatabase::SetBestFriendStatus(const uint32_t playerCharacterId, const
); );
} }
void MySQLDatabase::AddFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) { void MySQLDatabase::AddFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
ExecuteInsert("INSERT IGNORE INTO friends (player_id, friend_id, best_friend) VALUES (?, ?, 0);", playerCharacterId, friendCharacterId); ExecuteInsert("INSERT IGNORE INTO friends (player_id, friend_id, best_friend) VALUES (?, ?, 0);", playerCharacterId, friendCharacterId);
} }
void MySQLDatabase::RemoveFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) { void MySQLDatabase::RemoveFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
ExecuteDelete("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;", ExecuteDelete("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
playerCharacterId, playerCharacterId,
friendCharacterId, friendCharacterId,

View File

@@ -1,22 +1,22 @@
#include "MySQLDatabase.h" #include "MySQLDatabase.h"
std::vector<IIgnoreList::Info> MySQLDatabase::GetIgnoreList(const uint32_t playerId) { std::vector<IIgnoreList::Info> MySQLDatabase::GetIgnoreList(const LWOOBJID 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); 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; std::vector<IIgnoreList::Info> ignoreList;
ignoreList.reserve(result->rowsCount()); ignoreList.reserve(result->rowsCount());
while (result->next()) { while (result->next()) {
ignoreList.push_back(IIgnoreList::Info{ result->getString("name").c_str(), result->getUInt("ignore_id") }); ignoreList.push_back(IIgnoreList::Info{ result->getString("name").c_str(), result->getInt64("ignore_id") });
} }
return ignoreList; return ignoreList;
} }
void MySQLDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) { void MySQLDatabase::AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
ExecuteInsert("INSERT IGNORE INTO ignore_list (player_id, ignored_player_id) VALUES (?, ?)", playerId, ignoredPlayerId); ExecuteInsert("INSERT IGNORE INTO ignore_list (player_id, ignored_player_id) VALUES (?, ?)", playerId, ignoredPlayerId);
} }
void MySQLDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) { void MySQLDatabase::RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
ExecuteDelete("DELETE FROM ignore_list WHERE player_id = ? AND ignored_player_id = ?", playerId, ignoredPlayerId); ExecuteDelete("DELETE FROM ignore_list WHERE player_id = ? AND ignored_player_id = ?", playerId, ignoredPlayerId);
} }

View File

@@ -21,7 +21,7 @@ std::vector<ILeaderboard::Entry> ProcessQuery(UniqueResultSet& rows) {
while (rows->next()) { while (rows->next()) {
auto& entry = entries.emplace_back(); auto& entry = entries.emplace_back();
entry.charId = rows->getUInt("character_id"); entry.charId = rows->getUInt64("character_id");
entry.lastPlayedTimestamp = rows->getUInt("lp_unix"); entry.lastPlayedTimestamp = rows->getUInt("lp_unix");
entry.primaryScore = rows->getFloat("primaryScore"); entry.primaryScore = rows->getFloat("primaryScore");
entry.secondaryScore = rows->getFloat("secondaryScore"); entry.secondaryScore = rows->getFloat("secondaryScore");
@@ -58,21 +58,21 @@ std::vector<ILeaderboard::Entry> MySQLDatabase::GetNsLeaderboard(const uint32_t
return ProcessQuery(leaderboard); return ProcessQuery(leaderboard);
} }
void MySQLDatabase::SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) { void MySQLDatabase::SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) {
ExecuteInsert("INSERT leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, character_id = ?, game_id = ?;", ExecuteInsert("INSERT leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, character_id = ?, game_id = ?;",
score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId); score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
} }
void MySQLDatabase::UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) { void MySQLDatabase::UpdateScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) {
ExecuteInsert("UPDATE leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;", ExecuteInsert("UPDATE leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;",
score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId); score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
} }
void MySQLDatabase::IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) { void MySQLDatabase::IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) {
ExecuteUpdate("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId); ExecuteUpdate("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId);
} }
std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) { std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) {
std::optional<ILeaderboard::Score> toReturn = std::nullopt; std::optional<ILeaderboard::Score> toReturn = std::nullopt;
auto res = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId); auto res = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId);
if (res->next()) { if (res->next()) {
@@ -86,6 +86,6 @@ std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const uint32_t
return toReturn; return toReturn;
} }
void MySQLDatabase::IncrementNumWins(const uint32_t playerId, const uint32_t gameId) { void MySQLDatabase::IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) {
ExecuteUpdate("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId); ExecuteUpdate("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId);
} }

View File

@@ -19,7 +19,7 @@ void MySQLDatabase::InsertNewMail(const MailInfo& mail) {
mail.itemCount); mail.itemCount);
} }
std::vector<MailInfo> MySQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) { std::vector<MailInfo> MySQLDatabase::GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) {
auto res = ExecuteSelect( auto res = ExecuteSelect(
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent" "SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
" FROM mail WHERE receiver_id=? limit ?;", " FROM mail WHERE receiver_id=? limit ?;",
@@ -61,7 +61,7 @@ std::optional<MailInfo> MySQLDatabase::GetMail(const uint64_t mailId) {
return toReturn; return toReturn;
} }
uint32_t MySQLDatabase::GetUnreadMailCount(const uint32_t characterId) { uint32_t MySQLDatabase::GetUnreadMailCount(const LWOOBJID characterId) {
auto res = ExecuteSelect("SELECT COUNT(*) AS number_unread FROM mail WHERE receiver_id=? AND was_read=0;", characterId); auto res = ExecuteSelect("SELECT COUNT(*) AS number_unread FROM mail WHERE receiver_id=? AND was_read=0;", characterId);
if (!res->next()) { if (!res->next()) {

View File

@@ -119,7 +119,7 @@ std::optional<IProperty::PropertyEntranceResult> MySQLDatabase::GetProperties(co
if (!result) result = IProperty::PropertyEntranceResult(); if (!result) result = IProperty::PropertyEntranceResult();
auto& entry = result->entries.emplace_back(); auto& entry = result->entries.emplace_back();
entry.id = properties->getUInt64("id"); entry.id = properties->getUInt64("id");
entry.ownerId = properties->getUInt64("owner_id"); entry.ownerId = properties->getInt64("owner_id");
entry.cloneId = properties->getUInt64("clone_id"); entry.cloneId = properties->getUInt64("clone_id");
entry.name = properties->getString("name").c_str(); entry.name = properties->getString("name").c_str();
entry.description = properties->getString("description").c_str(); entry.description = properties->getString("description").c_str();
@@ -146,7 +146,7 @@ std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOMAPID map
IProperty::Info toReturn; IProperty::Info toReturn;
toReturn.id = propertyEntry->getUInt64("id"); toReturn.id = propertyEntry->getUInt64("id");
toReturn.ownerId = propertyEntry->getUInt64("owner_id"); toReturn.ownerId = propertyEntry->getInt64("owner_id");
toReturn.cloneId = propertyEntry->getUInt64("clone_id"); toReturn.cloneId = propertyEntry->getUInt64("clone_id");
toReturn.name = propertyEntry->getString("name").c_str(); toReturn.name = propertyEntry->getString("name").c_str();
toReturn.description = propertyEntry->getString("description").c_str(); toReturn.description = propertyEntry->getString("description").c_str();

View File

@@ -48,7 +48,7 @@ void MySQLDatabase::InsertNewUgcModel(
std:: stringstream& sd0Data, // cant be const sad std:: stringstream& sd0Data, // cant be const sad
const uint32_t blueprintId, const uint32_t blueprintId,
const uint32_t accountId, const uint32_t accountId,
const uint32_t characterId) { const LWOOBJID characterId) {
const std::istream stream(sd0Data.rdbuf()); const std::istream stream(sd0Data.rdbuf());
ExecuteInsert( ExecuteInsert(
"INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?)", "INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?)",

View File

@@ -1,6 +1,6 @@
#include "MySQLDatabase.h" #include "MySQLDatabase.h"
void MySQLDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) { void MySQLDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) {
ExecuteInsert("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)", bigId, modules, characterId); ExecuteInsert("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)", bigId, modules, characterId);
} }

View File

@@ -67,7 +67,7 @@ void SQLiteDatabase::SetAutoCommit(bool value) {
} }
} }
void SQLiteDatabase::DeleteCharacter(const uint32_t characterId) { void SQLiteDatabase::DeleteCharacter(const LWOOBJID characterId) {
ExecuteDelete("DELETE FROM charxml WHERE id=?;", characterId); ExecuteDelete("DELETE FROM charxml WHERE id=?;", characterId);
ExecuteDelete("DELETE FROM command_log WHERE character_id=?;", characterId); ExecuteDelete("DELETE FROM command_log WHERE character_id=?;", characterId);
ExecuteDelete("DELETE FROM friends WHERE player_id=? OR friend_id=?;", characterId, characterId); ExecuteDelete("DELETE FROM friends WHERE player_id=? OR friend_id=?;", characterId, characterId);

View File

@@ -38,31 +38,31 @@ public:
std::vector<std::string> GetApprovedCharacterNames() override; std::vector<std::string> GetApprovedCharacterNames() override;
std::vector<FriendData> GetFriendsList(uint32_t charID) override; std::vector<FriendData> GetFriendsList(LWOOBJID charID) override;
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override; std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) override;
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override; void SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) override;
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override; void AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override; void RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override; void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) override;
void DeleteUgcModelData(const LWOOBJID& modelId) override; void DeleteUgcModelData(const LWOOBJID& modelId) override;
void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override; void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override;
std::vector<IUgc::Model> GetAllUgcModels() override; std::vector<IUgc::Model> GetAllUgcModels() override;
void CreateMigrationHistoryTable() override; void CreateMigrationHistoryTable() override;
bool IsMigrationRun(const std::string_view str) override; bool IsMigrationRun(const std::string_view str) override;
void InsertMigration(const std::string_view str) override; void InsertMigration(const std::string_view str) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override; std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override; std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
std::string GetCharacterXml(const uint32_t accountId) override; std::string GetCharacterXml(const LWOOBJID accountId) override;
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override; void UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) override;
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override; std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
void InsertNewCharacter(const ICharInfo::Info info) override; void InsertNewCharacter(const ICharInfo::Info info) override;
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override; void InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) override;
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override; std::vector<LWOOBJID> GetAccountCharacterIds(LWOOBJID accountId) override;
void DeleteCharacter(const uint32_t characterId) override; void DeleteCharacter(const LWOOBJID characterId) override;
void SetCharacterName(const uint32_t characterId, const std::string_view name) override; void SetCharacterName(const LWOOBJID characterId, const std::string_view name) override;
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override; void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) override;
void UpdateLastLoggedInCharacter(const uint32_t characterId) override; void UpdateLastLoggedInCharacter(const LWOOBJID characterId) override;
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override; void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override; std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override; std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
@@ -83,14 +83,14 @@ public:
std::stringstream& sd0Data, std::stringstream& sd0Data,
const uint32_t blueprintId, const uint32_t blueprintId,
const uint32_t accountId, const uint32_t accountId,
const uint32_t characterId) override; const LWOOBJID characterId) override;
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override; std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) override;
std::optional<MailInfo> GetMail(const uint64_t mailId) override; std::optional<MailInfo> GetMail(const uint64_t mailId) override;
uint32_t GetUnreadMailCount(const uint32_t characterId) override; uint32_t GetUnreadMailCount(const LWOOBJID characterId) override;
void MarkMailRead(const uint64_t mailId) override; void MarkMailRead(const uint64_t mailId) override;
void DeleteMail(const uint64_t mailId) override; void DeleteMail(const uint64_t mailId) override;
void ClaimMailItem(const uint64_t mailId) override; void ClaimMailItem(const uint64_t mailId) override;
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override; void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) override;
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override; void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
void UpdateAccountBan(const uint32_t accountId, const bool banned) override; void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override; void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
@@ -102,9 +102,9 @@ public:
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override; std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override; std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override; std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override; void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override; void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override; std::vector<IIgnoreList::Info> GetIgnoreList(const LWOOBJID playerId) override;
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) 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; std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
void AddBehavior(const IBehaviors::Info& info) override; void AddBehavior(const IBehaviors::Info& info) override;
@@ -116,12 +116,12 @@ public:
std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override; std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override;
std::vector<ILeaderboard::Entry> GetNsLeaderboard(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; std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override;
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override; void SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override;
void UpdateScore(const uint32_t 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 uint32_t playerId, const uint32_t gameId) override; std::optional<ILeaderboard::Score> GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) override;
void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override; void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) override;
void IncrementTimesPlayed(const uint32_t 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<uint32_t> characterId) override; void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) override;
void DeleteUgcBuild(const LWOOBJID bigId) override; void DeleteUgcBuild(const LWOOBJID bigId) override;
uint32_t GetAccountCount() override; uint32_t GetAccountCount() override;
bool IsNameInUse(const std::string_view name) override; bool IsNameInUse(const std::string_view name) override;
@@ -270,4 +270,15 @@ 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 #endif //!SQLITEDATABASE_H

View File

@@ -17,6 +17,7 @@ std::optional<IAccounts::Info> SQLiteDatabase::GetAccountInfo(const std::string_
toReturn.banned = result.getIntField("banned"); toReturn.banned = result.getIntField("banned");
toReturn.locked = result.getIntField("locked"); toReturn.locked = result.getIntField("locked");
toReturn.playKeyId = result.getIntField("play_key_id"); toReturn.playKeyId = result.getIntField("play_key_id");
toReturn.muteExpire = static_cast<uint64_t>(result.getInt64Field("mute_expire"));
return toReturn; return toReturn;
} }

View File

@@ -1,6 +1,6 @@
#include "SQLiteDatabase.h" #include "SQLiteDatabase.h"
void SQLiteDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) { void SQLiteDatabase::UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) {
ExecuteInsert("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);", 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); characterId, static_cast<uint32_t>(activityType), static_cast<uint32_t>(time(NULL)), mapId);
} }

View File

@@ -20,7 +20,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(CppSQLite3Query stmt) {
ICharInfo::Info toReturn; ICharInfo::Info toReturn;
toReturn.id = stmt.getIntField("id"); toReturn.id = stmt.getInt64Field("id");
toReturn.name = stmt.getStringField("name"); toReturn.name = stmt.getStringField("name");
toReturn.pendingName = stmt.getStringField("pending_name"); toReturn.pendingName = stmt.getStringField("pending_name");
toReturn.needsRename = stmt.getIntField("needs_rename"); toReturn.needsRename = stmt.getIntField("needs_rename");
@@ -31,7 +31,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(CppSQLite3Query stmt) {
return toReturn; return toReturn;
} }
std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const uint32_t charId) { std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const LWOOBJID charId) {
return CharInfoFromQueryResult( 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 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<uint32_t> SQLiteDatabase::GetAccountCharacterIds(const uint32_t accountId) { std::vector<LWOOBJID> SQLiteDatabase::GetAccountCharacterIds(const LWOOBJID accountId) {
auto [_, result] = ExecuteSelect("SELECT id FROM charinfo WHERE account_id = ? ORDER BY last_login DESC LIMIT 4;", accountId); auto [_, result] = ExecuteSelect("SELECT id FROM charinfo WHERE account_id = ? ORDER BY last_login DESC LIMIT 4;", accountId);
std::vector<uint32_t> toReturn; std::vector<LWOOBJID> toReturn;
while (!result.eof()) { while (!result.eof()) {
toReturn.push_back(result.getIntField("id")); toReturn.push_back(result.getInt64Field("id"));
result.nextRow(); result.nextRow();
} }
@@ -66,15 +66,15 @@ void SQLiteDatabase::InsertNewCharacter(const ICharInfo::Info info) {
static_cast<uint32_t>(time(NULL))); static_cast<uint32_t>(time(NULL)));
} }
void SQLiteDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) { void SQLiteDatabase::SetCharacterName(const LWOOBJID 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); 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 uint32_t characterId, const std::string_view name) { void SQLiteDatabase::SetPendingCharacterName(const LWOOBJID 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); 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 uint32_t characterId) { void SQLiteDatabase::UpdateLastLoggedInCharacter(const LWOOBJID characterId) {
ExecuteUpdate("UPDATE charinfo SET last_login = ? WHERE id = ?;", static_cast<uint32_t>(time(NULL)), characterId); ExecuteUpdate("UPDATE charinfo SET last_login = ? WHERE id = ?;", static_cast<uint32_t>(time(NULL)), characterId);
} }

View File

@@ -1,6 +1,6 @@
#include "SQLiteDatabase.h" #include "SQLiteDatabase.h"
std::string SQLiteDatabase::GetCharacterXml(const uint32_t charId) { std::string SQLiteDatabase::GetCharacterXml(const LWOOBJID charId) {
auto [_, result] = ExecuteSelect("SELECT xml_data FROM charxml WHERE id = ? LIMIT 1;", charId); auto [_, result] = ExecuteSelect("SELECT xml_data FROM charxml WHERE id = ? LIMIT 1;", charId);
if (result.eof()) { if (result.eof()) {
@@ -10,10 +10,10 @@ std::string SQLiteDatabase::GetCharacterXml(const uint32_t charId) {
return result.getStringField("xml_data"); return result.getStringField("xml_data");
} }
void SQLiteDatabase::UpdateCharacterXml(const uint32_t charId, const std::string_view lxfml) { void SQLiteDatabase::UpdateCharacterXml(const LWOOBJID charId, const std::string_view lxfml) {
ExecuteUpdate("UPDATE charxml SET xml_data = ? WHERE id = ?;", lxfml, charId); ExecuteUpdate("UPDATE charxml SET xml_data = ? WHERE id = ?;", lxfml, charId);
} }
void SQLiteDatabase::InsertCharacterXml(const uint32_t characterId, const std::string_view lxfml) { void SQLiteDatabase::InsertCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) {
ExecuteInsert("INSERT INTO `charxml` (`id`, `xml_data`) VALUES (?,?)", characterId, lxfml); ExecuteInsert("INSERT INTO `charxml` (`id`, `xml_data`) VALUES (?,?)", characterId, lxfml);
} }

View File

@@ -1,5 +1,5 @@
#include "SQLiteDatabase.h" #include "SQLiteDatabase.h"
void SQLiteDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) { void SQLiteDatabase::InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) {
ExecuteInsert("INSERT INTO command_log (character_id, command) VALUES (?, ?);", characterId, command); ExecuteInsert("INSERT INTO command_log (character_id, command) VALUES (?, ?);", characterId, command);
} }

View File

@@ -1,6 +1,6 @@
#include "SQLiteDatabase.h" #include "SQLiteDatabase.h"
std::vector<FriendData> SQLiteDatabase::GetFriendsList(const uint32_t charId) { std::vector<FriendData> SQLiteDatabase::GetFriendsList(const LWOOBJID charId) {
auto [_, friendsList] = ExecuteSelect( auto [_, friendsList] = ExecuteSelect(
R"QUERY( R"QUERY(
SELECT fr.requested_player AS player, best_friend AS bff, ci.name AS name FROM 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 uint32_t charId) {
while (!friendsList.eof()) { while (!friendsList.eof()) {
FriendData fd; FriendData fd;
fd.friendID = friendsList.getIntField("player"); fd.friendID = friendsList.getInt64Field("player");
fd.isBestFriend = friendsList.getIntField("bff") == 3; // 0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs 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"); fd.friendName = friendsList.getStringField("name");
@@ -29,7 +29,7 @@ std::vector<FriendData> SQLiteDatabase::GetFriendsList(const uint32_t charId) {
return toReturn; return toReturn;
} }
std::optional<IFriends::BestFriendStatus> SQLiteDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) { std::optional<IFriends::BestFriendStatus> SQLiteDatabase::GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
auto [_, result] = ExecuteSelect("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;", auto [_, result] = ExecuteSelect("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;",
playerCharacterId, playerCharacterId,
friendCharacterId, friendCharacterId,
@@ -42,14 +42,14 @@ std::optional<IFriends::BestFriendStatus> SQLiteDatabase::GetBestFriendStatus(co
} }
IFriends::BestFriendStatus toReturn; IFriends::BestFriendStatus toReturn;
toReturn.playerCharacterId = result.getIntField("player_id"); toReturn.playerCharacterId = result.getInt64Field("player_id");
toReturn.friendCharacterId = result.getIntField("friend_id"); toReturn.friendCharacterId = result.getInt64Field("friend_id");
toReturn.bestFriendStatus = result.getIntField("best_friend"); toReturn.bestFriendStatus = result.getIntField("best_friend");
return toReturn; return toReturn;
} }
void SQLiteDatabase::SetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId, const uint32_t bestFriendStatus) { void SQLiteDatabase::SetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId, const uint32_t bestFriendStatus) {
ExecuteUpdate("UPDATE friends SET best_friend = ? WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?);", ExecuteUpdate("UPDATE friends SET best_friend = ? WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?);",
bestFriendStatus, bestFriendStatus,
playerCharacterId, playerCharacterId,
@@ -59,11 +59,11 @@ void SQLiteDatabase::SetBestFriendStatus(const uint32_t playerCharacterId, const
); );
} }
void SQLiteDatabase::AddFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) { void SQLiteDatabase::AddFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
ExecuteInsert("INSERT OR IGNORE INTO friends (player_id, friend_id, best_friend) VALUES (?, ?, 0);", playerCharacterId, friendCharacterId); ExecuteInsert("INSERT OR IGNORE INTO friends (player_id, friend_id, best_friend) VALUES (?, ?, 0);", playerCharacterId, friendCharacterId);
} }
void SQLiteDatabase::RemoveFriend(const uint32_t playerCharacterId, const uint32_t friendCharacterId) { void SQLiteDatabase::RemoveFriend(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
ExecuteDelete("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?);", ExecuteDelete("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?);",
playerCharacterId, playerCharacterId,
friendCharacterId, friendCharacterId,

View File

@@ -1,22 +1,22 @@
#include "SQLiteDatabase.h" #include "SQLiteDatabase.h"
std::vector<IIgnoreList::Info> SQLiteDatabase::GetIgnoreList(const uint32_t playerId) { std::vector<IIgnoreList::Info> SQLiteDatabase::GetIgnoreList(const LWOOBJID 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); 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; std::vector<IIgnoreList::Info> ignoreList;
while (!result.eof()) { while (!result.eof()) {
ignoreList.push_back(IIgnoreList::Info{ result.getStringField("name"), static_cast<uint32_t>(result.getIntField("ignore_id")) }); ignoreList.push_back(IIgnoreList::Info{ result.getStringField("name"), result.getInt64Field("ignore_id") });
result.nextRow(); result.nextRow();
} }
return ignoreList; return ignoreList;
} }
void SQLiteDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) { void SQLiteDatabase::AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
ExecuteInsert("INSERT OR IGNORE INTO ignore_list (player_id, ignored_player_id) VALUES (?, ?)", playerId, ignoredPlayerId); ExecuteInsert("INSERT OR IGNORE INTO ignore_list (player_id, ignored_player_id) VALUES (?, ?)", playerId, ignoredPlayerId);
} }
void SQLiteDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) { void SQLiteDatabase::RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
ExecuteDelete("DELETE FROM ignore_list WHERE player_id = ? AND ignored_player_id = ?", playerId, ignoredPlayerId); ExecuteDelete("DELETE FROM ignore_list WHERE player_id = ? AND ignored_player_id = ?", playerId, ignoredPlayerId);
} }

View File

@@ -20,7 +20,7 @@ std::vector<ILeaderboard::Entry> ProcessQuery(CppSQLite3Query& rows) {
while (!rows.eof()) { while (!rows.eof()) {
auto& entry = entries.emplace_back(); auto& entry = entries.emplace_back();
entry.charId = rows.getIntField("character_id"); entry.charId = rows.getInt64Field("character_id");
entry.lastPlayedTimestamp = rows.getIntField("lp_unix"); entry.lastPlayedTimestamp = rows.getIntField("lp_unix");
entry.primaryScore = rows.getFloatField("primaryScore"); entry.primaryScore = rows.getFloatField("primaryScore");
entry.secondaryScore = rows.getFloatField("secondaryScore"); entry.secondaryScore = rows.getFloatField("secondaryScore");
@@ -58,17 +58,17 @@ std::vector<ILeaderboard::Entry> SQLiteDatabase::GetNsLeaderboard(const uint32_t
return ProcessQuery(result); return ProcessQuery(result);
} }
void SQLiteDatabase::SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) { void SQLiteDatabase::SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) {
ExecuteInsert("INSERT INTO leaderboard (primaryScore, secondaryScore, tertiaryScore, character_id, game_id, last_played) VALUES (?,?,?,?,?,CURRENT_TIMESTAMP) ;", ExecuteInsert("INSERT INTO leaderboard (primaryScore, secondaryScore, tertiaryScore, character_id, game_id, last_played) VALUES (?,?,?,?,?,CURRENT_TIMESTAMP) ;",
score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId); score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
} }
void SQLiteDatabase::UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) { void SQLiteDatabase::UpdateScore(const LWOOBJID 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 = ?;", 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); score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId);
} }
std::optional<ILeaderboard::Score> SQLiteDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) { std::optional<ILeaderboard::Score> SQLiteDatabase::GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) {
std::optional<ILeaderboard::Score> toReturn = std::nullopt; std::optional<ILeaderboard::Score> toReturn = std::nullopt;
auto [_, res] = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId); auto [_, res] = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId);
if (!res.eof()) { if (!res.eof()) {
@@ -82,10 +82,10 @@ std::optional<ILeaderboard::Score> SQLiteDatabase::GetPlayerScore(const uint32_t
return toReturn; return toReturn;
} }
void SQLiteDatabase::IncrementNumWins(const uint32_t playerId, const uint32_t gameId) { void SQLiteDatabase::IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) {
ExecuteUpdate("UPDATE leaderboard SET numWins = numWins + 1, last_played = CURRENT_TIMESTAMP WHERE character_id = ? AND game_id = ?;", playerId, gameId); ExecuteUpdate("UPDATE leaderboard SET numWins = numWins + 1, last_played = CURRENT_TIMESTAMP WHERE character_id = ? AND game_id = ?;", playerId, gameId);
} }
void SQLiteDatabase::IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) { void SQLiteDatabase::IncrementTimesPlayed(const LWOOBJID playerId, const uint32_t gameId) {
ExecuteUpdate("UPDATE leaderboard SET timesPlayed = timesPlayed + 1, last_played = CURRENT_TIMESTAMP WHERE character_id = ? AND game_id = ?;", playerId, gameId); ExecuteUpdate("UPDATE leaderboard SET timesPlayed = timesPlayed + 1, last_played = CURRENT_TIMESTAMP WHERE character_id = ? AND game_id = ?;", playerId, gameId);
} }

View File

@@ -18,7 +18,7 @@ void SQLiteDatabase::InsertNewMail(const MailInfo& mail) {
mail.itemCount); mail.itemCount);
} }
std::vector<MailInfo> SQLiteDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) { std::vector<MailInfo> SQLiteDatabase::GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) {
auto [_, res] = ExecuteSelect( auto [_, res] = ExecuteSelect(
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent" "SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
" FROM mail WHERE receiver_id=? limit ?;", " FROM mail WHERE receiver_id=? limit ?;",
@@ -60,7 +60,7 @@ std::optional<MailInfo> SQLiteDatabase::GetMail(const uint64_t mailId) {
return toReturn; return toReturn;
} }
uint32_t SQLiteDatabase::GetUnreadMailCount(const uint32_t characterId) { uint32_t SQLiteDatabase::GetUnreadMailCount(const LWOOBJID characterId) {
auto [_, res] = ExecuteSelect("SELECT COUNT(*) AS number_unread FROM mail WHERE receiver_id=? AND was_read=0;", characterId); auto [_, res] = ExecuteSelect("SELECT COUNT(*) AS number_unread FROM mail WHERE receiver_id=? AND was_read=0;", characterId);
if (res.eof()) { if (res.eof()) {

View File

@@ -49,7 +49,7 @@ void SQLiteDatabase::InsertNewUgcModel(
std::stringstream& sd0Data, // cant be const sad std::stringstream& sd0Data, // cant be const sad
const uint32_t blueprintId, const uint32_t blueprintId,
const uint32_t accountId, const uint32_t accountId,
const uint32_t characterId) { const LWOOBJID characterId) {
const std::istream stream(sd0Data.rdbuf()); const std::istream stream(sd0Data.rdbuf());
ExecuteInsert( ExecuteInsert(
"INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?)", "INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?)",

View File

@@ -1,6 +1,6 @@
#include "SQLiteDatabase.h" #include "SQLiteDatabase.h"
void SQLiteDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) { void SQLiteDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) {
ExecuteInsert("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)", bigId, modules, characterId); ExecuteInsert("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)", bigId, modules, characterId);
} }

View File

@@ -32,27 +32,27 @@ std::vector<std::string> TestSQLDatabase::GetApprovedCharacterNames() {
return {}; return {};
} }
std::vector<FriendData> TestSQLDatabase::GetFriendsList(uint32_t charID) { std::vector<FriendData> TestSQLDatabase::GetFriendsList(LWOOBJID charID) {
return {}; return {};
} }
std::optional<IFriends::BestFriendStatus> TestSQLDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) { std::optional<IFriends::BestFriendStatus> TestSQLDatabase::GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) {
return {}; return {};
} }
void TestSQLDatabase::SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) { void TestSQLDatabase::SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) {
} }
void TestSQLDatabase::AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) { void TestSQLDatabase::AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) {
} }
void TestSQLDatabase::RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) { void TestSQLDatabase::RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) {
} }
void TestSQLDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) { void TestSQLDatabase::UpdateActivityLog(const LWOOBJID 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 uint32_t charId) { std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const LWOOBJID charId) {
return {}; return {};
} }
@@ -88,11 +88,11 @@ std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const std::stri
return {}; return {};
} }
std::string TestSQLDatabase::GetCharacterXml(const uint32_t accountId) { std::string TestSQLDatabase::GetCharacterXml(const LWOOBJID accountId) {
return {}; return {};
} }
void TestSQLDatabase::UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) { void TestSQLDatabase::UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) {
} }
@@ -104,27 +104,27 @@ void TestSQLDatabase::InsertNewCharacter(const ICharInfo::Info info) {
} }
void TestSQLDatabase::InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) { void TestSQLDatabase::InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) {
} }
std::vector<uint32_t> TestSQLDatabase::GetAccountCharacterIds(uint32_t accountId) { std::vector<LWOOBJID> TestSQLDatabase::GetAccountCharacterIds(LWOOBJID accountId) {
return {}; return {};
} }
void TestSQLDatabase::DeleteCharacter(const uint32_t characterId) { void TestSQLDatabase::DeleteCharacter(const LWOOBJID characterId) {
} }
void TestSQLDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) { void TestSQLDatabase::SetCharacterName(const LWOOBJID characterId, const std::string_view name) {
} }
void TestSQLDatabase::SetPendingCharacterName(const uint32_t characterId, const std::string_view name) { void TestSQLDatabase::SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) {
} }
void TestSQLDatabase::UpdateLastLoggedInCharacter(const uint32_t characterId) { void TestSQLDatabase::UpdateLastLoggedInCharacter(const LWOOBJID characterId) {
} }
@@ -192,11 +192,11 @@ void TestSQLDatabase::InsertNewMail(const MailInfo& mail) {
} }
void TestSQLDatabase::InsertNewUgcModel(std::stringstream& sd0Data, const uint32_t blueprintId, const uint32_t accountId, const uint32_t characterId) { void TestSQLDatabase::InsertNewUgcModel(std::stringstream& sd0Data, const uint32_t blueprintId, const uint32_t accountId, const LWOOBJID characterId) {
} }
std::vector<MailInfo> TestSQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) { std::vector<MailInfo> TestSQLDatabase::GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) {
return {}; return {};
} }
@@ -204,7 +204,7 @@ std::optional<MailInfo> TestSQLDatabase::GetMail(const uint64_t mailId) {
return {}; return {};
} }
uint32_t TestSQLDatabase::GetUnreadMailCount(const uint32_t characterId) { uint32_t TestSQLDatabase::GetUnreadMailCount(const LWOOBJID characterId) {
return {}; return {};
} }
@@ -220,7 +220,7 @@ void TestSQLDatabase::ClaimMailItem(const uint64_t mailId) {
} }
void TestSQLDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) { void TestSQLDatabase::InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) {
} }
@@ -268,15 +268,15 @@ std::vector<IUgc::Model> TestSQLDatabase::GetUgcModels(const LWOOBJID& propertyI
return {}; return {};
} }
void TestSQLDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) { void TestSQLDatabase::AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
} }
void TestSQLDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) { void TestSQLDatabase::RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) {
} }
std::vector<IIgnoreList::Info> TestSQLDatabase::GetIgnoreList(const uint32_t playerId) { std::vector<IIgnoreList::Info> TestSQLDatabase::GetIgnoreList(const LWOOBJID playerId) {
return {}; return {};
} }

View File

@@ -17,31 +17,31 @@ class TestSQLDatabase : public GameDatabase {
std::vector<std::string> GetApprovedCharacterNames() override; std::vector<std::string> GetApprovedCharacterNames() override;
std::vector<FriendData> GetFriendsList(uint32_t charID) override; std::vector<FriendData> GetFriendsList(LWOOBJID charID) override;
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override; std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const LWOOBJID playerCharacterId, const LWOOBJID friendCharacterId) override;
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override; void SetBestFriendStatus(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId, const uint32_t bestFriendStatus) override;
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override; void AddFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override; void RemoveFriend(const LWOOBJID playerAccountId, const LWOOBJID friendAccountId) override;
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override; void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) override;
void DeleteUgcModelData(const LWOOBJID& modelId) override; void DeleteUgcModelData(const LWOOBJID& modelId) override;
void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override; void UpdateUgcModelData(const LWOOBJID& modelId, std::stringstream& lxfml) override;
std::vector<IUgc::Model> GetAllUgcModels() override; std::vector<IUgc::Model> GetAllUgcModels() override;
void CreateMigrationHistoryTable() override; void CreateMigrationHistoryTable() override;
bool IsMigrationRun(const std::string_view str) override; bool IsMigrationRun(const std::string_view str) override;
void InsertMigration(const std::string_view str) override; void InsertMigration(const std::string_view str) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override; std::optional<ICharInfo::Info> GetCharacterInfo(const LWOOBJID charId) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override; std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
std::string GetCharacterXml(const uint32_t accountId) override; std::string GetCharacterXml(const LWOOBJID accountId) override;
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override; void UpdateCharacterXml(const LWOOBJID characterId, const std::string_view lxfml) override;
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override; std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
void InsertNewCharacter(const ICharInfo::Info info) override; void InsertNewCharacter(const ICharInfo::Info info) override;
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override; void InsertCharacterXml(const LWOOBJID accountId, const std::string_view lxfml) override;
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override; std::vector<LWOOBJID> GetAccountCharacterIds(LWOOBJID accountId) override;
void DeleteCharacter(const uint32_t characterId) override; void DeleteCharacter(const LWOOBJID characterId) override;
void SetCharacterName(const uint32_t characterId, const std::string_view name) override; void SetCharacterName(const LWOOBJID characterId, const std::string_view name) override;
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override; void SetPendingCharacterName(const LWOOBJID characterId, const std::string_view name) override;
void UpdateLastLoggedInCharacter(const uint32_t characterId) override; void UpdateLastLoggedInCharacter(const LWOOBJID characterId) override;
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override; void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override; std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override; std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
@@ -62,14 +62,14 @@ class TestSQLDatabase : public GameDatabase {
std::stringstream& sd0Data, std::stringstream& sd0Data,
const uint32_t blueprintId, const uint32_t blueprintId,
const uint32_t accountId, const uint32_t accountId,
const uint32_t characterId) override; const LWOOBJID characterId) override;
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override; std::vector<MailInfo> GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) override;
std::optional<MailInfo> GetMail(const uint64_t mailId) override; std::optional<MailInfo> GetMail(const uint64_t mailId) override;
uint32_t GetUnreadMailCount(const uint32_t characterId) override; uint32_t GetUnreadMailCount(const LWOOBJID characterId) override;
void MarkMailRead(const uint64_t mailId) override; void MarkMailRead(const uint64_t mailId) override;
void DeleteMail(const uint64_t mailId) override; void DeleteMail(const uint64_t mailId) override;
void ClaimMailItem(const uint64_t mailId) override; void ClaimMailItem(const uint64_t mailId) override;
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override; void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) override;
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override; void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
void UpdateAccountBan(const uint32_t accountId, const bool banned) override; void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override; void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
@@ -81,9 +81,9 @@ class TestSQLDatabase : public GameDatabase {
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override; std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override; std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override; std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override; void AddIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override; void RemoveIgnore(const LWOOBJID playerId, const LWOOBJID ignoredPlayerId) override;
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override; std::vector<IIgnoreList::Info> GetIgnoreList(const LWOOBJID playerId) override;
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) 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; std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
void AddBehavior(const IBehaviors::Info& info) override; void AddBehavior(const IBehaviors::Info& info) override;
@@ -95,12 +95,12 @@ class TestSQLDatabase : public GameDatabase {
std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override { return {}; }; 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> GetNsLeaderboard(const uint32_t activityId) override { return {}; };
std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override { return {}; }; std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override { return {}; };
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override {}; void SaveScore(const LWOOBJID playerId, const uint32_t gameId, const Score& score) override {};
void UpdateScore(const uint32_t 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 uint32_t playerId, const uint32_t gameId) override { return {}; }; std::optional<ILeaderboard::Score> GetPlayerScore(const LWOOBJID playerId, const uint32_t gameId) override { return {}; };
void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override {}; void IncrementNumWins(const LWOOBJID playerId, const uint32_t gameId) override {};
void IncrementTimesPlayed(const uint32_t 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<uint32_t> characterId) override {}; void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<LWOOBJID> characterId) override {};
void DeleteUgcBuild(const LWOOBJID bigId) override {}; void DeleteUgcBuild(const LWOOBJID bigId) override {};
uint32_t GetAccountCount() override { return 0; }; uint32_t GetAccountCount() override { return 0; };

View File

@@ -23,7 +23,7 @@
#include "ePlayerFlag.h" #include "ePlayerFlag.h"
#include "CDPlayerFlagsTable.h" #include "CDPlayerFlagsTable.h"
Character::Character(uint32_t id, User* parentUser) { Character::Character(LWOOBJID id, User* parentUser) {
//First load the name, etc: //First load the name, etc:
m_ID = id; m_ID = id;
m_ParentUser = parentUser; m_ParentUser = parentUser;
@@ -50,6 +50,10 @@ void Character::UpdateInfoFromDatabase() {
//Load the xmlData now: //Load the xmlData now:
m_XMLData = Database::Get()->GetCharacterXml(m_ID); 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_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. m_ZoneInstanceID = 0; //These values don't really matter, these are only used on the char select screen and seem unused.
@@ -61,7 +65,6 @@ void Character::UpdateInfoFromDatabase() {
//Set our objectID: //Set our objectID:
m_ObjectID = m_ID; m_ObjectID = m_ID;
GeneralUtils::SetBit(m_ObjectID, eObjectBits::CHARACTER); GeneralUtils::SetBit(m_ObjectID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(m_ObjectID, eObjectBits::PERSISTENT);
m_OurEntity = nullptr; m_OurEntity = nullptr;
m_BuildMode = false; m_BuildMode = false;
@@ -75,7 +78,7 @@ void Character::DoQuickXMLDataParse() {
if (m_XMLData.size() == 0) return; if (m_XMLData.size() == 0) return;
if (m_Doc.Parse(m_XMLData.c_str(), m_XMLData.size()) == 0) { if (m_Doc.Parse(m_XMLData.c_str(), m_XMLData.size()) == 0) {
LOG("Loaded xmlData for character %s (%i)!", m_Name.c_str(), m_ID); LOG("Loaded xmlData for character %s (%llu)!", m_Name.c_str(), m_ID);
} else { } else {
LOG("Failed to load xmlData (%i) (%s) (%s)!", m_Doc.ErrorID(), m_Doc.ErrorIDToName(m_Doc.ErrorID()), m_Doc.ErrorStr()); LOG("Failed to load xmlData (%i) (%s) (%s)!", m_Doc.ErrorID(), m_Doc.ErrorIDToName(m_Doc.ErrorID()), m_Doc.ErrorStr());
//Server::rakServer->CloseConnection(m_ParentUser->GetSystemAddress(), true); //Server::rakServer->CloseConnection(m_ParentUser->GetSystemAddress(), true);
@@ -238,7 +241,7 @@ void Character::SetBuildMode(bool buildMode) {
void Character::SaveXMLToDatabase() { void Character::SaveXMLToDatabase() {
// Check that we can actually _save_ before saving // Check that we can actually _save_ before saving
if (!m_OurEntity) { if (!m_OurEntity) {
LOG("%i:%s didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!", this->GetID(), this->GetName().c_str()); LOG("%llu:%s didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!", this->GetID(), this->GetName().c_str());
return; return;
} }
@@ -308,7 +311,7 @@ void Character::SaveXMLToDatabase() {
//For metrics, log the time it took to save: //For metrics, log the time it took to save:
auto end = std::chrono::system_clock::now(); auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = end - start; std::chrono::duration<double> elapsed = end - start;
LOG("%i:%s Saved character to Database in: %fs", this->GetID(), this->GetName().c_str(), elapsed.count()); LOG("%llu:%s Saved character to Database in: %fs", this->GetID(), this->GetName().c_str(), elapsed.count());
} }
void Character::SetIsNewLogin() { void Character::SetIsNewLogin() {
@@ -320,7 +323,7 @@ void Character::SetIsNewLogin() {
while (currentChild) { while (currentChild) {
auto* nextChild = currentChild->NextSiblingElement(); auto* nextChild = currentChild->NextSiblingElement();
if (currentChild->Attribute("si")) { if (currentChild->Attribute("si")) {
LOG("Removed session flag (%s) from character %i:%s, saving character to database", currentChild->Attribute("si"), GetID(), GetName().c_str()); LOG("Removed session flag (%s) from character %llu:%s, saving character to database", currentChild->Attribute("si"), GetID(), GetName().c_str());
flags->DeleteChild(currentChild); flags->DeleteChild(currentChild);
WriteToDatabase(); WriteToDatabase();
} }
@@ -496,7 +499,7 @@ void Character::OnZoneLoad() {
// Remove all GM items // Remove all GM items
for (const auto lot : Inventory::GetAllGMItems()) { for (const auto lot : Inventory::GetAllGMItems()) {
inventoryComponent->RemoveItem(lot, inventoryComponent->GetLotCount(lot)); inventoryComponent->RemoveItem(lot, inventoryComponent->GetLotCount(lot), eInventoryType::ALL);
} }
} }

View File

@@ -23,7 +23,7 @@ enum class eLootSourceType : uint32_t;
*/ */
class Character { class Character {
public: public:
Character(uint32_t id, User* parentUser); Character(LWOOBJID id, User* parentUser);
~Character(); ~Character();
/** /**
@@ -53,7 +53,7 @@ public:
* Gets the database ID of the character * Gets the database ID of the character
* @return the database ID of the character * @return the database ID of the character
*/ */
uint32_t GetID() const { return m_ID; } LWOOBJID GetID() const { return m_ID; }
/** /**
* Gets the (custom) name of the character * Gets the (custom) name of the character
@@ -467,9 +467,9 @@ public:
private: private:
void UpdateInfoFromDatabase(); void UpdateInfoFromDatabase();
/** /**
* The ID of this character. First 32 bits of the ObjectID. * The ID of this character.
*/ */
uint32_t m_ID{}; LWOOBJID m_ID{};
/** /**
* The 64-bit unique ID used in the game. * The 64-bit unique ID used in the game.
@@ -654,7 +654,7 @@ private:
/** /**
* The spawn rotation of this character when loading in * The spawn rotation of this character when loading in
*/ */
NiQuaternion m_OriginalRotation; NiQuaternion m_OriginalRotation = QuatUtils::IDENTITY;
/** /**
* The respawn points of this character, per world * The respawn points of this character, per world

View File

@@ -97,6 +97,8 @@
#include "CDSkillBehaviorTable.h" #include "CDSkillBehaviorTable.h"
#include "CDZoneTableTable.h" #include "CDZoneTableTable.h"
#include "StringifiedEnum.h"
#include <ranges> #include <ranges>
Observable<Entity*, const PositionUpdate&> Entity::OnPlayerPositionUpdate; Observable<Entity*, const PositionUpdate&> Entity::OnPlayerPositionUpdate;
@@ -173,8 +175,11 @@ Entity::~Entity() {
CancelAllTimers(); CancelAllTimers();
CancelCallbackTimers(); CancelCallbackTimers();
for (const auto& component : m_Components | std::views::values) { for (auto& component : m_Components | std::views::values) {
if (component) delete component; if (component) {
delete component;
component = nullptr;
}
} }
for (auto* const child : m_ChildEntities) { for (auto* const child : m_ChildEntities) {
@@ -187,6 +192,7 @@ Entity::~Entity() {
} }
void Entity::Initialize() { void Entity::Initialize() {
RegisterMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, this, &Entity::MsgRequestServerObjectInfo);
/** /**
* Setup trigger * Setup trigger
*/ */
@@ -298,7 +304,7 @@ void Entity::Initialize() {
//If we came from another zone, put us in the starting loc //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. if (m_Character->GetZoneID() != Game::server->GetZoneID() || mapID == 1603) { // Exception for Moon Base as you tend to spawn on the roof.
NiPoint3 pos; NiPoint3 pos;
NiQuaternion rot; NiQuaternion rot = QuatUtils::IDENTITY;
const auto& targetSceneName = m_Character->GetTargetScene(); const auto& targetSceneName = m_Character->GetTargetScene();
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName); auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
@@ -899,7 +905,7 @@ void Entity::SetGMLevel(eGameMasterLevel value) {
// Update the chat server of our GM Level // Update the chat server of our GM Level
{ {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GMLEVEL_UPDATE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GMLEVEL_UPDATE);
bitStream.Write(m_ObjectID); bitStream.Write(m_ObjectID);
bitStream.Write(m_GMLevel); bitStream.Write(m_GMLevel);
@@ -920,7 +926,7 @@ void Entity::WriteLDFData(const std::vector<LDFBaseData*>& ldf, RakNet::BitStrea
numberOfValidKeys--; numberOfValidKeys--;
} }
} }
// Now write it to the main bitstream // Now write it to the main bitstream
outBitStream.Write<uint32_t>(settingStream.GetNumberOfBytesUsed() + 1 + sizeof(uint32_t)); outBitStream.Write<uint32_t>(settingStream.GetNumberOfBytesUsed() + 1 + sizeof(uint32_t));
outBitStream.Write<uint8_t>(0); //no compression used outBitStream.Write<uint8_t>(0); //no compression used
@@ -1662,11 +1668,9 @@ void Entity::PickupItem(const LWOOBJID& objectID) const {
auto* const skillsTable = CDClientManager::GetTable<CDObjectSkillsTable>(); auto* const skillsTable = CDClientManager::GetTable<CDObjectSkillsTable>();
const auto skills = skillsTable->Query([&info](CDObjectSkills entry) {return (entry.objectTemplate == info.lot); }); const auto skills = skillsTable->Query([&info](CDObjectSkills entry) {return (entry.objectTemplate == info.lot); });
for (const auto& skill : skills) { for (const auto& skill : skills) {
auto* skillComponent = GetComponent<SkillComponent>(); const auto [skillComponent, missionComponent] = GetComponentsMut<SkillComponent, MissionComponent>();
if (skillComponent) skillComponent->CastSkill(skill.skillID, GetObjectID(), GetObjectID(), skill.castOnType, NiQuaternion(0, 0, 0, 0)); if (skillComponent) skillComponent->CastSkill(skill.skillID, GetObjectID(), GetObjectID(), skill.castOnType, NiQuaternion(0, 0, 0, 0));
auto* missionComponent = GetComponent<MissionComponent>();
if (missionComponent != nullptr) { if (missionComponent != nullptr) {
missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID); missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID);
} }
@@ -1878,7 +1882,7 @@ const NiQuaternion& Entity::GetRotation() const {
return rigidBodyPhantomPhysicsComponent->GetRotation(); return rigidBodyPhantomPhysicsComponent->GetRotation();
} }
return NiQuaternionConstant::IDENTITY; return QuatUtils::IDENTITY;
} }
void Entity::SetPosition(const NiPoint3& position) { void Entity::SetPosition(const NiPoint3& position) {
@@ -2174,7 +2178,7 @@ const NiPoint3& Entity::GetRespawnPosition() const {
const NiQuaternion& Entity::GetRespawnRotation() const { const NiQuaternion& Entity::GetRespawnRotation() const {
auto* characterComponent = GetComponent<CharacterComponent>(); auto* characterComponent = GetComponent<CharacterComponent>();
return characterComponent ? characterComponent->GetRespawnRotation() : NiQuaternionConstant::IDENTITY; return characterComponent ? characterComponent->GetRespawnRotation() : QuatUtils::IDENTITY;
} }
void Entity::SetRespawnPos(const NiPoint3& position) const { void Entity::SetRespawnPos(const NiPoint3& position) const {
@@ -2211,3 +2215,38 @@ bool Entity::HandleMsg(GameMessages::GameMsg& msg) const {
void Entity::RegisterMsg(const MessageType::Game msgId, std::function<bool(GameMessages::GameMsg&)> handler) { void Entity::RegisterMsg(const MessageType::Game msgId, std::function<bool(GameMessages::GameMsg&)> handler) {
m_MsgHandlers.emplace(msgId, handler); m_MsgHandlers.emplace(msgId, handler);
} }
bool Entity::MsgRequestServerObjectInfo(GameMessages::GameMsg& msg) {
auto& requestInfo = static_cast<GameMessages::RequestServerObjectInfo&>(msg);
AMFArrayValue response;
response.Insert("visible", true);
response.Insert("objectID", std::to_string(m_ObjectID));
response.Insert("serverInfo", true);
GameMessages::GetObjectReportInfo info{};
info.info = response.InsertArray("data");
auto& objectInfo = info.info->PushDebug("Object Details");
auto* table = CDClientManager::GetTable<CDObjectsTable>();
const auto& objTableInfo = table->GetByID(GetLOT());
objectInfo.PushDebug<AMFStringValue>("Name") = objTableInfo.name;
objectInfo.PushDebug<AMFIntValue>("Template ID(LOT)") = GetLOT();
objectInfo.PushDebug<AMFStringValue>("Object ID") = std::to_string(GetObjectID());
objectInfo.PushDebug<AMFStringValue>("Spawner's Object ID") = std::to_string(GetSpawnerID());
auto& componentDetails = objectInfo.PushDebug("Component Information");
for (const auto [id, component] : m_Components) {
componentDetails.PushDebug<AMFStringValue>(StringifiedEnum::ToString(id)) = "";
}
auto& configData = objectInfo.PushDebug("Config Data");
for (const auto config : m_Settings) {
configData.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(config->GetKey())) = config->GetValueAsString();
}
HandleMsg(info);
auto* client = Game::entityManager->GetEntity(requestInfo.clientId);
if (client) GameMessages::SendUIMessageServerToSingleClient("ToggleObjectDebugger", response, client->GetSystemAddress());
return true;
}

View File

@@ -2,6 +2,7 @@
#include <map> #include <map>
#include <functional> #include <functional>
#include <tuple>
#include <typeinfo> #include <typeinfo>
#include <type_traits> #include <type_traits>
#include <unordered_map> #include <unordered_map>
@@ -161,6 +162,12 @@ public:
template<typename T> template<typename T>
T* GetComponent() const; T* GetComponent() const;
template<typename... T>
auto GetComponents() const;
template<typename... T>
auto GetComponentsMut() const;
template<typename T> template<typename T>
bool TryGetComponent(eReplicaComponentType componentId, T*& component) const; bool TryGetComponent(eReplicaComponentType componentId, T*& component) const;
@@ -168,6 +175,8 @@ public:
void AddComponent(eReplicaComponentType componentId, Component* component); void AddComponent(eReplicaComponentType componentId, Component* component);
bool MsgRequestServerObjectInfo(GameMessages::GameMsg& msg);
// This is expceted to never return nullptr, an assert checks this. // This is expceted to never return nullptr, an assert checks this.
CppScripts::Script* const GetScript() const; CppScripts::Script* const GetScript() const;
@@ -329,6 +338,10 @@ public:
bool HandleMsg(GameMessages::GameMsg& msg) const; bool HandleMsg(GameMessages::GameMsg& msg) const;
void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1));
}
/** /**
* @brief The observable for player entity position updates. * @brief The observable for player entity position updates.
*/ */
@@ -344,7 +357,7 @@ private:
std::vector<LDFBaseData*> m_NetworkSettings; std::vector<LDFBaseData*> m_NetworkSettings;
NiPoint3 m_DefaultPosition; NiPoint3 m_DefaultPosition;
NiQuaternion m_DefaultRotation; NiQuaternion m_DefaultRotation = QuatUtils::IDENTITY;
float m_Scale; float m_Scale;
Spawner* m_Spawner; Spawner* m_Spawner;
@@ -579,3 +592,13 @@ inline ComponentType* Entity::AddComponent(VaArgs... args) {
// To allow a static cast here instead of a dynamic one. // To allow a static cast here instead of a dynamic one.
return dynamic_cast<ComponentType*>(componentToReturn); return dynamic_cast<ComponentType*>(componentToReturn);
} }
template<typename... T>
auto Entity::GetComponents() const {
return GetComponentsMut<const T...>();
}
template<typename... T>
auto Entity::GetComponentsMut() const {
return std::tuple{GetComponent<T>()...};
}

View File

@@ -52,6 +52,43 @@ std::vector<LOT> EntityManager::m_GhostingExcludedLOTs = {
4967 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() { void EntityManager::Initialize() {
// Check if this zone has ghosting enabled // Check if this zone has ghosting enabled
m_GhostingEnabled = std::find( m_GhostingEnabled = std::find(
@@ -61,15 +98,8 @@ void EntityManager::Initialize() {
) == m_GhostingExcludedZones.end(); ) == m_GhostingExcludedZones.end();
// grab hardcore mode settings and load them with sane defaults // grab hardcore mode settings and load them with sane defaults
auto hcmode = Game::config->GetValue("hardcore_mode"); Game::config->AddConfigHandler([]() {Game::entityManager->ReloadConfig();});
m_HardcoreMode = hcmode.empty() ? false : (hcmode == "1"); Game::entityManager->ReloadConfig();
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 // If cloneID is not zero, then hardcore mode is disabled
// aka minigames and props // aka minigames and props
if (Game::zoneManager->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false; if (Game::zoneManager->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false;
@@ -129,6 +159,8 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
// Set the zone control entity if the entity is a zone control object, this should only happen once // Set the zone control entity if the entity is a zone control object, this should only happen once
if (controller) { if (controller) {
m_ZoneControlEntity = entity; m_ZoneControlEntity = entity;
// Proooooobably shouldn't ghost zoneControl
m_ZoneControlEntity->SetIsGhostingCandidate(false);
} }
// Check if this entity is a respawn point, if so add it to the registry // Check if this entity is a respawn point, if so add it to the registry
@@ -279,6 +311,8 @@ std::vector<Entity*> EntityManager::GetEntitiesByComponent(const eReplicaCompone
withComp.push_back(entity); withComp.push_back(entity);
} }
} else {
for (auto* const entity : m_Entities | std::views::values) withComp.push_back(entity);
} }
return withComp; return withComp;
} }
@@ -394,7 +428,7 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
} }
} }
UpdateGhosting(PlayerManager::GetPlayer(sysAddr), true); UpdateGhosting(PlayerManager::GetPlayer(sysAddr));
} }
void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) { void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) {
@@ -463,7 +497,7 @@ void EntityManager::UpdateGhosting() {
m_PlayersToUpdateGhosting.clear(); m_PlayersToUpdateGhosting.clear();
} }
void EntityManager::UpdateGhosting(Entity* player, const bool constructAll) { void EntityManager::UpdateGhosting(Entity* player) {
if (!player) return; if (!player) return;
auto* missionComponent = player->GetComponent<MissionComponent>(); auto* missionComponent = player->GetComponent<MissionComponent>();
@@ -513,9 +547,6 @@ void EntityManager::UpdateGhosting(Entity* player, const bool constructAll) {
entity->SetObservers(entity->GetObservers() + 1); entity->SetObservers(entity->GetObservers() + 1);
// TODO: figure out if zone control should be ghosted at all
if (constructAll && entity->GetObjectID() == GetZoneControlEntity()->GetObjectID()) continue;
ConstructEntity(entity, player->GetSystemAddress()); ConstructEntity(entity, player->GetSystemAddress());
} }
} }

View File

@@ -58,7 +58,7 @@ public:
void SetGhostDistanceMin(float value); void SetGhostDistanceMin(float value);
void QueueGhostUpdate(LWOOBJID playerID); void QueueGhostUpdate(LWOOBJID playerID);
void UpdateGhosting(); void UpdateGhosting();
void UpdateGhosting(Entity* player, const bool constructAll = false); void UpdateGhosting(Entity* player);
void CheckGhosting(Entity* entity); void CheckGhosting(Entity* entity);
Entity* GetGhostCandidate(LWOOBJID id) const; Entity* GetGhostCandidate(LWOOBJID id) const;
bool GetGhostingEnabled() const; bool GetGhostingEnabled() const;
@@ -75,11 +75,18 @@ public:
const uint32_t GetHardcoreLoseUscoreOnDeathPercent() { return m_HardcoreLoseUscoreOnDeathPercent; }; const uint32_t GetHardcoreLoseUscoreOnDeathPercent() { return m_HardcoreLoseUscoreOnDeathPercent; };
const bool GetHardcoreDropinventoryOnDeath() { return m_HardcoreDropinventoryOnDeath; }; const bool GetHardcoreDropinventoryOnDeath() { return m_HardcoreDropinventoryOnDeath; };
const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; }; 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 // Messaging
bool SendMessage(GameMessages::GameMsg& msg) const; bool SendMessage(GameMessages::GameMsg& msg) const;
private: private:
void ReloadConfig();
void SerializeEntities(); void SerializeEntities();
void KillEntities(); void KillEntities();
void DeleteEntities(); void DeleteEntities();
@@ -112,6 +119,12 @@ private:
uint32_t m_HardcoreLoseUscoreOnDeathPercent; uint32_t m_HardcoreLoseUscoreOnDeathPercent;
bool m_HardcoreDropinventoryOnDeath; bool m_HardcoreDropinventoryOnDeath;
uint32_t m_HardcoreUscoreEnemiesMultiplier; 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 #endif // ENTITYMANAGER_H

View File

@@ -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 uint32_t relatedPlayer, const Leaderboard::InfoType infoType, const uint32_t numResults) { 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> toReturn; std::vector<ILeaderboard::Entry> toReturn;
int32_t index = 0; int32_t index = 0;
@@ -197,7 +197,7 @@ std::vector<ILeaderboard::Entry> FilterWeeklies(const std::vector<ILeaderboard::
return weeklyLeaderboard; return weeklyLeaderboard;
} }
std::vector<ILeaderboard::Entry> FilterFriends(const std::vector<ILeaderboard::Entry>& leaderboard, const uint32_t relatedPlayer) { std::vector<ILeaderboard::Entry> FilterFriends(const std::vector<ILeaderboard::Entry>& leaderboard, const LWOOBJID relatedPlayer) {
// Filter the leaderboard to only include friends of the player // Filter the leaderboard to only include friends of the player
auto friendOfPlayer = Database::Get()->GetFriendsList(relatedPlayer); auto friendOfPlayer = Database::Get()->GetFriendsList(relatedPlayer);
std::vector<ILeaderboard::Entry> friendsLeaderboard; std::vector<ILeaderboard::Entry> friendsLeaderboard;
@@ -217,7 +217,7 @@ std::vector<ILeaderboard::Entry> ProcessLeaderboard(
const std::vector<ILeaderboard::Entry>& leaderboard, const std::vector<ILeaderboard::Entry>& leaderboard,
const bool weekly, const bool weekly,
const Leaderboard::InfoType infoType, const Leaderboard::InfoType infoType,
const uint32_t relatedPlayer, const LWOOBJID relatedPlayer,
const uint32_t numResults) { const uint32_t numResults) {
std::vector<ILeaderboard::Entry> toReturn; std::vector<ILeaderboard::Entry> toReturn;

View File

@@ -7,6 +7,10 @@
#include "dZoneManager.h" #include "dZoneManager.h"
#include "eServerDisconnectIdentifiers.h" #include "eServerDisconnectIdentifiers.h"
#include "eGameMasterLevel.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) { User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) {
m_AccountID = 0; m_AccountID = 0;
@@ -28,18 +32,18 @@ User::User(const SystemAddress& sysAddr, const std::string& username, const std:
if (userInfo) { if (userInfo) {
m_AccountID = userInfo->id; m_AccountID = userInfo->id;
m_MaxGMLevel = userInfo->maxGmLevel; m_MaxGMLevel = userInfo->maxGmLevel;
m_MuteExpire = 0; //res->getUInt64(3); m_MuteExpire = userInfo->muteExpire;
} }
//If we're loading a zone, we'll load the last used (aka current) character: //If we're loading a zone, we'll load the last used (aka current) character:
if (Game::server->GetZoneID() != 0) { if (Game::server->GetZoneID() != 0) {
auto characterList = Database::Get()->GetAccountCharacterIds(m_AccountID); auto characterList = Database::Get()->GetAccountCharacterIds(m_AccountID);
if (!characterList.empty()) { if (!characterList.empty()) {
const uint32_t lastUsedCharacterId = characterList.front(); const auto lastUsedCharacterId = characterList.front();
Character* character = new Character(lastUsedCharacterId, this); Character* character = new Character(lastUsedCharacterId, this);
character->UpdateFromDatabase(); character->UpdateFromDatabase();
m_Characters.push_back(character); m_Characters.push_back(character);
LOG("Loaded %i as it is the last used char", lastUsedCharacterId); LOG("Loaded %llu as it is the last used char", lastUsedCharacterId);
} }
} }
} }
@@ -91,8 +95,28 @@ Character* User::GetLastUsedChar() {
} }
} }
bool User::GetIsMuted() const { bool User::GetIsMuted() {
return m_MuteExpire == 1 || m_MuteExpire > time(NULL); 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);
} }
time_t User::GetMuteExpire() const { time_t User::GetMuteExpire() const {

View File

@@ -3,6 +3,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <chrono>
#include "RakNetTypes.h" #include "RakNetTypes.h"
#include "dCommonVars.h" #include "dCommonVars.h"
@@ -46,7 +47,7 @@ public:
const std::unordered_map<std::string, bool>& GetIsBestFriendMap() { return m_IsBestFriendMap; } const std::unordered_map<std::string, bool>& GetIsBestFriendMap() { return m_IsBestFriendMap; }
void UpdateBestFriendValue(const std::string_view playerName, const bool newValue); void UpdateBestFriendValue(const std::string_view playerName, const bool newValue);
bool GetIsMuted() const; bool GetIsMuted();
time_t GetMuteExpire() const; time_t GetMuteExpire() const;
void SetMuteExpire(time_t value); void SetMuteExpire(time_t value);
@@ -72,7 +73,8 @@ private:
bool m_LastChatMessageApproved = false; bool m_LastChatMessageApproved = false;
int m_AmountOfTimesOutOfSync = 0; int m_AmountOfTimesOutOfSync = 0;
const int m_MaxDesyncAllowed = 12; const int m_MaxDesyncAllowed = 12;
time_t m_MuteExpire; uint64_t m_MuteExpire;
std::chrono::steady_clock::time_point m_LastMuteCheck{};
}; };
#endif // USER_H #endif // USER_H

View File

@@ -25,7 +25,7 @@
#include "eGameMasterLevel.h" #include "eGameMasterLevel.h"
#include "eCharacterCreationResponse.h" #include "eCharacterCreationResponse.h"
#include "eRenameResponse.h" #include "eRenameResponse.h"
#include "eConnectionType.h" #include "ServiceType.h"
#include "MessageType/Chat.h" #include "MessageType/Chat.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#include "CheatDetection.h" #include "CheatDetection.h"
@@ -217,7 +217,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) {
} }
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CHARACTER_LIST_RESPONSE); BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::CHARACTER_LIST_RESPONSE);
std::vector<Character*> characters = u->GetCharacters(); std::vector<Character*> characters = u->GetCharacters();
bitStream.Write<uint8_t>(characters.size()); bitStream.Write<uint8_t>(characters.size());
@@ -325,7 +325,9 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet)
} }
//Now that the name is ok, we can get an objectID from Master: //Now that the name is ok, we can get an objectID from Master:
ObjectIDManager::RequestPersistentID([=, this](uint32_t objectID) { ObjectIDManager::RequestPersistentID([=, this](uint32_t persistentID) {
LWOOBJID objectID = persistentID;
GeneralUtils::SetBit(objectID, eObjectBits::CHARACTER);
if (Database::Get()->GetCharacterInfo(objectID)) { if (Database::Get()->GetCharacterInfo(objectID)) {
LOG("Character object id unavailable, check object_id_tracker!"); LOG("Character object id unavailable, check object_id_tracker!");
WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE); WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE);
@@ -409,9 +411,8 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
CINSTREAM_SKIP_HEADER; CINSTREAM_SKIP_HEADER;
LWOOBJID objectID; LWOOBJID objectID;
inStream.Read(objectID); inStream.Read(objectID);
uint32_t charID = static_cast<uint32_t>(objectID);
LOG("Received char delete req for ID: %llu (%u)", objectID, charID); LOG("Received char delete req for ID: %llu", objectID);
bool hasCharacter = CheatDetection::VerifyLwoobjidIsSender( bool hasCharacter = CheatDetection::VerifyLwoobjidIsSender(
objectID, objectID,
@@ -423,11 +424,11 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
if (!hasCharacter) { if (!hasCharacter) {
WorldPackets::SendCharacterDeleteResponse(sysAddr, false); WorldPackets::SendCharacterDeleteResponse(sysAddr, false);
} else { } else {
LOG("Deleting character %i", charID); LOG("Deleting character %llu", objectID);
Database::Get()->DeleteCharacter(charID); Database::Get()->DeleteCharacter(objectID);
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
bitStream.Write(objectID); bitStream.Write(objectID);
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
@@ -445,11 +446,8 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
CINSTREAM_SKIP_HEADER; CINSTREAM_SKIP_HEADER;
LWOOBJID objectID; LWOOBJID objectID;
inStream.Read(objectID); inStream.Read(objectID);
GeneralUtils::ClearBit(objectID, eObjectBits::CHARACTER);
GeneralUtils::ClearBit(objectID, eObjectBits::PERSISTENT);
uint32_t charID = static_cast<uint32_t>(objectID); LOG("Received char rename request for ID: %llu", objectID);
LOG("Received char rename request for ID: %llu (%u)", objectID, charID);
LUWString LUWStringName; LUWString LUWStringName;
inStream.Read(LUWStringName); inStream.Read(LUWStringName);
@@ -466,7 +464,7 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
u->GetAccountID()); u->GetAccountID());
auto unusedItr = std::find_if(u->GetCharacters().begin(), u->GetCharacters().end(), [&](Character* c) { auto unusedItr = std::find_if(u->GetCharacters().begin(), u->GetCharacters().end(), [&](Character* c) {
if (c->GetID() == charID) { if (c->GetID() == objectID) {
character = c; character = c;
return true; return true;
} }
@@ -483,12 +481,12 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
if (!Database::Get()->GetCharacterInfo(newName)) { if (!Database::Get()->GetCharacterInfo(newName)) {
if (IsNamePreapproved(newName)) { if (IsNamePreapproved(newName)) {
Database::Get()->SetCharacterName(charID, newName); Database::Get()->SetCharacterName(objectID, newName);
LOG("Character %s now known as %s", character->GetName().c_str(), newName.c_str()); LOG("Character %s now known as %s", character->GetName().c_str(), newName.c_str());
WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS); WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS);
UserManager::RequestCharacterList(sysAddr); UserManager::RequestCharacterList(sysAddr);
} else { } else {
Database::Get()->SetPendingCharacterName(charID, newName); Database::Get()->SetPendingCharacterName(objectID, newName);
LOG("Character %s has been renamed to %s and is pending approval by a moderator.", character->GetName().c_str(), newName.c_str()); 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); WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS);
UserManager::RequestCharacterList(sysAddr); UserManager::RequestCharacterList(sysAddr);
@@ -502,7 +500,7 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
} }
} }
void UserManager::LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID) { void UserManager::LoginCharacter(const SystemAddress& sysAddr, LWOOBJID playerID) {
User* u = GetUser(sysAddr); User* u = GetUser(sysAddr);
if (!u) { if (!u) {
LOG("Couldn't get user to log in character"); LOG("Couldn't get user to log in character");

View File

@@ -35,7 +35,7 @@ public:
void CreateCharacter(const SystemAddress& sysAddr, Packet* packet); void CreateCharacter(const SystemAddress& sysAddr, Packet* packet);
void DeleteCharacter(const SystemAddress& sysAddr, Packet* packet); void DeleteCharacter(const SystemAddress& sysAddr, Packet* packet);
void RenameCharacter(const SystemAddress& sysAddr, Packet* packet); void RenameCharacter(const SystemAddress& sysAddr, Packet* packet);
void LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID); void LoginCharacter(const SystemAddress& sysAddr, LWOOBJID playerID);
void SaveAllActiveCharacters(); void SaveAllActiveCharacters();

View File

@@ -16,7 +16,7 @@
#include "QuickBuildComponent.h" #include "QuickBuildComponent.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "TeamManager.h" #include "TeamManager.h"
#include "eConnectionType.h" #include "ServiceType.h"
BehaviorSyncEntry::BehaviorSyncEntry() { BehaviorSyncEntry::BehaviorSyncEntry() {
} }
@@ -212,7 +212,7 @@ void BehaviorContext::UpdatePlayerSyncs(float deltaTime) {
echo.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed()); echo.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed());
RakNet::BitStream message; RakNet::BitStream message;
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG); BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
message.Write(this->originator); message.Write(this->originator);
echo.Serialize(message); echo.Serialize(message);
@@ -285,7 +285,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
// Write message // Write message
RakNet::BitStream message; RakNet::BitStream message;
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG); BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
message.Write(this->originator); message.Write(this->originator);
echo.Serialize(message); echo.Serialize(message);

View File

@@ -3,6 +3,8 @@
#include "BehaviorContext.h" #include "BehaviorContext.h"
#include "EntityManager.h" #include "EntityManager.h"
#include <glm/gtc/quaternion.hpp>
void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream& bitStream, BehaviorBranchContext branch) { void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream& bitStream, BehaviorBranchContext branch) {
Entity* sourceEntity; Entity* sourceEntity;
if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator); if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator);
@@ -16,12 +18,12 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS
if (!destinationEntity) return; if (!destinationEntity) return;
sourceEntity->SetRotation( sourceEntity->SetRotation(
NiQuaternion::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition()) QuatUtils::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition())
); );
} else if (this->m_toAngle){ } else if (this->m_toAngle){
auto baseAngle = NiPoint3(0, 0, this->m_angle); auto baseAngle = NiPoint3(0, 0, this->m_angle);
if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector(); if (this->m_relative) baseAngle += QuatUtils::Forward(sourceEntity->GetRotation());
sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle)); sourceEntity->SetRotation(glm::quat(glm::vec3(baseAngle.x, baseAngle.y, baseAngle.z)));
} else return; } else return;
Game::entityManager->SerializeEntity(sourceEntity); Game::entityManager->SerializeEntity(sourceEntity);
return; return;

View File

@@ -12,7 +12,7 @@ void ConsumeItemBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bi
auto inventoryComponent = caster->GetComponent<InventoryComponent>(); auto inventoryComponent = caster->GetComponent<InventoryComponent>();
if (!inventoryComponent) return; if (!inventoryComponent) return;
if (inventoryComponent->RemoveItem(this->m_ConsumeLOT, this->m_NumToConsume, eInventoryType::INVALID, false, true)){ if (inventoryComponent->RemoveItem(this->m_ConsumeLOT, this->m_NumToConsume, eInventoryType::ALL, false, true)){
action_to_cast = m_ActionConsumed; action_to_cast = m_ActionConsumed;
} }
} }

View File

@@ -48,7 +48,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
if (controllablePhysicsComponent != nullptr) { if (controllablePhysicsComponent != nullptr) {
if (m_Forward == 1) { if (m_Forward == 1) {
controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25); controllablePhysicsComponent->SetVelocity(QuatUtils::Forward(controllablePhysicsComponent->GetRotation()) * 25);
} }
Game::entityManager->SerializeEntity(casterEntity); Game::entityManager->SerializeEntity(casterEntity);

View File

@@ -92,7 +92,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
const auto time = distance / this->m_projectileSpeed; const auto time = distance / this->m_projectileSpeed;
const auto rotation = NiQuaternion::LookAtUnlocked(position, other->GetPosition()); const auto rotation = QuatUtils::LookAtUnlocked(position, other->GetPosition());
const auto targetPosition = other->GetPosition(); const auto targetPosition = other->GetPosition();
@@ -112,13 +112,13 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
bitStream.Write(id); bitStream.Write(id);
auto eulerAngles = rotation.GetEulerAngles(); auto eulerAngles = QuatUtils::Euler(rotation);
eulerAngles.y += angle * (3.14 / 180); eulerAngles.y += angle * (glm::pi<float>() / 180.0f);
const auto angledRotation = NiQuaternion::FromEulerAngles(eulerAngles); const auto angledRotation = QuatUtils::FromEuler(eulerAngles);
const auto direction = angledRotation.GetForwardVector(); const auto direction = QuatUtils::Forward(angledRotation);
const auto destination = position + direction * distance; const auto destination = position + direction * distance;

View File

@@ -36,7 +36,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStrea
info.spawner = nullptr; info.spawner = nullptr;
info.spawnerID = context->originator; info.spawnerID = context->originator;
info.spawnerNodeID = 0; info.spawnerNodeID = 0;
info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance); info.pos = info.pos + (QuatUtils::Forward(info.rot) * m_Distance);
auto* entity = Game::entityManager->CreateEntity( auto* entity = Game::entityManager->CreateEntity(
info, info,

View File

@@ -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) if (targetPos.y > reference.y && heightDifference > this->m_upperBound || targetPos.y < reference.y && heightDifference > this->m_lowerBound)
continue; continue;
const auto forward = self->GetRotation().GetForwardVector(); const auto forward = QuatUtils::Forward(self->GetRotation());
// forward is a normalized vector of where the caster is facing. // forward is a normalized vector of where the caster is facing.
// targetPos is the position of the target. // targetPos is the position of the target.

View File

@@ -64,12 +64,11 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
} }
const uint32_t altCurrencyCost = itemComp.commendationCost * count; const uint32_t altCurrencyCost = itemComp.commendationCost * count;
if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost) { if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost || !inventoryComponent->RemoveItem(costLOT, altCurrencyCost, eInventoryType::ALL)) {
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
return; return;
} }
inventoryComponent->RemoveItem(costLOT, altCurrencyCost);
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR); inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS); GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);

View File

@@ -20,7 +20,7 @@
#include "Loot.h" #include "Loot.h"
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eMatchUpdate.h" #include "eMatchUpdate.h"
#include "eConnectionType.h" #include "ServiceType.h"
#include "MessageType/Chat.h" #include "MessageType/Chat.h"
#include "CDCurrencyTableTable.h" #include "CDCurrencyTableTable.h"
@@ -28,8 +28,11 @@
#include "CDActivitiesTable.h" #include "CDActivitiesTable.h"
#include "LeaderboardManager.h" #include "LeaderboardManager.h"
#include "CharacterComponent.h" #include "CharacterComponent.h"
#include "Amf3.h"
ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Component(parent) { ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Component(parent) {
using namespace GameMessages;
RegisterMsg<GetObjectReportInfo>(this, &ActivityComponent::OnGetObjectReportInfo);
/* /*
* This is precisely what the client does functionally * This is precisely what the client does functionally
* Use the component id as the default activity id and load its data from the database * Use the component id as the default activity id and load its data from the database
@@ -348,14 +351,10 @@ bool ActivityComponent::CheckCost(Entity* player) const {
return true; return true;
} }
bool ActivityComponent::TakeCost(Entity* player) const{ bool ActivityComponent::TakeCost(Entity* player) const {
auto* inventoryComponent = player->GetComponent<InventoryComponent>(); auto* inventoryComponent = player->GetComponent<InventoryComponent>();
if (CheckCost(player)) { return CheckCost(player) && inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount, eInventoryType::ALL);
inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount);
return true;
}
else return false;
} }
void ActivityComponent::PlayerReady(Entity* player, bool bReady) { void ActivityComponent::PlayerReady(Entity* player, bool bReady) {
@@ -510,7 +509,7 @@ void ActivityInstance::StartZone() {
// only make a team if we have more than one participant // only make a team if we have more than one participant
if (participants.size() > 1) { if (participants.size() > 1) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::CREATE_TEAM); BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::CREATE_TEAM);
bitStream.Write(leader->GetObjectID()); bitStream.Write(leader->GetObjectID());
bitStream.Write(m_Participants.size()); bitStream.Write(m_Participants.size());
@@ -618,3 +617,91 @@ void ActivityInstance::SetScore(uint32_t score) {
Entity* LobbyPlayer::GetEntity() const { Entity* LobbyPlayer::GetEntity() const {
return Game::entityManager->GetEntity(entityID); return Game::entityManager->GetEntity(entityID);
} }
bool ActivityComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
auto& activityInfo = reportInfo.info->PushDebug("Activity");
auto& instances = activityInfo.PushDebug("Instances: " + std::to_string(m_Instances.size()));
size_t i = 0;
for (const auto& activityInstance : m_Instances) {
if (!activityInstance) continue;
auto& instance = instances.PushDebug("Instance " + std::to_string(i++));
instance.PushDebug<AMFIntValue>("Score") = activityInstance->GetScore();
instance.PushDebug<AMFIntValue>("Next Zone Clone ID") = activityInstance->GetNextZoneCloneID();
{
auto& activityInfo = instance.PushDebug("Activity Info");
const auto& instanceActInfo = activityInstance->GetActivityInfo();
activityInfo.PushDebug<AMFIntValue>("ActivityID") = instanceActInfo.ActivityID;
activityInfo.PushDebug<AMFIntValue>("locStatus") = instanceActInfo.locStatus;
activityInfo.PushDebug<AMFIntValue>("instanceMapID") = instanceActInfo.instanceMapID;
activityInfo.PushDebug<AMFIntValue>("minTeams") = instanceActInfo.minTeams;
activityInfo.PushDebug<AMFIntValue>("maxTeams") = instanceActInfo.maxTeams;
activityInfo.PushDebug<AMFIntValue>("minTeamSize") = instanceActInfo.minTeamSize;
activityInfo.PushDebug<AMFIntValue>("maxTeamSize") = instanceActInfo.maxTeamSize;
activityInfo.PushDebug<AMFIntValue>("waitTime") = instanceActInfo.waitTime;
activityInfo.PushDebug<AMFIntValue>("startDelay") = instanceActInfo.startDelay;
activityInfo.PushDebug<AMFBoolValue>("requiresUniqueData") = instanceActInfo.requiresUniqueData;
activityInfo.PushDebug<AMFIntValue>("leaderboardType") = instanceActInfo.leaderboardType;
activityInfo.PushDebug<AMFBoolValue>("localize") = instanceActInfo.localize;
activityInfo.PushDebug<AMFIntValue>("optionalCostLOT") = instanceActInfo.optionalCostLOT;
activityInfo.PushDebug<AMFIntValue>("optionalCostCount") = instanceActInfo.optionalCostCount;
activityInfo.PushDebug<AMFBoolValue>("showUIRewards") = instanceActInfo.showUIRewards;
activityInfo.PushDebug<AMFIntValue>("CommunityActivityFlagID") = instanceActInfo.CommunityActivityFlagID;
activityInfo.PushDebug<AMFStringValue>("gate_version") = instanceActInfo.gate_version;
activityInfo.PushDebug<AMFBoolValue>("noTeamLootOnDeath") = instanceActInfo.noTeamLootOnDeath;
activityInfo.PushDebug<AMFDoubleValue>("optionalPercentage") = instanceActInfo.optionalPercentage;
}
auto& participants = instance.PushDebug("Participants");
for (const auto* participant : activityInstance->GetParticipants()) {
if (!participant) continue;
auto* character = participant->GetCharacter();
if (!character) continue;
participants.PushDebug<AMFStringValue>(std::to_string(participant->GetObjectID()) + ": " + character->GetName()) = "";
}
}
auto& queue = activityInfo.PushDebug("Queue");
i = 0;
for (const auto& lobbyQueue : m_Queue) {
auto& lobby = queue.PushDebug("Lobby " + std::to_string(i++));
lobby.PushDebug<AMFDoubleValue>("Timer") = lobbyQueue->timer;
auto& players = lobby.PushDebug("Players");
for (const auto* player : lobbyQueue->players) {
if (!player) continue;
auto* playerEntity = player->GetEntity();
if (!playerEntity) continue;
auto* character = playerEntity->GetCharacter();
if (!character) continue;
players.PushDebug<AMFStringValue>(std::to_string(playerEntity->GetObjectID()) + ": " + character->GetName()) = player->ready ? "Ready" : "Not Ready";
}
}
auto& activityPlayers = activityInfo.PushDebug("Activity Players");
for (const auto* activityPlayer : m_ActivityPlayers) {
if (!activityPlayer) continue;
auto* const activityPlayerEntity = Game::entityManager->GetEntity(activityPlayer->playerID);
if (!activityPlayerEntity) continue;
auto* character = activityPlayerEntity->GetCharacter();
if (!character) continue;
auto& playerData = activityPlayers.PushDebug(std::to_string(activityPlayer->playerID) + " " + character->GetName());
auto& scores = playerData.PushDebug("Scores");
for (size_t i = 0; i < 10; ++i) {
scores.PushDebug<AMFDoubleValue>(std::to_string(i)) = activityPlayer->values[i];
}
}
auto& lootMatrices = activityInfo.PushDebug("Loot Matrices");
for (const auto& [activityRating, lootMatrixID] : m_ActivityLootMatrices) {
lootMatrices.PushDebug<AMFIntValue>("Loot Matrix " + std::to_string(activityRating)) = lootMatrixID;
}
activityInfo.PushDebug<AMFIntValue>("ActivityID") = m_ActivityID;
return true;
}

View File

@@ -9,6 +9,10 @@
#include "CDActivitiesTable.h" #include "CDActivitiesTable.h"
namespace GameMessages {
class GameMsg;
};
/** /**
* Represents an instance of an activity, having participants and score * Represents an instance of an activity, having participants and score
*/ */
@@ -60,6 +64,10 @@ public:
* Currently unused * Currently unused
*/ */
void SetScore(uint32_t score); void SetScore(uint32_t score);
[[nodiscard]] uint32_t GetNextZoneCloneID() const noexcept { return m_NextZoneCloneID; }
const CDActivities& GetActivityInfo() const noexcept { return m_ActivityInfo; }
private: private:
/** /**
@@ -75,12 +83,12 @@ private:
/** /**
* The database information for this activity * The database information for this activity
*/ */
CDActivities m_ActivityInfo; CDActivities m_ActivityInfo{};
/** /**
* The entity that owns this activity (the entity that has the ScriptedActivityComponent) * The entity that owns this activity (the entity that has the ScriptedActivityComponent)
*/ */
Entity* m_Parent; Entity* m_Parent{};
/** /**
* All the participants of this activity * All the participants of this activity
@@ -341,6 +349,7 @@ public:
uint32_t GetLootMatrixForTeamSize(uint32_t teamSize) { return m_ActivityLootMatrices[teamSize]; } uint32_t GetLootMatrixForTeamSize(uint32_t teamSize) { return m_ActivityLootMatrices[teamSize]; }
private: private:
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
/** /**
* The database information for this activity * The database information for this activity
*/ */

View File

@@ -767,7 +767,7 @@ void BaseCombatAIComponent::LookAt(const NiPoint3& point) {
return; return;
} }
m_Parent->SetRotation(NiQuaternion::LookAt(m_Parent->GetPosition(), point)); m_Parent->SetRotation(QuatUtils::LookAt(m_Parent->GetPosition(), point));
} }
void BaseCombatAIComponent::SetDisabled(bool value) { void BaseCombatAIComponent::SetDisabled(bool value) {

View File

@@ -77,4 +77,4 @@ target_include_directories(dComponents PUBLIC "."
) )
target_precompile_headers(dComponents REUSE_FROM dGameBase) target_precompile_headers(dComponents REUSE_FROM dGameBase)
target_link_libraries(dComponents INTERFACE dBehaviors) target_link_libraries(dComponents INTERFACE dBehaviors PRIVATE glm::glm)

View File

@@ -49,19 +49,13 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character, con
m_LastUpdateTimestamp = std::time(nullptr); m_LastUpdateTimestamp = std::time(nullptr);
m_SystemAddress = systemAddress; m_SystemAddress = systemAddress;
RegisterMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, this, &CharacterComponent::OnRequestServerObjectInfo); RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &CharacterComponent::OnGetObjectReportInfo);
} }
bool CharacterComponent::OnRequestServerObjectInfo(GameMessages::GameMsg& msg) { bool CharacterComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
auto& request = static_cast<GameMessages::RequestServerObjectInfo&>(msg); auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
AMFArrayValue response;
response.Insert("visible", true); auto& cmptType = reportInfo.info->PushDebug("Character");
response.Insert("objectID", std::to_string(request.targetForReport));
response.Insert("serverInfo", true);
auto& data = *response.InsertArray("data");
auto& cmptType = data.PushDebug("Character");
cmptType.PushDebug<AMFIntValue>("Component ID") = GeneralUtils::ToUnderlying(ComponentType); cmptType.PushDebug<AMFIntValue>("Component ID") = GeneralUtils::ToUnderlying(ComponentType);
cmptType.PushDebug<AMFIntValue>("Character's account ID") = m_Character->GetParentUser()->GetAccountID(); cmptType.PushDebug<AMFIntValue>("Character's account ID") = m_Character->GetParentUser()->GetAccountID();
@@ -72,6 +66,13 @@ bool CharacterComponent::OnRequestServerObjectInfo(GameMessages::GameMsg& msg) {
cmptType.PushDebug<AMFStringValue>("Total currency") = std::to_string(m_Character->GetCoins()); cmptType.PushDebug<AMFStringValue>("Total currency") = std::to_string(m_Character->GetCoins());
cmptType.PushDebug<AMFStringValue>("Currency able to be picked up") = std::to_string(m_DroppedCoins); cmptType.PushDebug<AMFStringValue>("Currency able to be picked up") = std::to_string(m_DroppedCoins);
cmptType.PushDebug<AMFStringValue>("Tooltip flags value") = "0"; cmptType.PushDebug<AMFStringValue>("Tooltip flags value") = "0";
auto& vl = cmptType.PushDebug("Visited Levels");
for (const auto zoneID : m_VisitedLevels) {
std::stringstream sstream;
sstream << "MapID: " << zoneID.GetMapID() << " CloneID: " << zoneID.GetCloneID();
vl.PushDebug<AMFStringValue>(sstream.str()) = "";
}
// visited locations // visited locations
cmptType.PushDebug<AMFBoolValue>("is a GM") = m_GMLevel > eGameMasterLevel::CIVILIAN; cmptType.PushDebug<AMFBoolValue>("is a GM") = m_GMLevel > eGameMasterLevel::CIVILIAN;
cmptType.PushDebug<AMFBoolValue>("Has PVP flag turned on") = m_PvpEnabled; cmptType.PushDebug<AMFBoolValue>("Has PVP flag turned on") = m_PvpEnabled;
@@ -83,9 +84,6 @@ bool CharacterComponent::OnRequestServerObjectInfo(GameMessages::GameMsg& msg) {
cmptType.PushDebug<AMFIntValue>("Current Activity Type") = GeneralUtils::ToUnderlying(m_CurrentActivity); cmptType.PushDebug<AMFIntValue>("Current Activity Type") = GeneralUtils::ToUnderlying(m_CurrentActivity);
cmptType.PushDebug<AMFDoubleValue>("Property Clone ID") = m_Character->GetPropertyCloneID(); cmptType.PushDebug<AMFDoubleValue>("Property Clone ID") = m_Character->GetPropertyCloneID();
GameMessages::SendUIMessageServerToSingleClient("ToggleObjectDebugger", response, m_Parent->GetSystemAddress());
LOG("Handled!");
return true; return true;
} }

View File

@@ -331,7 +331,7 @@ public:
void LoadVisitedLevelsXml(const tinyxml2::XMLElement& doc); void LoadVisitedLevelsXml(const tinyxml2::XMLElement& doc);
private: private:
bool OnRequestServerObjectInfo(GameMessages::GameMsg& msg); bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
/** /**
* The map of active venture vision effects * The map of active venture vision effects
@@ -622,7 +622,7 @@ private:
NiPoint3 m_respawnPos; NiPoint3 m_respawnPos;
NiQuaternion m_respawnRot; NiQuaternion m_respawnRot = QuatUtils::IDENTITY;
std::map<LWOOBJID, Loot::Info> m_DroppedLoot; std::map<LWOOBJID, Loot::Info> m_DroppedLoot;

View File

@@ -56,10 +56,16 @@ public:
protected: protected:
void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) { inline void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
m_Parent->RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1)); m_Parent->RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1));
} }
template<typename T>
inline void RegisterMsg(auto* self, const auto handler) {
T msg;
RegisterMsg(msg.msgId, self, handler);
}
/** /**
* The entity that owns this component * The entity that owns this component
*/ */

View File

@@ -14,8 +14,12 @@
#include "dZoneManager.h" #include "dZoneManager.h"
#include "LevelProgressionComponent.h" #include "LevelProgressionComponent.h"
#include "eStateChangeType.h" #include "eStateChangeType.h"
#include "StringifiedEnum.h"
#include "Amf3.h"
ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity, int32_t componentId) : PhysicsComponent(entity, componentId) { ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity, int32_t componentId) : PhysicsComponent(entity, componentId) {
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &ControllablePhysicsComponent::OnGetObjectReportInfo);
m_Velocity = {}; m_Velocity = {};
m_AngularVelocity = {}; m_AngularVelocity = {};
m_InJetpackMode = false; m_InJetpackMode = false;
@@ -354,3 +358,58 @@ void ControllablePhysicsComponent::SetStunImmunity(
bImmuneToStunUseItem bImmuneToStunUseItem
); );
} }
bool ControllablePhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
PhysicsComponent::OnGetObjectReportInfo(msg);
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
auto& info = reportInfo.subCategory->PushDebug("Controllable Info");
auto& vel = info.PushDebug("Velocity");
vel.PushDebug<AMFDoubleValue>("x") = m_Velocity.x;
vel.PushDebug<AMFDoubleValue>("y") = m_Velocity.y;
vel.PushDebug<AMFDoubleValue>("z") = m_Velocity.z;
auto& angularVelocity = info.PushDebug("Angular Velocity");
angularVelocity.PushDebug<AMFDoubleValue>("x") = m_AngularVelocity.x;
angularVelocity.PushDebug<AMFDoubleValue>("y") = m_AngularVelocity.y;
angularVelocity.PushDebug<AMFDoubleValue>("z") = m_AngularVelocity.z;
info.PushDebug<AMFBoolValue>("Is On Ground") = m_IsOnGround;
info.PushDebug<AMFBoolValue>("Is On Rail") = m_IsOnRail;
info.PushDebug<AMFBoolValue>("Is In Jetpack Mode") = m_InJetpackMode;
info.PushDebug<AMFBoolValue>("Is Jetpack Flying") = m_JetpackFlying;
info.PushDebug<AMFBoolValue>("Is Bypassing Jetpack Checks") = m_JetpackBypassChecks;
info.PushDebug<AMFIntValue>("Jetpack Effect ID") = m_JetpackEffectID;
info.PushDebug<AMFDoubleValue>("Speed Multiplier") = m_SpeedMultiplier;
info.PushDebug<AMFDoubleValue>("Gravity Scale") = m_GravityScale;
info.PushDebug<AMFBoolValue>("Is Static") = m_Static;
auto& pickupRadii = info.PushDebug("Active Pickup Radius Scales");
size_t i = 0;
for (const auto& scale : m_ActivePickupRadiusScales) {
pickupRadii.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(scale)) = "";
}
info.PushDebug<AMFDoubleValue>("Largest Pickup Radius") = m_PickupRadius;
info.PushDebug<AMFBoolValue>("Is Teleporting") = m_IsTeleporting;
auto& activeSpeedBoosts = info.PushDebug("Active Speed Boosts");
i = 0;
for (const auto& boost : m_ActiveSpeedBoosts) {
activeSpeedBoosts.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(boost)) = "";
}
info.PushDebug<AMFDoubleValue>("Speed Boost") = m_SpeedBoost;
info.PushDebug<AMFBoolValue>("Is In Bubble") = m_IsInBubble;
info.PushDebug<AMFStringValue>("Bubble Type") = StringifiedEnum::ToString(m_BubbleType).data();
info.PushDebug<AMFBoolValue>("Special Anims") = m_SpecialAnims;
info.PushDebug<AMFIntValue>("Immune To Stun Attack Count") = m_ImmuneToStunAttackCount;
info.PushDebug<AMFIntValue>("Immune To Stun Equip Count") = m_ImmuneToStunEquipCount;
info.PushDebug<AMFIntValue>("Immune To Stun Interact Count") = m_ImmuneToStunInteractCount;
info.PushDebug<AMFIntValue>("Immune To Stun Jump Count") = m_ImmuneToStunJumpCount;
info.PushDebug<AMFIntValue>("Immune To Stun Move Count") = m_ImmuneToStunMoveCount;
info.PushDebug<AMFIntValue>("Immune To Stun Turn Count") = m_ImmuneToStunTurnCount;
info.PushDebug<AMFIntValue>("Immune To Stun UseItem Count") = m_ImmuneToStunUseItemCount;
return true;
}

View File

@@ -1,16 +1,18 @@
#ifndef CONTROLLABLEPHYSICSCOMPONENT_H #ifndef CONTROLLABLEPHYSICSCOMPONENT_H
#define CONTROLLABLEPHYSICSCOMPONENT_H #define CONTROLLABLEPHYSICSCOMPONENT_H
#include "PhysicsComponent.h"
#include "eReplicaComponentType.h"
#include "dCommonVars.h" #include "dCommonVars.h"
#include "RakNetTypes.h" #include "RakNetTypes.h"
#include "NiPoint3.h" #include "NiPoint3.h"
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include "tinyxml2.h"
#include "PhysicsComponent.h"
#include "dpCollisionChecks.h" #include "dpCollisionChecks.h"
#include "PhantomPhysicsComponent.h"
#include "eBubbleType.h" #include "eBubbleType.h"
#include "eReplicaComponentType.h"
namespace tinyxml2 {
class XMLDocument;
}
class Entity; class Entity;
class dpEntity; class dpEntity;
@@ -281,6 +283,8 @@ public:
const bool GetImmuneToStunUseItem() { return m_ImmuneToStunUseItemCount > 0;}; const bool GetImmuneToStunUseItem() { return m_ImmuneToStunUseItemCount > 0;};
private: private:
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
/** /**
* The entity that owns this component * The entity that owns this component
*/ */
@@ -374,7 +378,7 @@ private:
/** /**
* The active speed boost for this entity * The active speed boost for this entity
*/ */
float m_SpeedBoost; float m_SpeedBoost = 500.0f;
/* /*
* If Bubble info is dirty * If Bubble info is dirty

View File

@@ -21,6 +21,7 @@
#include "BuffComponent.h" #include "BuffComponent.h"
#include "SkillComponent.h" #include "SkillComponent.h"
#include "Item.h" #include "Item.h"
#include "Amf3.h"
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
@@ -29,12 +30,14 @@
#include "CharacterComponent.h" #include "CharacterComponent.h"
#include "PossessableComponent.h" #include "PossessableComponent.h"
#include "PossessorComponent.h" #include "PossessorComponent.h"
#include "ModelComponent.h"
#include "InventoryComponent.h" #include "InventoryComponent.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "WorldConfig.h" #include "WorldConfig.h"
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eStateChangeType.h" #include "eStateChangeType.h"
#include "eGameActivity.h" #include "eGameActivity.h"
#include <ranges>
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
@@ -42,6 +45,7 @@ Implementation<bool, const Entity*> DestroyableComponent::IsEnemyImplentation;
Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation; Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation;
DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
using namespace GameMessages;
m_iArmor = 0; m_iArmor = 0;
m_fMaxArmor = 0.0f; m_fMaxArmor = 0.0f;
m_iImagination = 0; m_iImagination = 0;
@@ -78,6 +82,9 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
m_DeathBehavior = -1; m_DeathBehavior = -1;
m_DamageCooldownTimer = 0.0f; m_DamageCooldownTimer = 0.0f;
RegisterMsg<GetObjectReportInfo>(this, &DestroyableComponent::OnGetObjectReportInfo);
RegisterMsg<GameMessages::SetFaction>(this, &DestroyableComponent::OnSetFaction);
} }
DestroyableComponent::~DestroyableComponent() { DestroyableComponent::~DestroyableComponent() {
@@ -575,6 +582,14 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
return; return;
} }
// Client does the same check, so we're doing it too
auto* const modelComponent = m_Parent->GetComponent<ModelComponent>();
if (modelComponent) {
modelComponent->OnHit();
// Don't actually deal the damage so the model doesn't die
return;
}
// If this entity has damage reduction, reduce the damage to a minimum of 1 // If this entity has damage reduction, reduce the damage to a minimum of 1
if (m_DamageReduction > 0 && damage > 0) { if (m_DamageReduction > 0 && damage > 0) {
if (damage > m_DamageReduction) { if (damage > m_DamageReduction) {
@@ -652,11 +667,6 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
return; return;
} }
//check if hardcore mode is enabled
if (Game::entityManager->GetHardcoreMode()) {
DoHardcoreModeDrops(source);
}
Smash(source, eKillType::VIOLENT, u"", skillID); Smash(source, eKillType::VIOLENT, u"", skillID);
} }
@@ -684,6 +694,11 @@ void DestroyableComponent::NotifySubscribers(Entity* attacker, uint32_t damage)
} }
void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType, uint32_t skillID) { 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) { if (m_iHealth > 0) {
SetArmor(0); SetArmor(0);
SetHealth(0); SetHealth(0);
@@ -967,7 +982,8 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
auto* character = m_Parent->GetComponent<CharacterComponent>(); auto* character = m_Parent->GetComponent<CharacterComponent>();
auto uscore = character->GetUScore(); auto uscore = character->GetUScore();
auto uscoreToLose = uscore * (Game::entityManager->GetHardcoreLoseUscoreOnDeathPercent() / 100); auto uscoreToLose = static_cast<uint64_t>(uscore * (Game::entityManager->GetHardcoreLoseUscoreOnDeathPercent() / 100.0f));
LOG("Player %llu has lost %llu uscore!", m_Parent->GetObjectID(), uscoreToLose);
character->SetUScore(uscore - uscoreToLose); character->SetUScore(uscore - uscoreToLose);
GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::MISSION); GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::MISSION);
@@ -981,13 +997,11 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
if (items) { if (items) {
auto itemMap = items->GetItems(); auto itemMap = items->GetItems();
if (!itemMap.empty()) { if (!itemMap.empty()) {
for (const auto& item : itemMap) { for (const auto item : itemMap | std::views::values) {
//drop the item: // Don't drop excluded items or null ones
if (!item.second) continue; if (!item || Game::entityManager->GetHardcoreExcludedItemDrops().contains(item->GetLot())) continue;
// don't drop the thinkng cap GameMessages::SendDropClientLoot(m_Parent, source, item->GetLot(), 0, m_Parent->GetPosition(), item->GetCount());
if (item.second->GetLot() == 6086) continue; item->SetCount(0, false, false);
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); Game::entityManager->SerializeEntity(m_Parent);
} }
@@ -1006,24 +1020,25 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
//drop all coins: //drop all coins:
GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, coins, m_Parent->GetPosition()); 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; return;
} }
//award the player some u-score: //award the player some u-score:
auto* player = Game::entityManager->GetEntity(source); auto* player = Game::entityManager->GetEntity(source);
if (player && player->IsPlayer()) { if (player && player->IsPlayer()) {
const auto lot = m_Parent->GetLOT();
auto* playerStats = player->GetComponent<CharacterComponent>(); auto* playerStats = player->GetComponent<CharacterComponent>();
if (playerStats) { if (playerStats && GetMaxHealth() > 0 && !Game::entityManager->GetHardcoreUscoreExcludedEnemies().contains(lot)) {
//get the maximum health from this enemy: //get the maximum health from this enemy:
auto maxHealth = GetMaxHealth(); 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(); int uscore = maxHealth * Game::entityManager->GetHardcoreUscoreEnemiesMultiplier() * uscoreReduction;
LOG("Rewarding player %llu with %i uscore for killing enemy %i", player->GetObjectID(), uscore, lot);
playerStats->SetUScore(playerStats->GetUScore() + uscore); playerStats->SetUScore(playerStats->GetUScore() + uscore);
GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::MISSION); GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::MISSION);
@@ -1031,3 +1046,65 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
} }
} }
} }
bool DestroyableComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
auto& destroyableInfo = reportInfo.info->PushDebug("Destroyable");
destroyableInfo.PushDebug<AMFIntValue>("Health") = m_iHealth;
destroyableInfo.PushDebug<AMFDoubleValue>("Max Health") = m_fMaxHealth;
destroyableInfo.PushDebug<AMFIntValue>("Armor") = m_iArmor;
destroyableInfo.PushDebug<AMFDoubleValue>("Max Armor") = m_fMaxArmor;
destroyableInfo.PushDebug<AMFIntValue>("Imagination") = m_iImagination;
destroyableInfo.PushDebug<AMFDoubleValue>("Max Imagination") = m_fMaxImagination;
destroyableInfo.PushDebug<AMFIntValue>("Damage To Absorb") = m_DamageToAbsorb;
destroyableInfo.PushDebug<AMFBoolValue>("Is GM Immune") = m_IsGMImmune;
destroyableInfo.PushDebug<AMFBoolValue>("Is Shielded") = m_IsShielded;
destroyableInfo.PushDebug<AMFIntValue>("Attacks To Block") = m_AttacksToBlock;
destroyableInfo.PushDebug<AMFIntValue>("Damage Reduction") = m_DamageReduction;
auto& factions = destroyableInfo.PushDebug("Factions");
size_t i = 0;
for (const auto factionID : m_FactionIDs) {
factions.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(factionID)) = "";
}
auto& enemyFactions = destroyableInfo.PushDebug("Enemy Factions");
i = 0;
for (const auto enemyFactionID : m_EnemyFactionIDs) {
enemyFactions.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(enemyFactionID)) = "";
}
destroyableInfo.PushDebug<AMFBoolValue>("Is Smashable") = m_IsSmashable;
destroyableInfo.PushDebug<AMFBoolValue>("Is Dead") = m_IsDead;
destroyableInfo.PushDebug<AMFBoolValue>("Is Smashed") = m_IsSmashed;
destroyableInfo.PushDebug<AMFBoolValue>("Is Module Assembly") = m_IsModuleAssembly;
destroyableInfo.PushDebug<AMFDoubleValue>("Explode Factor") = m_ExplodeFactor;
destroyableInfo.PushDebug<AMFBoolValue>("Has Threats") = m_HasThreats;
destroyableInfo.PushDebug<AMFIntValue>("Loot Matrix ID") = m_LootMatrixID;
destroyableInfo.PushDebug<AMFIntValue>("Min Coins") = m_MinCoins;
destroyableInfo.PushDebug<AMFIntValue>("Max Coins") = m_MaxCoins;
destroyableInfo.PushDebug<AMFStringValue>("Killer ID") = std::to_string(m_KillerID);
// "Scripts"; idk what to do about scripts yet
auto& immuneCounts = destroyableInfo.PushDebug("Immune Counts");
immuneCounts.PushDebug<AMFIntValue>("Basic Attack") = m_ImmuneToBasicAttackCount;
immuneCounts.PushDebug<AMFIntValue>("Damage Over Time") = m_ImmuneToDamageOverTimeCount;
immuneCounts.PushDebug<AMFIntValue>("Knockback") = m_ImmuneToKnockbackCount;
immuneCounts.PushDebug<AMFIntValue>("Interrupt") = m_ImmuneToInterruptCount;
immuneCounts.PushDebug<AMFIntValue>("Speed") = m_ImmuneToSpeedCount;
immuneCounts.PushDebug<AMFIntValue>("Imagination Gain") = m_ImmuneToImaginationGainCount;
immuneCounts.PushDebug<AMFIntValue>("Imagination Loss") = m_ImmuneToImaginationLossCount;
immuneCounts.PushDebug<AMFIntValue>("Quickbuild Interrupt") = m_ImmuneToQuickbuildInterruptCount;
immuneCounts.PushDebug<AMFIntValue>("Pull To Point") = m_ImmuneToPullToPointCount;
destroyableInfo.PushDebug<AMFIntValue>("Death Behavior") = m_DeathBehavior;
destroyableInfo.PushDebug<AMFDoubleValue>("Damage Cooldown Timer") = m_DamageCooldownTimer;
return true;
}
bool DestroyableComponent::OnSetFaction(GameMessages::GameMsg& msg) {
auto& modifyFaction = static_cast<GameMessages::SetFaction&>(msg);
m_DirtyHealth = true;
Game::entityManager->SerializeEntity(m_Parent);
SetFaction(modifyFaction.factionID, modifyFaction.bIgnoreChecks);
return true;
}

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