Compare commits

...

33 Commits

Author SHA1 Message Date
David Markowitz
22eb92e570 fix: hardcore mode fixes
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 16:26:15 -07: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
218 changed files with 1887 additions and 1212 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_VISIBILITY_INLINES_HIDDEN ON) # Set C and C++ symbol visibility to hide inlined functions
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
set(FETCHCONTENT_QUIET FALSE) # GLM takes a long time to clone, this will at least show _something_ while its downloading
# Read variables from file
FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables)
@@ -306,7 +307,7 @@ add_subdirectory(dServer)
add_subdirectory(dWeb)
# 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
if(UNIX)

View File

@@ -187,7 +187,8 @@ Now that you are logged in, run the following commands.
```bash
# 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.
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;
# Then create a database for Darkflame Universe to use.

View File

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

View File

@@ -20,7 +20,7 @@
//Auth includes:
#include "AuthPackets.h"
#include "eConnectionType.h"
#include "ServiceType.h"
#include "MessageType/Server.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:
Server::SetupLogger("AuthServer");
if (!Game::logger) return EXIT_FAILURE;
Game::config->LogSettings();
LOG("Starting Auth server...");
LOG("Version: %s", PROJECT_VERSION);
@@ -92,7 +93,7 @@ int main(int argc, char** argv) {
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::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:
auto t = std::chrono::high_resolution_clock::now();
@@ -167,11 +168,11 @@ void HandlePacket(Packet* packet) {
if (packet->length < 4) return;
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) {
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) {
AuthPackets::HandleLoginRequest(Game::server, packet);
}

View File

@@ -1,4 +1,4 @@
set(DCHATFILTER_SOURCES "dChatFilter.cpp")
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})
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)

View File

@@ -13,11 +13,11 @@
// 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) {
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receivingPlayer);
//portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, type);
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, type);
}
void ChatIgnoreList::GetIgnoreList(Packet* packet) {
@@ -34,7 +34,7 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
if (!receiver.ignoredPlayers.empty()) {
LOG_DEBUG("Player %llu already has an ignore list, but is requesting it again.", playerId);
} else {
auto ignoreList = Database::Get()->GetIgnoreList(static_cast<uint32_t>(playerId));
auto ignoreList = Database::Get()->GetIgnoreList(playerId);
if (ignoreList.empty()) {
LOG_DEBUG("Player %llu has no ignores", playerId);
return;
@@ -43,7 +43,6 @@ void ChatIgnoreList::GetIgnoreList(Packet* packet) {
for (auto& ignoredPlayer : ignoreList) {
receiver.ignoredPlayers.emplace_back(ignoredPlayer.name, ignoredPlayer.id);
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::CHARACTER);
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::PERSISTENT);
}
}
@@ -114,9 +113,8 @@ void ChatIgnoreList::AddIgnore(Packet* packet) {
}
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::PERSISTENT);
receiver.ignoredPlayers.emplace_back(toIgnoreStr, ignoredPlayerId);
LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str());
@@ -157,7 +155,7 @@ void ChatIgnoreList::RemoveIgnore(Packet* packet) {
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());
CBITSTREAM;

View File

@@ -12,7 +12,7 @@
#include "RakString.h"
#include "dConfig.h"
#include "eObjectBits.h"
#include "eConnectionType.h"
#include "ServiceType.h"
#include "MessageType/Chat.h"
#include "MessageType/Client.h"
#include "MessageType/Game.h"
@@ -35,7 +35,6 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
FriendData fd;
fd.isFTP = false; // not a thing in DLU
fd.friendID = friendData.friendID;
GeneralUtils::SetBit(fd.friendID, eObjectBits::PERSISTENT);
GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER);
fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
@@ -61,11 +60,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
//Now, we need to send the friendlist to the server they came from:
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(playerID);
//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<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it.
bitStream.Write<uint16_t>(player.friends.size());
@@ -161,9 +160,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
// Set the bits
GeneralUtils::SetBit(queryPlayerID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(queryPlayerID, eObjectBits::PERSISTENT);
GeneralUtils::SetBit(queryFriendID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(queryFriendID, eObjectBits::PERSISTENT);
// Since this player can either be the friend of someone else or be friends with someone else
// their column in the database determines what bit gets set. When the value hits 3, they
@@ -318,7 +315,6 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
}
// Convert friendID to LWOOBJID
GeneralUtils::SetBit(friendID, eObjectBits::PERSISTENT);
GeneralUtils::SetBit(friendID, eObjectBits::CHARACTER);
Database::Get()->RemoveFriend(playerID, friendID);
@@ -375,10 +371,10 @@ void ChatPacketHandler::HandleWho(Packet* packet) {
bool online = player;
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);
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(player.zoneID.GetMapID());
bitStream.Write(player.zoneID.GetInstanceID());
@@ -398,10 +394,10 @@ void ChatPacketHandler::HandleShowAll(Packet* packet) {
if (!sender) return;
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);
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(Game::playerContainer.GetPlayerCount());
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());
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);
notify.WriteHeader(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) {
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);
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(channel);
bitStream.Write<uint32_t>(0); // not used
@@ -579,11 +575,11 @@ void ChatPacketHandler::SendFriendUpdate(const PlayerData& friendData, const Pla
[bool] - is FTP*/
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);
//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);
std::string playerName = playerData.playerName.c_str();
@@ -616,11 +612,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
}
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);
//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<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) {
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);
// 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);
// 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);
@@ -653,11 +649,11 @@ void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const Pla
void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
bitStream.Write(receiver.playerID);
//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(LUWString(personToRemove));

View File

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

View File

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

View File

@@ -264,11 +264,11 @@ void TeamContainer::HandleTeamStatusRequest(Packet* packet) {
void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) {
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);
//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(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) {
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);
//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) {
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);
//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) {
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);
//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) {
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);
//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) {
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);
//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) {
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);
//portion that will get routed:
@@ -652,7 +652,7 @@ void TeamContainer::TeamStatusUpdate(TeamData* team) {
void TeamContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
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(deleteTeam);

View File

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

View File

@@ -20,6 +20,8 @@
#include "Game.h"
#include "Logger.h"
#include <glm/ext/vector_float3.hpp>
enum eInventoryType : uint32_t;
enum class eObjectBits : size_t;
enum class eReplicaComponentType : uint32_t;
@@ -244,7 +246,7 @@ namespace GeneralUtils {
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
[[nodiscard]] std::optional<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);
if (!x) return std::nullopt;
@@ -252,7 +254,7 @@ namespace GeneralUtils {
if (!y) return std::nullopt;
const auto z = TryParse<float>(strZ);
return z ? std::make_optional<NiPoint3>(x.value(), y.value(), z.value()) : std::nullopt;
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
*/
template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::span<const std::string> str) {
return (str.size() == 3) ? TryParse<NiPoint3>(str[0], str[1], str[2]) : std::nullopt;
[[nodiscard]] std::optional<T> TryParse(const std::span<const std::string> str) {
return (str.size() == 3) ? TryParse<T>(str[0], str[1], str[2]) : std::nullopt;
}
template <typename T>
@@ -300,6 +302,12 @@ namespace GeneralUtils {
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
* @param entry Enum entry to cast

View File

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

View File

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

View File

@@ -3,37 +3,18 @@
// C++
#include <cmath>
#include <glm/gtx/quaternion.hpp>
// MARK: Member Functions
Vector3 NiQuaternion::GetEulerAngles() const {
Vector3 angles;
// roll (x-axis rotation)
const float sinr_cosp = 2 * (w * x + y * z);
const float cosr_cosp = 1 - 2 * (x * x + y * y);
angles.x = std::atan2(sinr_cosp, cosr_cosp);
// pitch (y-axis rotation)
const float sinp = 2 * (w * y - z * x);
if (std::abs(sinp) >= 1) {
angles.y = std::copysign(3.14 / 2, sinp); // use 90 degrees if out of range
} else {
angles.y = std::asin(sinp);
}
// yaw (z-axis rotation)
const float siny_cosp = 2 * (w * z + x * y);
const float cosy_cosp = 1 - 2 * (y * y + z * z);
angles.z = std::atan2(siny_cosp, cosy_cosp);
return angles;
Vector3 QuatUtils::Euler(const NiQuaternion& quat) {
return glm::eulerAngles(quat);
}
// MARK: Helper Functions
//! 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:
NiPoint3 source = sourcePoint;
NiPoint3 dest = destPoint;
@@ -51,11 +32,11 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
NiPoint3 vecB = vecA.CrossProduct(posZ);
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
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 posZ = NiPoint3Constant::UNIT_Z;
@@ -67,37 +48,26 @@ NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiP
NiPoint3 vecB = vecA.CrossProduct(posZ);
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
NiQuaternion NiQuaternion::CreateFromAxisAngle(const Vector3& axis, float angle) {
float halfAngle = angle * 0.5f;
float s = static_cast<float>(sin(halfAngle));
NiQuaternion q;
q.x = axis.GetX() * s;
q.y = axis.GetY() * s;
q.z = axis.GetZ() * s;
q.w = static_cast<float>(cos(halfAngle));
return q;
NiQuaternion QuatUtils::AxisAngle(const Vector3& axis, float angle) {
return glm::angleAxis(angle, glm::vec3(axis.x, axis.y, axis.z));
}
NiQuaternion NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles) {
// Abbreviations for the various angular functions
float cy = cos(eulerAngles.z * 0.5);
float sy = sin(eulerAngles.z * 0.5);
float cp = cos(eulerAngles.y * 0.5);
float sp = sin(eulerAngles.y * 0.5);
float cr = cos(eulerAngles.x * 0.5);
float sr = sin(eulerAngles.x * 0.5);
NiQuaternion q;
q.w = cr * cp * cy + sr * sp * sy;
q.x = sr * cp * cy - cr * sp * sy;
q.y = cr * sp * cy + sr * cp * sy;
q.z = cr * cp * sy - sr * sp * cy;
return q;
NiQuaternion QuatUtils::FromEuler(const NiPoint3& eulerAngles) {
return glm::quat(glm::vec3(eulerAngles.x, eulerAngles.y, eulerAngles.z));
}
Vector3 QuatUtils::Forward(const NiQuaternion& quat) {
return quat * glm::vec3(0, 0, 1);
}
Vector3 QuatUtils::Up(const NiQuaternion& quat) {
return quat * glm::vec3(0, 1, 0);
}
Vector3 QuatUtils::Right(const NiQuaternion& quat) {
return quat * glm::vec3(1, 0, 0);
}

View File

@@ -1,158 +1,27 @@
#ifndef __NIQUATERNION_H__
#define __NIQUATERNION_H__
#ifndef NIQUATERNION_H
#define NIQUATERNION_H
// Custom Classes
#include "NiPoint3.h"
/*!
\file NiQuaternion.hpp
\brief Defines a quaternion in space in WXYZ coordinates
*/
#define GLM_FORCE_QUAT_DATA_WXYZ
class NiQuaternion;
typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version of NiQuaternion
#include <glm/ext/quaternion_float.hpp>
//! A class that defines a rotation in space
class NiQuaternion {
public:
float w{ 1 }; //!< The w coordinate
float x{ 0 }; //!< The x coordinate
float y{ 0 }; //!< The y coordinate
float z{ 0 }; //!< The z coordinate
using Quaternion = glm::quat;
using NiQuaternion = Quaternion;
//! The initializer
constexpr NiQuaternion() = default;
//! The initializer
/*!
\param w The w coordinate
\param x The x coordinate
\param y The y coordinate
\param z The z coordinate
*/
constexpr NiQuaternion(const float w, const float x, const float y, const float z) noexcept
: w{ w }
, x{ x }
, y{ y }
, z{ z } {
}
// MARK: Setters / Getters
//! Gets the W coordinate
/*!
\return The w coordinate
*/
[[nodiscard]] constexpr float GetW() const noexcept;
//! Sets the W coordinate
/*!
\param w The w coordinate
*/
constexpr void SetW(const float w) noexcept;
//! Gets the X coordinate
/*!
\return The x coordinate
*/
[[nodiscard]] constexpr float GetX() const noexcept;
//! Sets the X coordinate
/*!
\param x The x coordinate
*/
constexpr void SetX(const float x) noexcept;
//! Gets the Y coordinate
/*!
\return The y coordinate
*/
[[nodiscard]] constexpr float GetY() const noexcept;
//! Sets the Y coordinate
/*!
\param y The y coordinate
*/
constexpr void SetY(const float y) noexcept;
//! Gets the Z coordinate
/*!
\return The z coordinate
*/
[[nodiscard]] constexpr float GetZ() const noexcept;
//! Sets the Z coordinate
/*!
\param z The z coordinate
*/
constexpr void SetZ(const float z) noexcept;
// MARK: Member Functions
//! Returns the forward vector from the quaternion
/*!
\return The forward vector of the quaternion
*/
[[nodiscard]] constexpr Vector3 GetForwardVector() const noexcept;
//! Returns the up vector from the quaternion
/*!
\return The up vector fo the quaternion
*/
[[nodiscard]] constexpr Vector3 GetUpVector() const noexcept;
//! Returns the right vector from the quaternion
/*!
\return The right vector of the quaternion
*/
[[nodiscard]] constexpr Vector3 GetRightVector() const noexcept;
[[nodiscard]] Vector3 GetEulerAngles() const;
// MARK: Operators
//! Operator to check for equality
constexpr bool operator==(const NiQuaternion& rot) const noexcept;
//! Operator to check for inequality
constexpr bool operator!=(const NiQuaternion& rot) const noexcept;
// MARK: Helper Functions
//! Look from a specific point in space to another point in space (Y-locked)
/*!
\param sourcePoint The source location
\param destPoint The destination location
\return The Quaternion with the rotation towards the destination
*/
[[nodiscard]] static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Look from a specific point in space to another point in space
/*!
\param sourcePoint The source location
\param destPoint The destination location
\return The Quaternion with the rotation towards the destination
*/
[[nodiscard]] static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Creates a Quaternion from a specific axis and angle relative to that axis
/*!
\param axis The axis that is used
\param angle The angle relative to this axis
\return A quaternion created from the axis and angle
*/
[[nodiscard]] static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle);
[[nodiscard]] static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
namespace QuatUtils {
constexpr NiQuaternion IDENTITY = glm::identity<NiQuaternion>();
Vector3 Forward(const NiQuaternion& quat);
Vector3 Up(const NiQuaternion& quat);
Vector3 Right(const NiQuaternion& quat);
NiQuaternion LookAt(const NiPoint3& from, const NiPoint3& to);
NiQuaternion LookAtUnlocked(const NiPoint3& from, const NiPoint3& to);
Vector3 Euler(const NiQuaternion& quat);
NiQuaternion AxisAngle(const Vector3& axis, float angle);
NiQuaternion FromEuler(const NiPoint3& eulerAngles);
constexpr float PI_OVER_180 = glm::pi<float>() / 180.0f;
};
// Static Variables
namespace NiQuaternionConstant {
constexpr NiQuaternion IDENTITY(1, 0, 0, 0);
}
// Include constexpr and inline function definitions in a seperate file for readability
#include "NiQuaternion.inl"
#endif // !__NIQUATERNION_H__
#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 {
NiPoint3 position = NiPoint3Constant::ZERO;
NiQuaternion rotation = NiQuaternionConstant::IDENTITY;
NiQuaternion rotation = QuatUtils::IDENTITY;
bool onGround = false;
bool onRail = false;
NiPoint3 velocity = NiPoint3Constant::ZERO;

View File

@@ -47,6 +47,7 @@ void dConfig::LoadConfig() {
void dConfig::ReloadConfig() {
this->m_ConfigValues.clear();
LoadConfig();
LogSettings();
}
const std::string& dConfig::GetValue(std::string key) {
@@ -58,6 +59,14 @@ const std::string& dConfig::GetValue(std::string key) {
return this->m_ConfigValues[key];
}
void dConfig::LogSettings() const {
LOG("Configuration settings:");
for (const auto& [key, value] : m_ConfigValues) {
const auto& valueLog = key.find("password") != std::string::npos ? "<HIDDEN>" : value;
LOG(" %s = %s", key.c_str(), valueLog.c_str());
}
}
void dConfig::ProcessLine(const std::string& line) {
auto splitLoc = line.find('=');
auto key = line.substr(0, splitLoc);

View File

@@ -29,10 +29,12 @@ public:
* Reloads the config file to reset values
*/
void ReloadConfig();
void LogSettings() const;
private:
void ProcessLine(const std::string& line);
private:
std::map<std::string, std::string> m_ConfigValues;
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 "BitStreamUtils.h"
#include "MessageType/Client.h"
#include "eConnectionType.h"
#include "ServiceType.h"
#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 CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false);
#define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits());
#define CMSGHEADER BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, 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_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/dEnums"
)
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3)
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3 glm::glm)
if (${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_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
INTERFACE dCommon
PRIVATE sqlite3 MariaDB::ConnCpp)
PRIVATE sqlite3 MariaDB::ConnCpp glm::glm)
# Glob together all headers that need to be precompiled
file(

View File

@@ -48,7 +48,7 @@ public:
virtual void Commit() = 0;
virtual bool GetAutoCommit() = 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__

View File

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

View File

@@ -14,7 +14,7 @@ enum class eActivityType : uint32_t {
class IActivityLog {
public:
// 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__

View File

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

View File

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

View File

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

View File

@@ -8,13 +8,13 @@
class ICharXml {
public:
// 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.
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.
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__

View File

@@ -8,7 +8,7 @@ class ICommandLog {
public:
// 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__

View File

@@ -8,25 +8,25 @@
class IFriends {
public:
struct BestFriendStatus {
uint32_t playerCharacterId{};
uint32_t friendCharacterId{};
LWOOBJID playerCharacterId{};
LWOOBJID friendCharacterId{};
uint32_t bestFriendStatus{};
};
// 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.
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.
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.
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.
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__

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
class IUgcModularBuild {
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;
};

View File

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

View File

@@ -3,7 +3,7 @@
#include "eGameMasterLevel.h"
std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_view username) {
auto result = ExecuteSelect("SELECT id, password, banned, locked, play_key_id, gm_level 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()) {
return std::nullopt;
@@ -16,6 +16,7 @@ std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_v
toReturn.banned = result->getBoolean("banned");
toReturn.locked = result->getBoolean("locked");
toReturn.playKeyId = result->getUInt("play_key_id");
toReturn.muteExpire = result->getUInt64("mute_expire");
return toReturn;
}

View File

@@ -1,6 +1,6 @@
#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 (?, ?, ?, ?);",
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;
toReturn.id = stmt->getUInt("id");
toReturn.id = stmt->getInt64("id");
toReturn.name = stmt->getString("name").c_str();
toReturn.pendingName = stmt->getString("pending_name").c_str();
toReturn.needsRename = stmt->getBoolean("needs_rename");
@@ -30,7 +30,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(std::unique_ptr<sql::Resu
return toReturn;
}
std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const uint32_t charId) {
std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const LWOOBJID charId) {
return CharInfoFromQueryResult(
ExecuteSelect("SELECT name, pending_name, needs_rename, prop_clone_id, permission_map, id, account_id FROM charinfo WHERE id = ? LIMIT 1;", charId)
);
@@ -42,13 +42,13 @@ std::optional<ICharInfo::Info> MySQLDatabase::GetCharacterInfo(const std::string
);
}
std::vector<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);
std::vector<uint32_t> toReturn;
std::vector<LWOOBJID> toReturn;
toReturn.reserve(result->rowsCount());
while (result->next()) {
toReturn.push_back(result->getUInt("id"));
toReturn.push_back(result->getInt64("id"));
}
return toReturn;
@@ -65,15 +65,15 @@ void MySQLDatabase::InsertNewCharacter(const ICharInfo::Info info) {
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);
}
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);
}
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);
}

View File

@@ -1,6 +1,6 @@
#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);
if (!result->next()) {
@@ -10,10 +10,10 @@ std::string MySQLDatabase::GetCharacterXml(const uint32_t charId) {
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);
}
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);
}

View File

@@ -1,5 +1,5 @@
#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);
}

View File

@@ -1,6 +1,6 @@
#include "MySQLDatabase.h"
std::vector<FriendData> MySQLDatabase::GetFriendsList(const uint32_t charId) {
std::vector<FriendData> MySQLDatabase::GetFriendsList(const LWOOBJID charId) {
auto friendsList = ExecuteSelect(
R"QUERY(
SELECT fr.requested_player AS player, best_friend AS bff, ci.name AS name FROM
@@ -19,7 +19,7 @@ std::vector<FriendData> MySQLDatabase::GetFriendsList(const uint32_t charId) {
while (friendsList->next()) {
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.friendName = friendsList->getString("name").c_str();
@@ -29,7 +29,7 @@ std::vector<FriendData> MySQLDatabase::GetFriendsList(const uint32_t charId) {
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;",
playerCharacterId,
friendCharacterId,
@@ -42,14 +42,14 @@ std::optional<IFriends::BestFriendStatus> MySQLDatabase::GetBestFriendStatus(con
}
IFriends::BestFriendStatus toReturn;
toReturn.playerCharacterId = result->getUInt("player_id");
toReturn.friendCharacterId = result->getUInt("friend_id");
toReturn.playerCharacterId = result->getUInt64("player_id");
toReturn.friendCharacterId = result->getUInt64("friend_id");
toReturn.bestFriendStatus = result->getUInt("best_friend");
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;",
bestFriendStatus,
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);
}
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;",
playerCharacterId,
friendCharacterId,

View File

@@ -1,22 +1,22 @@
#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);
std::vector<IIgnoreList::Info> ignoreList;
ignoreList.reserve(result->rowsCount());
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;
}
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);
}
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);
}

View File

@@ -21,7 +21,7 @@ std::vector<ILeaderboard::Entry> ProcessQuery(UniqueResultSet& rows) {
while (rows->next()) {
auto& entry = entries.emplace_back();
entry.charId = rows->getUInt("character_id");
entry.charId = rows->getUInt64("character_id");
entry.lastPlayedTimestamp = rows->getUInt("lp_unix");
entry.primaryScore = rows->getFloat("primaryScore");
entry.secondaryScore = rows->getFloat("secondaryScore");
@@ -58,21 +58,21 @@ std::vector<ILeaderboard::Entry> MySQLDatabase::GetNsLeaderboard(const uint32_t
return ProcessQuery(leaderboard);
}
void MySQLDatabase::SaveScore(const 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 = ?;",
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 = ?;",
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);
}
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;
auto res = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId);
if (res->next()) {
@@ -86,6 +86,6 @@ std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const uint32_t
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);
}

View File

@@ -19,7 +19,7 @@ void MySQLDatabase::InsertNewMail(const MailInfo& mail) {
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(
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
" FROM mail WHERE receiver_id=? limit ?;",
@@ -61,7 +61,7 @@ std::optional<MailInfo> MySQLDatabase::GetMail(const uint64_t mailId) {
return toReturn;
}
uint32_t MySQLDatabase::GetUnreadMailCount(const 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);
if (!res->next()) {

View File

@@ -119,7 +119,7 @@ std::optional<IProperty::PropertyEntranceResult> MySQLDatabase::GetProperties(co
if (!result) result = IProperty::PropertyEntranceResult();
auto& entry = result->entries.emplace_back();
entry.id = properties->getUInt64("id");
entry.ownerId = properties->getUInt64("owner_id");
entry.ownerId = properties->getInt64("owner_id");
entry.cloneId = properties->getUInt64("clone_id");
entry.name = properties->getString("name").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;
toReturn.id = propertyEntry->getUInt64("id");
toReturn.ownerId = propertyEntry->getUInt64("owner_id");
toReturn.ownerId = propertyEntry->getInt64("owner_id");
toReturn.cloneId = propertyEntry->getUInt64("clone_id");
toReturn.name = propertyEntry->getString("name").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
const uint32_t blueprintId,
const uint32_t accountId,
const uint32_t characterId) {
const LWOOBJID characterId) {
const std::istream stream(sd0Data.rdbuf());
ExecuteInsert(
"INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?)",

View File

@@ -1,6 +1,6 @@
#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);
}

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

View File

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

View File

@@ -1,6 +1,6 @@
#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 (?, ?, ?, ?);",
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;
toReturn.id = stmt.getIntField("id");
toReturn.id = stmt.getInt64Field("id");
toReturn.name = stmt.getStringField("name");
toReturn.pendingName = stmt.getStringField("pending_name");
toReturn.needsRename = stmt.getIntField("needs_rename");
@@ -31,7 +31,7 @@ std::optional<ICharInfo::Info> CharInfoFromQueryResult(CppSQLite3Query stmt) {
return toReturn;
}
std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const uint32_t charId) {
std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const LWOOBJID charId) {
return CharInfoFromQueryResult(
ExecuteSelect("SELECT name, pending_name, needs_rename, prop_clone_id, permission_map, id, account_id FROM charinfo WHERE id = ? LIMIT 1;", charId).second
);
@@ -43,12 +43,12 @@ std::optional<ICharInfo::Info> SQLiteDatabase::GetCharacterInfo(const std::strin
);
}
std::vector<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);
std::vector<uint32_t> toReturn;
std::vector<LWOOBJID> toReturn;
while (!result.eof()) {
toReturn.push_back(result.getIntField("id"));
toReturn.push_back(result.getInt64Field("id"));
result.nextRow();
}
@@ -66,15 +66,15 @@ void SQLiteDatabase::InsertNewCharacter(const ICharInfo::Info info) {
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);
}
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);
}
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);
}

View File

@@ -1,6 +1,6 @@
#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);
if (result.eof()) {
@@ -10,10 +10,10 @@ std::string SQLiteDatabase::GetCharacterXml(const uint32_t charId) {
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);
}
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);
}

View File

@@ -1,5 +1,5 @@
#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);
}

View File

@@ -1,6 +1,6 @@
#include "SQLiteDatabase.h"
std::vector<FriendData> SQLiteDatabase::GetFriendsList(const uint32_t charId) {
std::vector<FriendData> SQLiteDatabase::GetFriendsList(const LWOOBJID charId) {
auto [_, friendsList] = ExecuteSelect(
R"QUERY(
SELECT fr.requested_player AS player, best_friend AS bff, ci.name AS name FROM
@@ -18,7 +18,7 @@ std::vector<FriendData> SQLiteDatabase::GetFriendsList(const uint32_t charId) {
while (!friendsList.eof()) {
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.friendName = friendsList.getStringField("name");
@@ -29,7 +29,7 @@ std::vector<FriendData> SQLiteDatabase::GetFriendsList(const uint32_t charId) {
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;",
playerCharacterId,
friendCharacterId,
@@ -42,14 +42,14 @@ std::optional<IFriends::BestFriendStatus> SQLiteDatabase::GetBestFriendStatus(co
}
IFriends::BestFriendStatus toReturn;
toReturn.playerCharacterId = result.getIntField("player_id");
toReturn.friendCharacterId = result.getIntField("friend_id");
toReturn.playerCharacterId = result.getInt64Field("player_id");
toReturn.friendCharacterId = result.getInt64Field("friend_id");
toReturn.bestFriendStatus = result.getIntField("best_friend");
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 = ?);",
bestFriendStatus,
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);
}
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 = ?);",
playerCharacterId,
friendCharacterId,

View File

@@ -1,22 +1,22 @@
#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);
std::vector<IIgnoreList::Info> ignoreList;
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();
}
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);
}
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);
}

View File

@@ -20,7 +20,7 @@ std::vector<ILeaderboard::Entry> ProcessQuery(CppSQLite3Query& rows) {
while (!rows.eof()) {
auto& entry = entries.emplace_back();
entry.charId = rows.getIntField("character_id");
entry.charId = rows.getInt64Field("character_id");
entry.lastPlayedTimestamp = rows.getIntField("lp_unix");
entry.primaryScore = rows.getFloatField("primaryScore");
entry.secondaryScore = rows.getFloatField("secondaryScore");
@@ -58,17 +58,17 @@ std::vector<ILeaderboard::Entry> SQLiteDatabase::GetNsLeaderboard(const uint32_t
return ProcessQuery(result);
}
void SQLiteDatabase::SaveScore(const 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) ;",
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 = ?;",
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;
auto [_, res] = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId);
if (!res.eof()) {
@@ -82,10 +82,10 @@ std::optional<ILeaderboard::Score> SQLiteDatabase::GetPlayerScore(const uint32_t
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);
}
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);
}

View File

@@ -18,7 +18,7 @@ void SQLiteDatabase::InsertNewMail(const MailInfo& mail) {
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(
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
" FROM mail WHERE receiver_id=? limit ?;",
@@ -60,7 +60,7 @@ std::optional<MailInfo> SQLiteDatabase::GetMail(const uint64_t mailId) {
return toReturn;
}
uint32_t SQLiteDatabase::GetUnreadMailCount(const 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);
if (res.eof()) {

View File

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

View File

@@ -1,6 +1,6 @@
#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);
}

View File

@@ -32,27 +32,27 @@ std::vector<std::string> TestSQLDatabase::GetApprovedCharacterNames() {
return {};
}
std::vector<FriendData> TestSQLDatabase::GetFriendsList(uint32_t charID) {
std::vector<FriendData> TestSQLDatabase::GetFriendsList(LWOOBJID charID) {
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 {};
}
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 {};
}
@@ -88,11 +88,11 @@ std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const std::stri
return {};
}
std::string TestSQLDatabase::GetCharacterXml(const uint32_t accountId) {
std::string TestSQLDatabase::GetCharacterXml(const LWOOBJID accountId) {
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 {};
}
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 {};
}
@@ -204,7 +204,7 @@ std::optional<MailInfo> TestSQLDatabase::GetMail(const uint64_t mailId) {
return {};
}
uint32_t TestSQLDatabase::GetUnreadMailCount(const uint32_t characterId) {
uint32_t TestSQLDatabase::GetUnreadMailCount(const LWOOBJID characterId) {
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 {};
}
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 {};
}

View File

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

View File

@@ -23,7 +23,7 @@
#include "ePlayerFlag.h"
#include "CDPlayerFlagsTable.h"
Character::Character(uint32_t id, User* parentUser) {
Character::Character(LWOOBJID id, User* parentUser) {
//First load the name, etc:
m_ID = id;
m_ParentUser = parentUser;
@@ -50,6 +50,10 @@ void Character::UpdateInfoFromDatabase() {
//Load the xmlData now:
m_XMLData = Database::Get()->GetCharacterXml(m_ID);
if (m_XMLData.empty()) {
LOG("Character %s (%llu) has no xml data!", m_Name.c_str(), m_ID);
return;
}
m_ZoneID = 0; //TEMP! Set back to 0 when done. This is so we can see loading screen progress for testing.
m_ZoneInstanceID = 0; //These values don't really matter, these are only used on the char select screen and seem unused.
@@ -61,7 +65,6 @@ void Character::UpdateInfoFromDatabase() {
//Set our objectID:
m_ObjectID = m_ID;
GeneralUtils::SetBit(m_ObjectID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(m_ObjectID, eObjectBits::PERSISTENT);
m_OurEntity = nullptr;
m_BuildMode = false;
@@ -75,7 +78,7 @@ void Character::DoQuickXMLDataParse() {
if (m_XMLData.size() == 0) return;
if (m_Doc.Parse(m_XMLData.c_str(), m_XMLData.size()) == 0) {
LOG("Loaded xmlData for character %s (%i)!", m_Name.c_str(), m_ID);
LOG("Loaded xmlData for character %s (%llu)!", m_Name.c_str(), m_ID);
} else {
LOG("Failed to load xmlData (%i) (%s) (%s)!", m_Doc.ErrorID(), m_Doc.ErrorIDToName(m_Doc.ErrorID()), m_Doc.ErrorStr());
//Server::rakServer->CloseConnection(m_ParentUser->GetSystemAddress(), true);
@@ -238,7 +241,7 @@ void Character::SetBuildMode(bool buildMode) {
void Character::SaveXMLToDatabase() {
// Check that we can actually _save_ before saving
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;
}
@@ -308,7 +311,7 @@ void Character::SaveXMLToDatabase() {
//For metrics, log the time it took to save:
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = end - start;
LOG("%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() {
@@ -320,7 +323,7 @@ void Character::SetIsNewLogin() {
while (currentChild) {
auto* nextChild = currentChild->NextSiblingElement();
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);
WriteToDatabase();
}
@@ -496,7 +499,7 @@ void Character::OnZoneLoad() {
// Remove all GM items
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 {
public:
Character(uint32_t id, User* parentUser);
Character(LWOOBJID id, User* parentUser);
~Character();
/**
@@ -53,7 +53,7 @@ public:
* Gets 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
@@ -467,9 +467,9 @@ public:
private:
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.
@@ -654,7 +654,7 @@ private:
/**
* 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

View File

@@ -97,6 +97,8 @@
#include "CDSkillBehaviorTable.h"
#include "CDZoneTableTable.h"
#include "StringifiedEnum.h"
#include <ranges>
Observable<Entity*, const PositionUpdate&> Entity::OnPlayerPositionUpdate;
@@ -173,8 +175,11 @@ Entity::~Entity() {
CancelAllTimers();
CancelCallbackTimers();
for (const auto& component : m_Components | std::views::values) {
if (component) delete component;
for (auto& component : m_Components | std::views::values) {
if (component) {
delete component;
component = nullptr;
}
}
for (auto* const child : m_ChildEntities) {
@@ -187,6 +192,7 @@ Entity::~Entity() {
}
void Entity::Initialize() {
RegisterMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, this, &Entity::MsgRequestServerObjectInfo);
/**
* Setup trigger
*/
@@ -298,7 +304,7 @@ void Entity::Initialize() {
//If we came from another zone, put us in the starting loc
if (m_Character->GetZoneID() != Game::server->GetZoneID() || mapID == 1603) { // Exception for Moon Base as you tend to spawn on the roof.
NiPoint3 pos;
NiQuaternion rot;
NiQuaternion rot = QuatUtils::IDENTITY;
const auto& targetSceneName = m_Character->GetTargetScene();
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
@@ -899,7 +905,7 @@ void Entity::SetGMLevel(eGameMasterLevel value) {
// Update the chat server of our GM Level
{
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_GMLevel);
@@ -920,7 +926,7 @@ void Entity::WriteLDFData(const std::vector<LDFBaseData*>& ldf, RakNet::BitStrea
numberOfValidKeys--;
}
}
// Now write it to the main bitstream
outBitStream.Write<uint32_t>(settingStream.GetNumberOfBytesUsed() + 1 + sizeof(uint32_t));
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>();
const auto skills = skillsTable->Query([&info](CDObjectSkills entry) {return (entry.objectTemplate == info.lot); });
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));
auto* missionComponent = GetComponent<MissionComponent>();
if (missionComponent != nullptr) {
missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID);
}
@@ -1878,7 +1882,7 @@ const NiQuaternion& Entity::GetRotation() const {
return rigidBodyPhantomPhysicsComponent->GetRotation();
}
return NiQuaternionConstant::IDENTITY;
return QuatUtils::IDENTITY;
}
void Entity::SetPosition(const NiPoint3& position) {
@@ -2174,7 +2178,7 @@ const NiPoint3& Entity::GetRespawnPosition() const {
const NiQuaternion& Entity::GetRespawnRotation() const {
auto* characterComponent = GetComponent<CharacterComponent>();
return characterComponent ? characterComponent->GetRespawnRotation() : NiQuaternionConstant::IDENTITY;
return characterComponent ? characterComponent->GetRespawnRotation() : QuatUtils::IDENTITY;
}
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) {
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 <functional>
#include <tuple>
#include <typeinfo>
#include <type_traits>
#include <unordered_map>
@@ -161,6 +162,12 @@ public:
template<typename T>
T* GetComponent() const;
template<typename... T>
auto GetComponents() const;
template<typename... T>
auto GetComponentsMut() const;
template<typename T>
bool TryGetComponent(eReplicaComponentType componentId, T*& component) const;
@@ -168,6 +175,8 @@ public:
void AddComponent(eReplicaComponentType componentId, Component* component);
bool MsgRequestServerObjectInfo(GameMessages::GameMsg& msg);
// This is expceted to never return nullptr, an assert checks this.
CppScripts::Script* const GetScript() const;
@@ -329,6 +338,10 @@ public:
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.
*/
@@ -344,7 +357,7 @@ private:
std::vector<LDFBaseData*> m_NetworkSettings;
NiPoint3 m_DefaultPosition;
NiQuaternion m_DefaultRotation;
NiQuaternion m_DefaultRotation = QuatUtils::IDENTITY;
float m_Scale;
Spawner* m_Spawner;
@@ -579,3 +592,13 @@ inline ComponentType* Entity::AddComponent(VaArgs... args) {
// To allow a static cast here instead of a dynamic one.
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

@@ -129,6 +129,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
if (controller) {
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
@@ -279,6 +281,8 @@ std::vector<Entity*> EntityManager::GetEntitiesByComponent(const eReplicaCompone
withComp.push_back(entity);
}
} else {
for (auto* const entity : m_Entities | std::views::values) withComp.push_back(entity);
}
return withComp;
}
@@ -394,7 +398,7 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
}
}
UpdateGhosting(PlayerManager::GetPlayer(sysAddr), true);
UpdateGhosting(PlayerManager::GetPlayer(sysAddr));
}
void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) {
@@ -463,7 +467,7 @@ void EntityManager::UpdateGhosting() {
m_PlayersToUpdateGhosting.clear();
}
void EntityManager::UpdateGhosting(Entity* player, const bool constructAll) {
void EntityManager::UpdateGhosting(Entity* player) {
if (!player) return;
auto* missionComponent = player->GetComponent<MissionComponent>();
@@ -513,9 +517,6 @@ void EntityManager::UpdateGhosting(Entity* player, const bool constructAll) {
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());
}
}

View File

@@ -58,7 +58,7 @@ public:
void SetGhostDistanceMin(float value);
void QueueGhostUpdate(LWOOBJID playerID);
void UpdateGhosting();
void UpdateGhosting(Entity* player, const bool constructAll = false);
void UpdateGhosting(Entity* player);
void CheckGhosting(Entity* entity);
Entity* GetGhostCandidate(LWOOBJID id) const;
bool GetGhostingEnabled() const;

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

View File

@@ -7,6 +7,10 @@
#include "dZoneManager.h"
#include "eServerDisconnectIdentifiers.h"
#include "eGameMasterLevel.h"
#include "BitStreamUtils.h"
#include "MessageType/Chat.h"
#include <chrono>
#include <ctime>
User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) {
m_AccountID = 0;
@@ -28,18 +32,18 @@ User::User(const SystemAddress& sysAddr, const std::string& username, const std:
if (userInfo) {
m_AccountID = userInfo->id;
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 (Game::server->GetZoneID() != 0) {
auto characterList = Database::Get()->GetAccountCharacterIds(m_AccountID);
if (!characterList.empty()) {
const uint32_t lastUsedCharacterId = characterList.front();
const auto lastUsedCharacterId = characterList.front();
Character* character = new Character(lastUsedCharacterId, this);
character->UpdateFromDatabase();
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 {
return m_MuteExpire == 1 || m_MuteExpire > time(NULL);
bool User::GetIsMuted() {
using namespace std::chrono;
constexpr auto refreshInterval = seconds{ 60 };
const auto now = steady_clock::now();
if (now - m_LastMuteCheck >= refreshInterval) {
m_LastMuteCheck = now;
if (const auto info = Database::Get()->GetAccountInfo(m_Username)) {
const auto expire = static_cast<time_t>(info->muteExpire);
if (expire != m_MuteExpire) {
m_MuteExpire = expire;
if (Game::chatServer && m_LoggedInCharID != 0) {
RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_MUTE);
bitStream.Write(m_LoggedInCharID);
bitStream.Write(m_MuteExpire);
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
}
}
}
}
return m_MuteExpire == 1 || m_MuteExpire > std::time(nullptr);
}
time_t User::GetMuteExpire() const {

View File

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

View File

@@ -25,7 +25,7 @@
#include "eGameMasterLevel.h"
#include "eCharacterCreationResponse.h"
#include "eRenameResponse.h"
#include "eConnectionType.h"
#include "ServiceType.h"
#include "MessageType/Chat.h"
#include "BitStreamUtils.h"
#include "CheatDetection.h"
@@ -217,7 +217,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) {
}
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();
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:
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)) {
LOG("Character object id unavailable, check object_id_tracker!");
WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE);
@@ -409,9 +411,8 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
CINSTREAM_SKIP_HEADER;
LWOOBJID objectID;
inStream.Read(objectID);
uint32_t charID = static_cast<uint32_t>(objectID);
LOG("Received char delete req for ID: %llu (%u)", objectID, charID);
LOG("Received char delete req for ID: %llu", objectID);
bool hasCharacter = CheatDetection::VerifyLwoobjidIsSender(
objectID,
@@ -423,11 +424,11 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
if (!hasCharacter) {
WorldPackets::SendCharacterDeleteResponse(sysAddr, false);
} else {
LOG("Deleting character %i", charID);
Database::Get()->DeleteCharacter(charID);
LOG("Deleting character %llu", objectID);
Database::Get()->DeleteCharacter(objectID);
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
bitStream.Write(objectID);
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;
LWOOBJID 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 (%u)", objectID, charID);
LOG("Received char rename request for ID: %llu", objectID);
LUWString LUWStringName;
inStream.Read(LUWStringName);
@@ -466,7 +464,7 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
u->GetAccountID());
auto unusedItr = std::find_if(u->GetCharacters().begin(), u->GetCharacters().end(), [&](Character* c) {
if (c->GetID() == charID) {
if (c->GetID() == objectID) {
character = c;
return true;
}
@@ -483,12 +481,12 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet)
if (!Database::Get()->GetCharacterInfo(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());
WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS);
UserManager::RequestCharacterList(sysAddr);
} 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());
WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS);
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);
if (!u) {
LOG("Couldn't get user to log in character");

View File

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

View File

@@ -16,7 +16,7 @@
#include "QuickBuildComponent.h"
#include "eReplicaComponentType.h"
#include "TeamManager.h"
#include "eConnectionType.h"
#include "ServiceType.h"
BehaviorSyncEntry::BehaviorSyncEntry() {
}
@@ -212,7 +212,7 @@ void BehaviorContext::UpdatePlayerSyncs(float deltaTime) {
echo.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed());
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);
echo.Serialize(message);
@@ -285,7 +285,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
// Write 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);
echo.Serialize(message);

View File

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

View File

@@ -12,7 +12,7 @@ void ConsumeItemBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bi
auto inventoryComponent = caster->GetComponent<InventoryComponent>();
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;
}
}

View File

@@ -48,7 +48,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
if (controllablePhysicsComponent != nullptr) {
if (m_Forward == 1) {
controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25);
controllablePhysicsComponent->SetVelocity(QuatUtils::Forward(controllablePhysicsComponent->GetRotation()) * 25);
}
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 rotation = NiQuaternion::LookAtUnlocked(position, other->GetPosition());
const auto rotation = QuatUtils::LookAtUnlocked(position, other->GetPosition());
const auto targetPosition = other->GetPosition();
@@ -112,13 +112,13 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
bitStream.Write(id);
auto eulerAngles = 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;

View File

@@ -36,7 +36,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStrea
info.spawner = nullptr;
info.spawnerID = context->originator;
info.spawnerNodeID = 0;
info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance);
info.pos = info.pos + (QuatUtils::Forward(info.rot) * m_Distance);
auto* entity = Game::entityManager->CreateEntity(
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)
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.
// 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;
if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost) {
if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost || !inventoryComponent->RemoveItem(costLOT, altCurrencyCost, eInventoryType::ALL)) {
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
return;
}
inventoryComponent->RemoveItem(costLOT, altCurrencyCost);
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);

View File

@@ -20,7 +20,7 @@
#include "Loot.h"
#include "eMissionTaskType.h"
#include "eMatchUpdate.h"
#include "eConnectionType.h"
#include "ServiceType.h"
#include "MessageType/Chat.h"
#include "CDCurrencyTableTable.h"
@@ -28,8 +28,11 @@
#include "CDActivitiesTable.h"
#include "LeaderboardManager.h"
#include "CharacterComponent.h"
#include "Amf3.h"
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
* 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;
}
bool ActivityComponent::TakeCost(Entity* player) const{
bool ActivityComponent::TakeCost(Entity* player) const {
auto* inventoryComponent = player->GetComponent<InventoryComponent>();
if (CheckCost(player)) {
inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount);
return true;
}
else return false;
return CheckCost(player) && inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount, eInventoryType::ALL);
}
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
if (participants.size() > 1) {
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(m_Participants.size());
@@ -618,3 +617,91 @@ void ActivityInstance::SetScore(uint32_t score) {
Entity* LobbyPlayer::GetEntity() const {
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"
namespace GameMessages {
class GameMsg;
};
/**
* Represents an instance of an activity, having participants and score
*/
@@ -60,6 +64,10 @@ public:
* Currently unused
*/
void SetScore(uint32_t score);
[[nodiscard]] uint32_t GetNextZoneCloneID() const noexcept { return m_NextZoneCloneID; }
const CDActivities& GetActivityInfo() const noexcept { return m_ActivityInfo; }
private:
/**
@@ -75,12 +83,12 @@ private:
/**
* The database information for this activity
*/
CDActivities m_ActivityInfo;
CDActivities m_ActivityInfo{};
/**
* The entity that owns this activity (the entity that has the ScriptedActivityComponent)
*/
Entity* m_Parent;
Entity* m_Parent{};
/**
* All the participants of this activity
@@ -341,6 +349,7 @@ public:
uint32_t GetLootMatrixForTeamSize(uint32_t teamSize) { return m_ActivityLootMatrices[teamSize]; }
private:
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
/**
* The database information for this activity
*/

View File

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

View File

@@ -77,4 +77,4 @@ target_include_directories(dComponents PUBLIC "."
)
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_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) {
auto& request = static_cast<GameMessages::RequestServerObjectInfo&>(msg);
AMFArrayValue response;
bool CharacterComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
response.Insert("visible", true);
response.Insert("objectID", std::to_string(request.targetForReport));
response.Insert("serverInfo", true);
auto& data = *response.InsertArray("data");
auto& cmptType = data.PushDebug("Character");
auto& cmptType = reportInfo.info->PushDebug("Character");
cmptType.PushDebug<AMFIntValue>("Component ID") = GeneralUtils::ToUnderlying(ComponentType);
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>("Currency able to be picked up") = std::to_string(m_DroppedCoins);
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
cmptType.PushDebug<AMFBoolValue>("is a GM") = m_GMLevel > eGameMasterLevel::CIVILIAN;
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<AMFDoubleValue>("Property Clone ID") = m_Character->GetPropertyCloneID();
GameMessages::SendUIMessageServerToSingleClient("ToggleObjectDebugger", response, m_Parent->GetSystemAddress());
LOG("Handled!");
return true;
}

View File

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

View File

@@ -56,10 +56,16 @@ public:
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));
}
template<typename T>
inline void RegisterMsg(auto* self, const auto handler) {
T msg;
RegisterMsg(msg.msgId, self, handler);
}
/**
* The entity that owns this component
*/

View File

@@ -14,8 +14,12 @@
#include "dZoneManager.h"
#include "LevelProgressionComponent.h"
#include "eStateChangeType.h"
#include "StringifiedEnum.h"
#include "Amf3.h"
ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity, int32_t componentId) : PhysicsComponent(entity, componentId) {
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &ControllablePhysicsComponent::OnGetObjectReportInfo);
m_Velocity = {};
m_AngularVelocity = {};
m_InJetpackMode = false;
@@ -354,3 +358,58 @@ void ControllablePhysicsComponent::SetStunImmunity(
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
#define CONTROLLABLEPHYSICSCOMPONENT_H
#include "PhysicsComponent.h"
#include "eReplicaComponentType.h"
#include "dCommonVars.h"
#include "RakNetTypes.h"
#include "NiPoint3.h"
#include "NiQuaternion.h"
#include "tinyxml2.h"
#include "PhysicsComponent.h"
#include "dpCollisionChecks.h"
#include "PhantomPhysicsComponent.h"
#include "eBubbleType.h"
#include "eReplicaComponentType.h"
namespace tinyxml2 {
class XMLDocument;
}
class Entity;
class dpEntity;
@@ -281,6 +283,8 @@ public:
const bool GetImmuneToStunUseItem() { return m_ImmuneToStunUseItemCount > 0;};
private:
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
/**
* The entity that owns this component
*/
@@ -374,7 +378,7 @@ private:
/**
* The active speed boost for this entity
*/
float m_SpeedBoost;
float m_SpeedBoost = 500.0f;
/*
* If Bubble info is dirty

View File

@@ -21,6 +21,7 @@
#include "BuffComponent.h"
#include "SkillComponent.h"
#include "Item.h"
#include "Amf3.h"
#include <sstream>
#include <algorithm>
@@ -29,6 +30,7 @@
#include "CharacterComponent.h"
#include "PossessableComponent.h"
#include "PossessorComponent.h"
#include "ModelComponent.h"
#include "InventoryComponent.h"
#include "dZoneManager.h"
#include "WorldConfig.h"
@@ -42,6 +44,7 @@ Implementation<bool, const Entity*> DestroyableComponent::IsEnemyImplentation;
Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation;
DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
using namespace GameMessages;
m_iArmor = 0;
m_fMaxArmor = 0.0f;
m_iImagination = 0;
@@ -78,6 +81,9 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
m_DeathBehavior = -1;
m_DamageCooldownTimer = 0.0f;
RegisterMsg<GetObjectReportInfo>(this, &DestroyableComponent::OnGetObjectReportInfo);
RegisterMsg<GameMessages::SetFaction>(this, &DestroyableComponent::OnSetFaction);
}
DestroyableComponent::~DestroyableComponent() {
@@ -575,6 +581,14 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
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 (m_DamageReduction > 0 && damage > 0) {
if (damage > m_DamageReduction) {
@@ -1031,3 +1045,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