Compare commits

..

1 Commits

Author SHA1 Message Date
David Markowitz
7f90bb6181 Update CMakeLists.txt 2023-08-07 20:01:45 -07:00
377 changed files with 3546 additions and 4145 deletions

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.18)
project(Darkflame) project(Darkflame)
include(CTest) include(CTest)
set (CMAKE_CXX_STANDARD 17) set (CMAKE_CXX_STANDARD 20)
# Read variables from file # Read variables from file
FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables) FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables)
@@ -148,19 +148,16 @@ foreach (resource_file ${RESOURCE_FILES})
endforeach() endforeach()
message(STATUS "Resource file integrity check complete") message(STATUS "Resource file integrity check complete")
# if navmeshes directory does not exist, create it
if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/navmeshes)
endif()
# Copy navmesh data on first build and extract it # Copy navmesh data on first build and extract it
if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes/)
configure_file( configure_file(
${CMAKE_SOURCE_DIR}/resources/navmeshes.zip ${PROJECT_BINARY_DIR}/navmeshes.zip ${CMAKE_SOURCE_DIR}/resources/navmeshes.zip ${PROJECT_BINARY_DIR}/navmeshes.zip
COPYONLY COPYONLY
) )
file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip DESTINATION ${PROJECT_BINARY_DIR}/navmeshes) file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip)
file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip) file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip)
endif()
# Copy vanity files on first build # Copy vanity files on first build
set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml") set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml")

View File

@@ -1,5 +1,5 @@
PROJECT_VERSION_MAJOR=1 PROJECT_VERSION_MAJOR=1
PROJECT_VERSION_MINOR=1 PROJECT_VERSION_MINOR=0
PROJECT_VERSION_PATCH=1 PROJECT_VERSION_PATCH=1
# LICENSE # LICENSE
LICENSE=AGPL-3.0 LICENSE=AGPL-3.0
@@ -18,5 +18,3 @@ __maria_db_connector_compile_jobs__=1
__enable_testing__=1 __enable_testing__=1
# The path to OpenSSL. Change this if your OpenSSL install path is different than the default. # The path to OpenSSL. Change this if your OpenSSL install path is different than the default.
OPENSSL_ROOT_DIR=/usr/local/opt/openssl@3/ OPENSSL_ROOT_DIR=/usr/local/opt/openssl@3/
# Uncomment the below line to cache the entire CDClient into memory
# CDCLIENT_CACHE_ALL=1

View File

@@ -7,7 +7,7 @@
//DLU Includes: //DLU Includes:
#include "dCommonVars.h" #include "dCommonVars.h"
#include "dServer.h" #include "dServer.h"
#include "Logger.h" #include "dLogger.h"
#include "Database.h" #include "Database.h"
#include "dConfig.h" #include "dConfig.h"
#include "Diagnostics.h" #include "Diagnostics.h"
@@ -25,14 +25,14 @@
#include "Game.h" #include "Game.h"
namespace Game { namespace Game {
Logger* logger = nullptr; dLogger* logger = nullptr;
dServer* server = nullptr; dServer* server = nullptr;
dConfig* config = nullptr; dConfig* config = nullptr;
bool shouldShutdown = false; bool shouldShutdown = false;
std::mt19937 randomEngine; std::mt19937 randomEngine;
} }
Logger* SetupLogger(); dLogger* SetupLogger();
void HandlePacket(Packet* packet); void HandlePacket(Packet* packet);
int main(int argc, char** argv) { int main(int argc, char** argv) {
@@ -51,9 +51,9 @@ int main(int argc, char** argv) {
Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0");
Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1");
LOG("Starting Auth server..."); Game::logger->Log("AuthServer", "Starting Auth server...");
LOG("Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("AuthServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
LOG("Compiled on: %s", __TIMESTAMP__); Game::logger->Log("AuthServer", "Compiled on: %s", __TIMESTAMP__);
//Connect to the MySQL Database //Connect to the MySQL Database
std::string mysql_host = Game::config->GetValue("mysql_host"); std::string mysql_host = Game::config->GetValue("mysql_host");
@@ -64,7 +64,7 @@ int main(int argc, char** argv) {
try { try {
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
} catch (sql::SQLException& ex) { } catch (sql::SQLException& ex) {
LOG("Got an error while connecting to the database: %s", ex.what()); Game::logger->Log("AuthServer", "Got an error while connecting to the database: %s", ex.what());
Database::Destroy("AuthServer"); Database::Destroy("AuthServer");
delete Game::server; delete Game::server;
delete Game::logger; delete Game::logger;
@@ -161,7 +161,7 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Logger* SetupLogger() { dLogger* SetupLogger() {
std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/AuthServer_" + std::to_string(time(nullptr)) + ".log")).string(); std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/AuthServer_" + std::to_string(time(nullptr)) + ".log")).string();
bool logToConsole = false; bool logToConsole = false;
bool logDebugStatements = false; bool logDebugStatements = false;
@@ -170,7 +170,7 @@ Logger* SetupLogger() {
logDebugStatements = true; logDebugStatements = true;
#endif #endif
return new Logger(logPath, logToConsole, logDebugStatements); return new dLogger(logPath, logToConsole, logDebugStatements);
} }
void HandlePacket(Packet* packet) { void HandlePacket(Packet* packet) {

View File

@@ -8,7 +8,7 @@
#include <regex> #include <regex>
#include "dCommonVars.h" #include "dCommonVars.h"
#include "Logger.h" #include "dLogger.h"
#include "dConfig.h" #include "dConfig.h"
#include "Database.h" #include "Database.h"
#include "Game.h" #include "Game.h"

View File

@@ -3,11 +3,10 @@
#include "Database.h" #include "Database.h"
#include <vector> #include <vector>
#include "PacketUtils.h" #include "PacketUtils.h"
#include "BitStreamUtils.h"
#include "Game.h" #include "Game.h"
#include "dServer.h" #include "dServer.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "Logger.h" #include "dLogger.h"
#include "eAddFriendResponseCode.h" #include "eAddFriendResponseCode.h"
#include "eAddFriendResponseType.h" #include "eAddFriendResponseType.h"
#include "RakString.h" #include "RakString.h"
@@ -76,11 +75,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
//Now, we need to send the friendlist to the server they came from: //Now, we need to send the friendlist to the server they came from:
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(playerID); bitStream.Write(playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE); PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE);
bitStream.Write<uint8_t>(0); bitStream.Write<uint8_t>(0);
bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it. bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it.
bitStream.Write((uint16_t)friends.size()); bitStream.Write((uint16_t)friends.size());
@@ -118,11 +117,6 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
inStream.Read(isBestFriendRequest); inStream.Read(isBestFriendRequest);
auto requestor = playerContainer.GetPlayerData(requestorPlayerID); auto requestor = playerContainer.GetPlayerData(requestorPlayerID);
if (!requestor) {
LOG("No requestor player %llu sent to %s found.", requestorPlayerID, playerName.c_str());
return;
}
if (requestor->playerName == playerName) { if (requestor->playerName == playerName) {
SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN); SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN);
return; return;
@@ -402,7 +396,7 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) {
std::string message = PacketUtils::ReadString(0x66, packet, true, 512); std::string message = PacketUtils::ReadString(0x66, packet, true, 512);
LOG("Got a message from (%s) [%d]: %s", senderName.c_str(), channel, message.c_str()); Game::logger->Log("ChatPacketHandler", "Got a message from (%s) [%d]: %s", senderName.c_str(), channel, message.c_str());
if (channel != 8) return; if (channel != 8) return;
@@ -418,21 +412,21 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) {
const auto otherName = std::string(otherMember->playerName.c_str()); const auto otherName = std::string(otherMember->playerName.c_str());
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(otherMember->playerID); bitStream.Write(otherMember->playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
bitStream.Write(otherMember->playerID); bitStream.Write(otherMember->playerID);
bitStream.Write<uint8_t>(8); bitStream.Write<uint8_t>(8);
bitStream.Write<unsigned int>(69); bitStream.Write<unsigned int>(69);
bitStream.Write(LUWString(senderName)); PacketUtils::WritePacketWString(senderName, 33, &bitStream);
bitStream.Write(sender->playerID); bitStream.Write(sender->playerID);
bitStream.Write<uint16_t>(0); bitStream.Write<uint16_t>(0);
bitStream.Write<uint8_t>(0); //not mythran nametag bitStream.Write<uint8_t>(0); //not mythran nametag
bitStream.Write(LUWString(otherName)); PacketUtils::WritePacketWString(otherName, 33, &bitStream);
bitStream.Write<uint8_t>(0); //not mythran for receiver bitStream.Write<uint8_t>(0); //not mythran for receiver
bitStream.Write<uint8_t>(0); //teams? bitStream.Write<uint8_t>(0); //teams?
bitStream.Write(LUWString(message, 512)); PacketUtils::WritePacketWString(message, 512, &bitStream);
SystemAddress sysAddr = otherMember->sysAddr; SystemAddress sysAddr = otherMember->sysAddr;
SEND_PACKET; SEND_PACKET;
@@ -440,7 +434,7 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) {
} }
void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
LWOOBJID senderID = PacketUtils::ReadS64(0x08, packet); LWOOBJID senderID = PacketUtils::ReadPacketS64(0x08, packet);
std::string receiverName = PacketUtils::ReadString(0x66, packet, true); std::string receiverName = PacketUtils::ReadString(0x66, packet, true);
std::string message = PacketUtils::ReadString(0xAA, packet, true, 512); std::string message = PacketUtils::ReadString(0xAA, packet, true, 512);
@@ -457,21 +451,21 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
//To the sender: //To the sender:
{ {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(goonA->playerID); bitStream.Write(goonA->playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
bitStream.Write(goonA->playerID); bitStream.Write(goonA->playerID);
bitStream.Write<uint8_t>(7); bitStream.Write<uint8_t>(7);
bitStream.Write<unsigned int>(69); bitStream.Write<unsigned int>(69);
bitStream.Write(LUWString(goonAName)); PacketUtils::WritePacketWString(goonAName, 33, &bitStream);
bitStream.Write(goonA->playerID); bitStream.Write(goonA->playerID);
bitStream.Write<uint16_t>(0); bitStream.Write<uint16_t>(0);
bitStream.Write<uint8_t>(0); //not mythran nametag bitStream.Write<uint8_t>(0); //not mythran nametag
bitStream.Write(LUWString(goonBName)); PacketUtils::WritePacketWString(goonBName, 33, &bitStream);
bitStream.Write<uint8_t>(0); //not mythran for receiver bitStream.Write<uint8_t>(0); //not mythran for receiver
bitStream.Write<uint8_t>(0); //success bitStream.Write<uint8_t>(0); //success
bitStream.Write(LUWString(message, 512)); PacketUtils::WritePacketWString(message, 512, &bitStream);
SystemAddress sysAddr = goonA->sysAddr; SystemAddress sysAddr = goonA->sysAddr;
SEND_PACKET; SEND_PACKET;
@@ -480,21 +474,21 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
//To the receiver: //To the receiver:
{ {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(goonB->playerID); bitStream.Write(goonB->playerID);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
bitStream.Write(goonA->playerID); bitStream.Write(goonA->playerID);
bitStream.Write<uint8_t>(7); bitStream.Write<uint8_t>(7);
bitStream.Write<unsigned int>(69); bitStream.Write<unsigned int>(69);
bitStream.Write(LUWString(goonAName)); PacketUtils::WritePacketWString(goonAName, 33, &bitStream);
bitStream.Write(goonA->playerID); bitStream.Write(goonA->playerID);
bitStream.Write<uint16_t>(0); bitStream.Write<uint16_t>(0);
bitStream.Write<uint8_t>(0); //not mythran nametag bitStream.Write<uint8_t>(0); //not mythran nametag
bitStream.Write(LUWString(goonBName)); PacketUtils::WritePacketWString(goonBName, 33, &bitStream);
bitStream.Write<uint8_t>(0); //not mythran for receiver bitStream.Write<uint8_t>(0); //not mythran for receiver
bitStream.Write<uint8_t>(3); //new whisper bitStream.Write<uint8_t>(3); //new whisper
bitStream.Write(LUWString(message, 512)); PacketUtils::WritePacketWString(message, 512, &bitStream);
SystemAddress sysAddr = goonB->sysAddr; SystemAddress sysAddr = goonB->sysAddr;
SEND_PACKET; SEND_PACKET;
@@ -532,13 +526,13 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
if (team->memberIDs.size() > 3) { if (team->memberIDs.size() > 3) {
// no more teams greater than 4 // no more teams greater than 4
LOG("Someone tried to invite a 5th player to a team"); Game::logger->Log("ChatPacketHandler", "Someone tried to invite a 5th player to a team");
return; return;
} }
SendTeamInvite(other, player); SendTeamInvite(other, player);
LOG("Got team invite: %llu -> %s", playerID, invitedPlayer.c_str()); Game::logger->Log("ChatPacketHandler", "Got team invite: %llu -> %s", playerID, invitedPlayer.c_str());
} }
void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) { void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) {
@@ -552,7 +546,7 @@ void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) {
LWOOBJID leaderID = LWOOBJID_EMPTY; LWOOBJID leaderID = LWOOBJID_EMPTY;
inStream.Read(leaderID); inStream.Read(leaderID);
LOG("Accepted invite: %llu -> %llu (%d)", playerID, leaderID, declined); Game::logger->Log("ChatPacketHandler", "Accepted invite: %llu -> %llu (%d)", playerID, leaderID, declined);
if (declined) { if (declined) {
return; return;
@@ -561,13 +555,13 @@ void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) {
auto* team = playerContainer.GetTeam(leaderID); auto* team = playerContainer.GetTeam(leaderID);
if (team == nullptr) { if (team == nullptr) {
LOG("Failed to find team for leader (%llu)", leaderID); Game::logger->Log("ChatPacketHandler", "Failed to find team for leader (%llu)", leaderID);
team = playerContainer.GetTeam(playerID); team = playerContainer.GetTeam(playerID);
} }
if (team == nullptr) { if (team == nullptr) {
LOG("Failed to find team for player (%llu)", playerID); Game::logger->Log("ChatPacketHandler", "Failed to find team for player (%llu)", playerID);
return; return;
} }
@@ -583,7 +577,7 @@ void ChatPacketHandler::HandleTeamLeave(Packet* packet) {
auto* team = playerContainer.GetTeam(playerID); auto* team = playerContainer.GetTeam(playerID);
LOG("(%llu) leaving team", playerID); Game::logger->Log("ChatPacketHandler", "(%llu) leaving team", playerID);
if (team != nullptr) { if (team != nullptr) {
playerContainer.RemoveMember(team, playerID, false, false, true); playerContainer.RemoveMember(team, playerID, false, false, true);
@@ -597,7 +591,7 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) {
std::string kickedPlayer = PacketUtils::ReadString(0x14, packet, true); std::string kickedPlayer = PacketUtils::ReadString(0x14, packet, true);
LOG("(%llu) kicking (%s) from team", playerID, kickedPlayer.c_str()); Game::logger->Log("ChatPacketHandler", "(%llu) kicking (%s) from team", playerID, kickedPlayer.c_str());
auto* kicked = playerContainer.GetPlayerData(kickedPlayer); auto* kicked = playerContainer.GetPlayerData(kickedPlayer);
@@ -627,7 +621,7 @@ void ChatPacketHandler::HandleTeamPromote(Packet* packet) {
std::string promotedPlayer = PacketUtils::ReadString(0x14, packet, true); std::string promotedPlayer = PacketUtils::ReadString(0x14, packet, true);
LOG("(%llu) promoting (%s) to team leader", playerID, promotedPlayer.c_str()); Game::logger->Log("ChatPacketHandler", "(%llu) promoting (%s) to team leader", playerID, promotedPlayer.c_str());
auto* promoted = playerContainer.GetPlayerData(promotedPlayer); auto* promoted = playerContainer.GetPlayerData(promotedPlayer);
@@ -715,13 +709,13 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) {
void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) { void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE); PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE);
bitStream.Write(LUWString(sender->playerName.c_str())); PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream);
bitStream.Write(sender->playerID); bitStream.Write(sender->playerID);
SystemAddress sysAddr = receiver->sysAddr; SystemAddress sysAddr = receiver->sysAddr;
@@ -730,7 +724,7 @@ void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender)
void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) { void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
@@ -757,7 +751,7 @@ void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeader
void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) { void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
@@ -782,7 +776,7 @@ void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderI
void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64PlayerID) { void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64PlayerID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
@@ -799,7 +793,7 @@ void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64Play
void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) { void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
@@ -828,7 +822,7 @@ void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTria
void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) { void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
@@ -854,7 +848,7 @@ void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband
void ChatPacketHandler::SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) { void ChatPacketHandler::SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
@@ -888,16 +882,16 @@ void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* pla
[bool] - is FTP*/ [bool] - is FTP*/
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(friendData->playerID); bitStream.Write(friendData->playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY); PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY);
bitStream.Write<uint8_t>(notifyType); bitStream.Write<uint8_t>(notifyType);
std::string playerName = playerData->playerName.c_str(); std::string playerName = playerData->playerName.c_str();
bitStream.Write(LUWString(playerName)); PacketUtils::WritePacketWString(playerName, 33, &bitStream);
bitStream.Write(playerData->zoneID.GetMapID()); bitStream.Write(playerData->zoneID.GetMapID());
bitStream.Write(playerData->zoneID.GetInstanceID()); bitStream.Write(playerData->zoneID.GetInstanceID());
@@ -927,12 +921,12 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send
} }
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST); PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST);
bitStream.Write(LUWString(sender->playerName.c_str())); PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream);
bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side. bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side.
SystemAddress sysAddr = receiver->sysAddr; SystemAddress sysAddr = receiver->sysAddr;
@@ -943,16 +937,16 @@ void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sen
if (!receiver || !sender) return; if (!receiver || !sender) return;
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
// Portion that will get routed: // Portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE); PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE);
bitStream.Write(responseCode); bitStream.Write(responseCode);
// For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver. // For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver.
bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS); bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS);
// Then write the player name // Then write the player name
bitStream.Write(LUWString(sender->playerName.c_str())); PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream);
// Then if this is an acceptance code, write the following extra info. // Then if this is an acceptance code, write the following extra info.
if (responseCode == eAddFriendResponseType::ACCEPTED) { if (responseCode == eAddFriendResponseType::ACCEPTED) {
bitStream.Write(sender->playerID); bitStream.Write(sender->playerID);
@@ -968,13 +962,13 @@ void ChatPacketHandler::SendRemoveFriend(PlayerData* receiver, std::string& pers
if (!receiver) return; if (!receiver) return;
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
bitStream.Write(receiver->playerID); bitStream.Write(receiver->playerID);
//portion that will get routed: //portion that will get routed:
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE); PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE);
bitStream.Write<uint8_t>(isSuccessful); //isOnline bitStream.Write<uint8_t>(isSuccessful); //isOnline
bitStream.Write(LUWString(personToRemove)); PacketUtils::WritePacketWString(personToRemove, 33, &bitStream);
SystemAddress sysAddr = receiver->sysAddr; SystemAddress sysAddr = receiver->sysAddr;
SEND_PACKET; SEND_PACKET;

View File

@@ -6,7 +6,7 @@
//DLU Includes: //DLU Includes:
#include "dCommonVars.h" #include "dCommonVars.h"
#include "dServer.h" #include "dServer.h"
#include "Logger.h" #include "dLogger.h"
#include "Database.h" #include "Database.h"
#include "dConfig.h" #include "dConfig.h"
#include "dChatFilter.h" #include "dChatFilter.h"
@@ -27,7 +27,7 @@
#include <MessageIdentifiers.h> #include <MessageIdentifiers.h>
namespace Game { namespace Game {
Logger* logger = nullptr; dLogger* logger = nullptr;
dServer* server = nullptr; dServer* server = nullptr;
dConfig* config = nullptr; dConfig* config = nullptr;
dChatFilter* chatFilter = nullptr; dChatFilter* chatFilter = nullptr;
@@ -37,7 +37,7 @@ namespace Game {
} }
Logger* SetupLogger(); dLogger* SetupLogger();
void HandlePacket(Packet* packet); void HandlePacket(Packet* packet);
PlayerContainer playerContainer; PlayerContainer playerContainer;
@@ -58,9 +58,9 @@ int main(int argc, char** argv) {
Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0");
Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1");
LOG("Starting Chat server..."); Game::logger->Log("ChatServer", "Starting Chat server...");
LOG("Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("ChatServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
LOG("Compiled on: %s", __TIMESTAMP__); Game::logger->Log("ChatServer", "Compiled on: %s", __TIMESTAMP__);
try { try {
std::string clientPathStr = Game::config->GetValue("client_location"); std::string clientPathStr = Game::config->GetValue("client_location");
@@ -72,7 +72,7 @@ int main(int argc, char** argv) {
Game::assetManager = new AssetManager(clientPath); Game::assetManager = new AssetManager(clientPath);
} catch (std::runtime_error& ex) { } catch (std::runtime_error& ex) {
LOG("Got an error while setting up assets: %s", ex.what()); Game::logger->Log("ChatServer", "Got an error while setting up assets: %s", ex.what());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -86,7 +86,7 @@ int main(int argc, char** argv) {
try { try {
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
} catch (sql::SQLException& ex) { } catch (sql::SQLException& ex) {
LOG("Got an error while connecting to the database: %s", ex.what()); Game::logger->Log("ChatServer", "Got an error while connecting to the database: %s", ex.what());
Database::Destroy("ChatServer"); Database::Destroy("ChatServer");
delete Game::server; delete Game::server;
delete Game::logger; delete Game::logger;
@@ -185,7 +185,7 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Logger* SetupLogger() { dLogger* SetupLogger() {
std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/ChatServer_" + std::to_string(time(nullptr)) + ".log")).string(); std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/ChatServer_" + std::to_string(time(nullptr)) + ".log")).string();
bool logToConsole = false; bool logToConsole = false;
bool logDebugStatements = false; bool logDebugStatements = false;
@@ -194,16 +194,16 @@ Logger* SetupLogger() {
logDebugStatements = true; logDebugStatements = true;
#endif #endif
return new Logger(logPath, logToConsole, logDebugStatements); return new dLogger(logPath, logToConsole, logDebugStatements);
} }
void HandlePacket(Packet* packet) { void HandlePacket(Packet* packet) {
if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) {
LOG("A server has disconnected, erasing their connected players from the list."); Game::logger->Log("ChatServer", "A server has disconnected, erasing their connected players from the list.");
} }
if (packet->data[0] == ID_NEW_INCOMING_CONNECTION) { if (packet->data[0] == ID_NEW_INCOMING_CONNECTION) {
LOG("A server is connecting, awaiting user list."); Game::logger->Log("ChatServer", "A server is connecting, awaiting user list.");
} }
if (packet->length < 4) return; // Nothing left to process. Need 4 bytes to continue. if (packet->length < 4) return; // Nothing left to process. Need 4 bytes to continue.
@@ -234,7 +234,7 @@ void HandlePacket(Packet* packet) {
} }
default: default:
LOG("Unknown CHAT_INTERNAL id: %i", int(packet->data[3])); Game::logger->Log("ChatServer", "Unknown CHAT_INTERNAL id: %i", int(packet->data[3]));
} }
} }
@@ -245,7 +245,7 @@ void HandlePacket(Packet* packet) {
break; break;
case eChatMessageType::GET_IGNORE_LIST: case eChatMessageType::GET_IGNORE_LIST:
LOG("Asked for ignore list, but is unimplemented right now."); Game::logger->Log("ChatServer", "Asked for ignore list, but is unimplemented right now.");
break; break;
case eChatMessageType::TEAM_GET_STATUS: case eChatMessageType::TEAM_GET_STATUS:
@@ -303,19 +303,19 @@ void HandlePacket(Packet* packet) {
break; break;
default: default:
LOG("Unknown CHAT id: %i", int(packet->data[3])); Game::logger->Log("ChatServer", "Unknown CHAT id: %i", int(packet->data[3]));
} }
} }
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::WORLD) { if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::WORLD) {
switch (static_cast<eWorldMessageType>(packet->data[3])) { switch (static_cast<eWorldMessageType>(packet->data[3])) {
case eWorldMessageType::ROUTE_PACKET: { case eWorldMessageType::ROUTE_PACKET: {
LOG("Routing packet from world"); Game::logger->Log("ChatServer", "Routing packet from world");
break; break;
} }
default: default:
LOG("Unknown World id: %i", int(packet->data[3])); Game::logger->Log("ChatServer", "Unknown World id: %i", int(packet->data[3]));
} }
} }
} }

View File

@@ -3,15 +3,13 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
#include "ChatPacketHandler.h" #include "ChatPacketHandler.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "BitStreamUtils.h" #include "PacketUtils.h"
#include "Database.h" #include "Database.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eChatInternalMessageType.h" #include "eChatInternalMessageType.h"
#include "ChatPackets.h"
#include "dConfig.h"
PlayerContainer::PlayerContainer() { PlayerContainer::PlayerContainer() {
} }
@@ -20,10 +18,6 @@ PlayerContainer::~PlayerContainer() {
mPlayers.clear(); mPlayers.clear();
} }
TeamData::TeamData() {
lootFlag = Game::config->GetValue("default_team_loot") == "0" ? 0 : 1;
}
void PlayerContainer::InsertPlayer(Packet* packet) { void PlayerContainer::InsertPlayer(Packet* packet) {
CINSTREAM_SKIP_HEADER; CINSTREAM_SKIP_HEADER;
PlayerData* data = new PlayerData(); PlayerData* data = new PlayerData();
@@ -44,7 +38,7 @@ void PlayerContainer::InsertPlayer(Packet* packet) {
mNames[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName); mNames[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName);
mPlayers.insert(std::make_pair(data->playerID, data)); mPlayers.insert(std::make_pair(data->playerID, data));
LOG("Added user: %s (%llu), zone: %i", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID()); Game::logger->Log("PlayerContainer", "Added user: %s (%llu), zone: %i", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID());
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);"); auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
@@ -87,7 +81,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
} }
} }
LOG("Removed user: %llu", playerID); Game::logger->Log("PlayerContainer", "Removed user: %llu", playerID);
mPlayers.erase(playerID); mPlayers.erase(playerID);
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);"); auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
@@ -110,7 +104,7 @@ void PlayerContainer::MuteUpdate(Packet* packet) {
auto* player = this->GetPlayerData(playerID); auto* player = this->GetPlayerData(playerID);
if (player == nullptr) { if (player == nullptr) {
LOG("Failed to find user: %llu", playerID); Game::logger->Log("PlayerContainer", "Failed to find user: %llu", playerID);
return; return;
} }
@@ -152,7 +146,7 @@ void PlayerContainer::CreateTeamServer(Packet* packet) {
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) { void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE);
bitStream.Write(player); bitStream.Write(player);
bitStream.Write(time); bitStream.Write(time);
@@ -213,14 +207,6 @@ TeamData* PlayerContainer::GetTeam(LWOOBJID playerID) {
} }
void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) { void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) {
if (team->memberIDs.size() >= 4){
LOG("Tried to add player to team that already had 4 players");
auto* player = GetPlayerData(playerID);
if (!player) return;
ChatPackets::SendSystemMessage(player->sysAddr, u"The teams is full! You have not been added to a team!");
return;
}
const auto index = std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID); const auto index = std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID);
if (index != team->memberIDs.end()) return; if (index != team->memberIDs.end()) return;
@@ -359,7 +345,7 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) {
void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) { void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::TEAM_UPDATE); PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::TEAM_UPDATE);
bitStream.Write(team->teamID); bitStream.Write(team->teamID);
bitStream.Write(deleteTeam); bitStream.Write(deleteTeam);

View File

@@ -18,7 +18,6 @@ struct PlayerData {
}; };
struct TeamData { struct TeamData {
TeamData();
LWOOBJID teamID = LWOOBJID_EMPTY; // Internal use LWOOBJID teamID = LWOOBJID_EMPTY; // Internal use
LWOOBJID leaderID = LWOOBJID_EMPTY; LWOOBJID leaderID = LWOOBJID_EMPTY;
std::vector<LWOOBJID> memberIDs{}; std::vector<LWOOBJID> memberIDs{};

View File

@@ -2,7 +2,7 @@
#define __AMF3__H__ #define __AMF3__H__
#include "dCommonVars.h" #include "dCommonVars.h"
#include "Logger.h" #include "dLogger.h"
#include "Game.h" #include "Game.h"
#include <unordered_map> #include <unordered_map>

View File

@@ -1,7 +1,7 @@
#include "AmfSerialize.h" #include "AmfSerialize.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
// Writes an AMFValue pointer to a RakNet::BitStream // Writes an AMFValue pointer to a RakNet::BitStream
template<> template<>
@@ -29,7 +29,7 @@ void RakNet::BitStream::Write<AMFBaseValue&>(AMFBaseValue& value) {
break; break;
} }
default: { default: {
LOG("Encountered unwritable AMFType %i!", type); Game::logger->Log("AmfSerialize", "Encountered unwritable AMFType %i!", type);
} }
case eAmf::Undefined: case eAmf::Undefined:
case eAmf::Null: case eAmf::Null:

View File

@@ -9,7 +9,7 @@
#include "Database.h" #include "Database.h"
#include "Game.h" #include "Game.h"
#include "ZCompression.h" #include "ZCompression.h"
#include "Logger.h" #include "dLogger.h"
//! Forward declarations //! Forward declarations
@@ -59,14 +59,14 @@ uint32_t BrickByBrickFix::TruncateBrokenBrickByBrickXml() {
completeUncompressedModel.append((char*)uncompressedChunk.get()); completeUncompressedModel.append((char*)uncompressedChunk.get());
completeUncompressedModel.resize(previousSize + actualUncompressedSize); completeUncompressedModel.resize(previousSize + actualUncompressedSize);
} else { } else {
LOG("Failed to inflate chunk %i for model %llu. Error: %i", chunkCount, modelId, err); Game::logger->Log("BrickByBrickFix", "Failed to inflate chunk %i for model %llu. Error: %i", chunkCount, modelId, err);
break; break;
} }
chunkCount++; chunkCount++;
} }
std::unique_ptr<tinyxml2::XMLDocument> document = std::make_unique<tinyxml2::XMLDocument>(); std::unique_ptr<tinyxml2::XMLDocument> document = std::make_unique<tinyxml2::XMLDocument>();
if (!document) { if (!document) {
LOG("Failed to initialize tinyxml document. Aborting."); Game::logger->Log("BrickByBrickFix", "Failed to initialize tinyxml document. Aborting.");
return 0; return 0;
} }
@@ -75,7 +75,8 @@ uint32_t BrickByBrickFix::TruncateBrokenBrickByBrickXml() {
"</LXFML>", "</LXFML>",
completeUncompressedModel.length() >= 15 ? completeUncompressedModel.length() - 15 : 0) == std::string::npos completeUncompressedModel.length() >= 15 ? completeUncompressedModel.length() - 15 : 0) == std::string::npos
) { ) {
LOG("Brick-by-brick model %llu will be deleted!", modelId); Game::logger->Log("BrickByBrickFix",
"Brick-by-brick model %llu will be deleted!", modelId);
ugcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1)); ugcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1));
pcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1)); pcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1));
ugcModelToDelete->execute(); ugcModelToDelete->execute();
@@ -84,7 +85,8 @@ uint32_t BrickByBrickFix::TruncateBrokenBrickByBrickXml() {
} }
} }
} else { } else {
LOG("Brick-by-brick model %llu will be deleted!", modelId); Game::logger->Log("BrickByBrickFix",
"Brick-by-brick model %llu will be deleted!", modelId);
ugcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1)); ugcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1));
pcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1)); pcModelToDelete->setInt64(1, modelsToTruncate->getInt64(1));
ugcModelToDelete->execute(); ugcModelToDelete->execute();
@@ -138,10 +140,12 @@ uint32_t BrickByBrickFix::UpdateBrickByBrickModelsToSd0() {
insertionStatement->setInt64(2, modelId); insertionStatement->setInt64(2, modelId);
try { try {
insertionStatement->executeUpdate(); insertionStatement->executeUpdate();
LOG("Updated model %i to sd0", modelId); Game::logger->Log("BrickByBrickFix", "Updated model %i to sd0", modelId);
updatedModels++; updatedModels++;
} catch (sql::SQLException exception) { } catch (sql::SQLException exception) {
LOG("Failed to update model %i. This model should be inspected manually to see why." Game::logger->Log(
"BrickByBrickFix",
"Failed to update model %i. This model should be inspected manually to see why."
"The database error is %s", modelId, exception.what()); "The database error is %s", modelId, exception.what());
} }
} }

View File

@@ -4,7 +4,7 @@ set(DCOMMON_SOURCES
"BinaryIO.cpp" "BinaryIO.cpp"
"dConfig.cpp" "dConfig.cpp"
"Diagnostics.cpp" "Diagnostics.cpp"
"Logger.cpp" "dLogger.cpp"
"GeneralUtils.cpp" "GeneralUtils.cpp"
"LDFFormat.cpp" "LDFFormat.cpp"
"MD5.cpp" "MD5.cpp"
@@ -12,7 +12,7 @@ set(DCOMMON_SOURCES
"NiPoint3.cpp" "NiPoint3.cpp"
"NiQuaternion.cpp" "NiQuaternion.cpp"
"SHA512.cpp" "SHA512.cpp"
"Demangler.cpp" "Type.cpp"
"ZCompression.cpp" "ZCompression.cpp"
"BrickByBrickFix.cpp" "BrickByBrickFix.cpp"
"BinaryPathFinder.cpp" "BinaryPathFinder.cpp"

View File

@@ -1,29 +0,0 @@
#include "Demangler.h"
#ifdef __GNUG__
#include <cstdlib>
#include <cxxabi.h>
#include <memory>
#include <typeinfo>
std::string Demangler::Demangle(const char* name) {
// some arbitrary value to eliminate the compiler warning
// -4 is not a valid return value for __cxa_demangle so we'll use that.
int status = -4;
// __cxa_demangle requires that we free the returned char*
std::unique_ptr<char, void (*)(void*)> res{
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status == 0) ? res.get() : "";
}
#else // __GNUG__
// does nothing if not g++
std::string Demangler::Demangle(const char* name) {
return name;
}
#endif // __GNUG__

View File

@@ -1,9 +0,0 @@
#pragma once
#include <string>
namespace Demangler {
// Given a char* containing a mangled name, return a std::string containing the demangled name.
// If the function fails for any reason, it returns an empty string.
std::string Demangle(const char* name);
}

View File

@@ -1,6 +1,6 @@
#include "Diagnostics.h" #include "Diagnostics.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
// If we're on Win32, we'll include our minidump writer // If we're on Win32, we'll include our minidump writer
#ifdef _WIN32 #ifdef _WIN32
@@ -9,7 +9,7 @@
#include <Dbghelp.h> #include <Dbghelp.h>
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
void make_minidump(EXCEPTION_POINTERS* e) { void make_minidump(EXCEPTION_POINTERS* e) {
auto hDbgHelp = LoadLibraryA("dbghelp"); auto hDbgHelp = LoadLibraryA("dbghelp");
@@ -28,7 +28,7 @@ void make_minidump(EXCEPTION_POINTERS* e) {
"_%4d%02d%02d_%02d%02d%02d.dmp", "_%4d%02d%02d_%02d%02d%02d.dmp",
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
} }
LOG("Creating crash dump %s", name); Game::logger->Log("Diagnostics", "Creating crash dump %s", name);
auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return; return;
@@ -83,7 +83,7 @@ struct bt_ctx {
static inline void Bt(struct backtrace_state* state) { static inline void Bt(struct backtrace_state* state) {
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log"; std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
LOG("backtrace is enabled, crash dump located at %s", fileName.c_str()); Game::logger->Log("Diagnostics", "backtrace is enabled, crash dump located at %s", fileName.c_str());
FILE* file = fopen(fileName.c_str(), "w+"); FILE* file = fopen(fileName.c_str(), "w+");
if (file != nullptr) { if (file != nullptr) {
backtrace_print(state, 2, file); backtrace_print(state, 2, file);
@@ -107,7 +107,7 @@ static void ErrorCallback(void* data, const char* msg, int errnum) {
} }
#endif #endif
#include "Demangler.h" #include "Type.h"
void GenerateDump() { void GenerateDump() {
std::string cmd = "sudo gcore " + std::to_string(getpid()); std::string cmd = "sudo gcore " + std::to_string(getpid());
@@ -118,56 +118,55 @@ void CatchUnhandled(int sig) {
#ifndef __include_backtrace__ #ifndef __include_backtrace__
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log"; std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
LOG("Encountered signal %i, creating crash dump %s", sig, fileName.c_str()); Game::logger->Log("Diagnostics", "Encountered signal %i, creating crash dump %s", sig, fileName.c_str());
if (Diagnostics::GetProduceMemoryDump()) { if (Diagnostics::GetProduceMemoryDump()) {
GenerateDump(); GenerateDump();
} }
constexpr uint8_t MaxStackTrace = 32;
void* array[MaxStackTrace]; void* array[10];
size_t size; size_t size;
// get void*'s for all entries on the stack // get void*'s for all entries on the stack
size = backtrace(array, MaxStackTrace); size = backtrace(array, 10);
# if defined(__GNUG__) #if defined(__GNUG__) and defined(__dynamic)
// Loop through the returned addresses, and get the symbols to be demangled // Loop through the returned addresses, and get the symbols to be demangled
char** strings = backtrace_symbols(array, size); char** strings = backtrace_symbols(array, size);
FILE* file = fopen(fileName.c_str(), "w+");
if (file != NULL) {
fprintf(file, "Error: signal %d:\n", sig);
}
// Print the stack trace // Print the stack trace
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' // Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' and extract the function name
// and extract '_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress' from it to be demangled into a proper name
std::string functionName = strings[i]; std::string functionName = strings[i];
std::string::size_type start = functionName.find('('); std::string::size_type start = functionName.find('(');
std::string::size_type end = functionName.find('+'); std::string::size_type end = functionName.find('+');
if (start != std::string::npos && end != std::string::npos) { if (start != std::string::npos && end != std::string::npos) {
std::string demangled = functionName.substr(start + 1, end - start - 1); std::string demangled = functionName.substr(start + 1, end - start - 1);
demangled = Demangler::Demangle(demangled.c_str()); demangled = demangle(functionName.c_str());
// If the demangled string is not empty, then we can replace the mangled string with the demangled one if (demangled.empty()) {
if (!demangled.empty()) { Game::logger->Log("Diagnostics", "[%02zu] %s", i, demangled.c_str());
demangled.push_back('('); } else {
demangled += functionName.substr(end); Game::logger->Log("Diagnostics", "[%02zu] %s", i, functionName.c_str());
functionName = demangled; }
} else {
Game::logger->Log("Diagnostics", "[%02zu] %s", i, functionName.c_str());
} }
} }
#else
LOG("[%02zu] %s", i, functionName.c_str());
if (file != NULL) {
fprintf(file, "[%02zu] %s\n", i, functionName.c_str());
}
}
# else // defined(__GNUG__)
backtrace_symbols_fd(array, size, STDOUT_FILENO); backtrace_symbols_fd(array, size, STDOUT_FILENO);
# endif // defined(__GNUG__) #endif
#else // __include_backtrace__ FILE* file = fopen(fileName.c_str(), "w+");
if (file != NULL) {
// print out all the frames to stderr
fprintf(file, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, fileno(file));
fclose(file);
}
#else
struct backtrace_state* state = backtrace_create_state( struct backtrace_state* state = backtrace_create_state(
Diagnostics::GetProcessFileName().c_str(), Diagnostics::GetProcessFileName().c_str(),
@@ -178,7 +177,7 @@ void CatchUnhandled(int sig) {
struct bt_ctx ctx = { state, 0 }; struct bt_ctx ctx = { state, 0 };
Bt(state); Bt(state);
#endif // __include_backtrace__ #endif
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@@ -9,7 +9,7 @@
#include "CDClientDatabase.h" #include "CDClientDatabase.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
#include "AssetManager.h" #include "AssetManager.h"
#include "eSqliteDataType.h" #include "eSqliteDataType.h"
@@ -44,7 +44,7 @@ bool FdbToSqlite::Convert::ConvertDatabase(AssetMemoryBuffer& buffer) {
CDClientDatabase::ExecuteQuery("COMMIT;"); CDClientDatabase::ExecuteQuery("COMMIT;");
} catch (CppSQLite3Exception& e) { } catch (CppSQLite3Exception& e) {
LOG("Encountered error %s converting FDB to SQLite", e.errorMessage()); Game::logger->Log("FdbToSqlite", "Encountered error %s converting FDB to SQLite", e.errorMessage());
return false; return false;
} }

View File

@@ -3,7 +3,7 @@
#include <random> #include <random>
class dServer; class dServer;
class Logger; class dLogger;
class InstanceManager; class InstanceManager;
class dChatFilter; class dChatFilter;
class dConfig; class dConfig;
@@ -14,7 +14,7 @@ class EntityManager;
class dZoneManager; class dZoneManager;
namespace Game { namespace Game {
extern Logger* logger; extern dLogger* logger;
extern dServer* server; extern dServer* server;
extern InstanceManager* im; extern InstanceManager* im;
extern dChatFilter* chatFilter; extern dChatFilter* chatFilter;

View File

@@ -13,7 +13,7 @@
#include "NiPoint3.h" #include "NiPoint3.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
enum eInventoryType : uint32_t; enum eInventoryType : uint32_t;
enum class eObjectBits : size_t; enum class eObjectBits : size_t;
@@ -126,11 +126,6 @@ namespace GeneralUtils {
template <typename T> template <typename T>
T Parse(const char* value); T Parse(const char* value);
template <>
inline bool Parse(const char* value) {
return std::stoi(value);
}
template <> template <>
inline int32_t Parse(const char* value) { inline int32_t Parse(const char* value) {
return std::stoi(value); return std::stoi(value);

View File

@@ -4,7 +4,7 @@
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
// C++ // C++
#include <string_view> #include <string_view>
@@ -48,7 +48,7 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
try { try {
type = static_cast<eLDFType>(strtol(ldfTypeAndValue.first.data(), &storage, 10)); type = static_cast<eLDFType>(strtol(ldfTypeAndValue.first.data(), &storage, 10));
} catch (std::exception) { } catch (std::exception) {
LOG("Attempted to process invalid ldf type (%s) from string (%s)", ldfTypeAndValue.first.data(), format.data()); Game::logger->Log("LDFFormat", "Attempted to process invalid ldf type (%s) from string (%s)", ldfTypeAndValue.first.data(), format.data());
return nullptr; return nullptr;
} }
@@ -61,33 +61,35 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} }
case LDF_TYPE_S32: { case LDF_TYPE_S32: {
int32_t data; try {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { int32_t data = static_cast<int32_t>(strtoul(ldfTypeAndValue.second.data(), &storage, 10));
LOG("Warning: Attempted to process invalid int32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); returnValue = new LDFData<int32_t>(key, data);
} catch (std::exception) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid int32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr; return nullptr;
} }
returnValue = new LDFData<int32_t>(key, data);
break; break;
} }
case LDF_TYPE_FLOAT: { case LDF_TYPE_FLOAT: {
float data; try {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { float data = strtof(ldfTypeAndValue.second.data(), &storage);
LOG("Warning: Attempted to process invalid float value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); returnValue = new LDFData<float>(key, data);
} catch (std::exception) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid float value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr; return nullptr;
} }
returnValue = new LDFData<float>(key, data);
break; break;
} }
case LDF_TYPE_DOUBLE: { case LDF_TYPE_DOUBLE: {
double data; try {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { double data = strtod(ldfTypeAndValue.second.data(), &storage);
LOG("Warning: Attempted to process invalid double value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); returnValue = new LDFData<double>(key, data);
} catch (std::exception) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid double value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr; return nullptr;
} }
returnValue = new LDFData<double>(key, data);
break; break;
} }
@@ -100,8 +102,10 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") { } else if (ldfTypeAndValue.second == "false") {
data = 0; data = 0;
} else { } else {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { try {
LOG("Warning: Attempted to process invalid uint32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); data = static_cast<uint32_t>(strtoul(ldfTypeAndValue.second.data(), &storage, 10));
} catch (std::exception) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid uint32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr; return nullptr;
} }
} }
@@ -118,8 +122,10 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") { } else if (ldfTypeAndValue.second == "false") {
data = false; data = false;
} else { } else {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { try {
LOG("Warning: Attempted to process invalid bool value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); data = static_cast<bool>(strtol(ldfTypeAndValue.second.data(), &storage, 10));
} catch (std::exception) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid bool value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr; return nullptr;
} }
} }
@@ -129,22 +135,24 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} }
case LDF_TYPE_U64: { case LDF_TYPE_U64: {
uint64_t data; try {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { uint64_t data = static_cast<uint64_t>(strtoull(ldfTypeAndValue.second.data(), &storage, 10));
LOG("Warning: Attempted to process invalid uint64 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); returnValue = new LDFData<uint64_t>(key, data);
} catch (std::exception) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid uint64 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr; return nullptr;
} }
returnValue = new LDFData<uint64_t>(key, data);
break; break;
} }
case LDF_TYPE_OBJID: { case LDF_TYPE_OBJID: {
LWOOBJID data; try {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { LWOOBJID data = static_cast<LWOOBJID>(strtoll(ldfTypeAndValue.second.data(), &storage, 10));
LOG("Warning: Attempted to process invalid LWOOBJID value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); returnValue = new LDFData<LWOOBJID>(key, data);
} catch (std::exception) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid LWOOBJID value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr; return nullptr;
} }
returnValue = new LDFData<LWOOBJID>(key, data);
break; break;
} }
@@ -155,12 +163,12 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} }
case LDF_TYPE_UNKNOWN: { case LDF_TYPE_UNKNOWN: {
LOG("Warning: Attempted to process invalid unknown value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid unknown value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
break; break;
} }
default: { default: {
LOG("Warning: Attempted to process invalid LDF type (%d) from string (%s)", type, format.data()); Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid LDF type (%d) from string (%s)", type, format.data());
break; break;
} }
} }

View File

@@ -1,96 +0,0 @@
#include "Logger.h"
#include <algorithm>
#include <ctime>
#include <filesystem>
#include <stdarg.h>
Writer::~Writer() {
// Dont try to close stdcout...
if (!m_Outfile || m_IsConsoleWriter) return;
fclose(m_Outfile);
m_Outfile = NULL;
}
void Writer::Log(const char* time, const char* message) {
if (!m_Outfile) return;
fputs(time, m_Outfile);
fputs(message, m_Outfile);
}
void Writer::Flush() {
if (!m_Outfile) return;
fflush(m_Outfile);
}
FileWriter::FileWriter(const char* outpath) {
m_Outfile = fopen(outpath, "wt");
if (!m_Outfile) printf("Couldn't open %s for writing!\n", outpath);
m_Outpath = outpath;
m_IsConsoleWriter = false;
}
ConsoleWriter::ConsoleWriter(bool enabled) {
m_Enabled = enabled;
m_Outfile = stdout;
m_IsConsoleWriter = true;
}
Logger::Logger(const std::string& outpath, bool logToConsole, bool logDebugStatements) {
m_logDebugStatements = logDebugStatements;
std::filesystem::path outpathPath(outpath);
if (!std::filesystem::exists(outpathPath.parent_path())) std::filesystem::create_directories(outpathPath.parent_path());
m_Writers.push_back(std::make_unique<FileWriter>(outpath));
m_Writers.push_back(std::make_unique<ConsoleWriter>(logToConsole));
}
void Logger::vLog(const char* format, va_list args) {
time_t t = time(NULL);
struct tm* time = localtime(&t);
char timeStr[70];
strftime(timeStr, sizeof(timeStr), "[%d-%m-%y %H:%M:%S ", time);
char message[2048];
vsnprintf(message, 2048, format, args);
for (const auto& writer : m_Writers) {
writer->Log(timeStr, message);
}
}
void Logger::Log(const char* className, const char* format, ...) {
va_list args;
std::string log = std::string(className) + "] " + std::string(format) + "\n";
va_start(args, format);
vLog(log.c_str(), args);
va_end(args);
}
void Logger::LogDebug(const char* className, const char* format, ...) {
if (!m_logDebugStatements) return;
va_list args;
std::string log = std::string(className) + "] " + std::string(format) + "\n";
va_start(args, format);
vLog(log.c_str(), args);
va_end(args);
}
void Logger::Flush() {
for (const auto& writer : m_Writers) {
writer->Flush();
}
}
void Logger::SetLogToConsole(bool logToConsole) {
for (const auto& writer : m_Writers) {
if (writer->IsConsoleWriter()) writer->SetEnabled(logToConsole);
}
}
bool Logger::GetLogToConsole() const {
bool toReturn = false;
for (const auto& writer : m_Writers) {
if (writer->IsConsoleWriter()) toReturn |= writer->GetEnabled();
}
return toReturn;
}

View File

@@ -1,89 +0,0 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#define STRINGIFY_IMPL(x) #x
#define STRINGIFY(x) STRINGIFY_IMPL(x)
#define GET_FILE_NAME(x, y) GetFileNameFromAbsolutePath(__FILE__ x y)
#define FILENAME_AND_LINE GET_FILE_NAME(":", STRINGIFY(__LINE__))
// Calculate the filename at compile time from the path.
// We just do this by scanning the path for the last '/' or '\' character and returning the string after it.
constexpr const char* GetFileNameFromAbsolutePath(const char* path) {
const char* file = path;
while (*path) {
char nextChar = *path++;
if (nextChar == '/' || nextChar == '\\') {
file = path;
}
}
return file;
}
// These have to have a constexpr variable to store the filename_and_line result in a local variable otherwise
// they will not be valid constexpr and will be evaluated at runtime instead of compile time!
// The full string is still stored in the binary, however the offset of the filename in the absolute paths
// is used in the instruction instead of the start of the absolute path.
#define LOG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->Log(str, message, ##__VA_ARGS__); } while(0)
#define LOG_DEBUG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->LogDebug(str, message, ##__VA_ARGS__); } while(0)
// Writer class for writing data to files.
class Writer {
public:
Writer(bool enabled = true) : m_Enabled(enabled) {};
virtual ~Writer();
virtual void Log(const char* time, const char* message);
virtual void Flush();
void SetEnabled(bool disabled) { m_Enabled = disabled; }
bool GetEnabled() const { return m_Enabled; }
bool IsConsoleWriter() { return m_IsConsoleWriter; }
public:
bool m_Enabled = true;
bool m_IsConsoleWriter = false;
FILE* m_Outfile;
};
// FileWriter class for writing data to a file on a disk.
class FileWriter : public Writer {
public:
FileWriter(const char* outpath);
FileWriter(const std::string& outpath) : FileWriter(outpath.c_str()) {};
private:
std::string m_Outpath;
};
// ConsoleWriter class for writing data to the console.
class ConsoleWriter : public Writer {
public:
ConsoleWriter(bool enabled);
};
class Logger {
public:
Logger() = delete;
Logger(const std::string& outpath, bool logToConsole, bool logDebugStatements);
void Log(const char* filenameAndLine, const char* format, ...);
void LogDebug(const char* filenameAndLine, const char* format, ...);
void Flush();
bool GetLogToConsole() const;
void SetLogToConsole(bool logToConsole);
void SetLogDebugStatements(bool logDebugStatements) { m_logDebugStatements = logDebugStatements; }
private:
void vLog(const char* format, va_list args);
bool m_logDebugStatements;
std::vector<std::unique_ptr<Writer>> m_Writers;
};

View File

@@ -136,13 +136,6 @@ NiPoint3& NiPoint3::operator+=(const NiPoint3& point) {
return *this; return *this;
} }
NiPoint3& NiPoint3::operator*=(const float scalar) {
this->x *= scalar;
this->y *= scalar;
this->z *= scalar;
return *this;
}
//! Operator for subtraction of vectors //! Operator for subtraction of vectors
NiPoint3 NiPoint3::operator-(const NiPoint3& point) const { NiPoint3 NiPoint3::operator-(const NiPoint3& point) const {
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z); return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);

View File

@@ -138,8 +138,6 @@ public:
//! Operator for addition of vectors //! Operator for addition of vectors
NiPoint3& operator+=(const NiPoint3& point); NiPoint3& operator+=(const NiPoint3& point);
NiPoint3& operator*=(const float scalar);
//! Operator for subtraction of vectors //! Operator for subtraction of vectors
NiPoint3 operator-(const NiPoint3& point) const; NiPoint3 operator-(const NiPoint3& point) const;

27
dCommon/Type.cpp Normal file
View File

@@ -0,0 +1,27 @@
#include "Type.h"
#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
std::string demangle(const char* name) {
int status = -4; // some arbitrary value to eliminate the compiler warning
// enable c++11 by passing the flag -std=c++11 to g++
std::unique_ptr<char, void(*)(void*)> res{
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status == 0) ? res.get() : name;
}
#else
// does nothing if not g++
std::string demangle(const char* name) {
return name;
}
#endif

12
dCommon/Type.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <string>
#include <typeinfo>
std::string demangle(const char* name);
template <class T>
std::string type(const T& t) {
return demangle(typeid(t).name());
}

View File

@@ -2,7 +2,7 @@
#include "AssetManager.h" #include "AssetManager.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
#include <zlib.h> #include <zlib.h>

View File

@@ -42,7 +42,7 @@ struct AssetMemoryBuffer : std::streambuf {
} }
void close() { void close() {
free(m_Base); delete m_Base;
} }
}; };

View File

@@ -3,7 +3,6 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <filesystem> #include <filesystem>
#include <fstream>
#pragma pack(push, 1) #pragma pack(push, 1)
struct PackRecord { struct PackRecord {

View File

@@ -1,7 +1,7 @@
#include "PackIndex.h" #include "PackIndex.h"
#include "BinaryIO.h" #include "BinaryIO.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "dLogger.h"
PackIndex::PackIndex(const std::filesystem::path& filePath) { PackIndex::PackIndex(const std::filesystem::path& filePath) {
m_FileStream = std::ifstream(filePath / "versions" / "primary.pki", std::ios::in | std::ios::binary); m_FileStream = std::ifstream(filePath / "versions" / "primary.pki", std::ios::in | std::ios::binary);
@@ -34,7 +34,7 @@ PackIndex::PackIndex(const std::filesystem::path& filePath) {
m_PackFileIndices.push_back(packFileIndex); m_PackFileIndices.push_back(packFileIndex);
} }
LOG("Loaded pack catalog with %i pack files and %i files", m_PackPaths.size(), m_PackFileIndices.size()); Game::logger->Log("PackIndex", "Loaded pack catalog with %i pack files and %i files", m_PackPaths.size(), m_PackFileIndices.size());
for (auto& item : m_PackPaths) { for (auto& item : m_PackPaths) {
std::replace(item.begin(), item.end(), '\\', '/'); std::replace(item.begin(), item.end(), '\\', '/');

View File

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

View File

@@ -1152,7 +1152,7 @@ enum class eGameMessageType : uint16_t {
COLLISION_POINT_REMOVED = 1269, COLLISION_POINT_REMOVED = 1269,
SET_ATTACHED = 1270, SET_ATTACHED = 1270,
SET_DESTROYABLE_MODEL_BRICKS = 1271, SET_DESTROYABLE_MODEL_BRICKS = 1271,
VEHICLE_SET_POWERSLIDE_LOCK_WHEELS = 1272, VEHICLE_SET_POWERSLIDE_LOCK_WHEELS = 1273,
VEHICLE_SET_WHEEL_LOCK_STATE = 1273, VEHICLE_SET_WHEEL_LOCK_STATE = 1273,
SHOW_HEALTH_BAR = 1274, SHOW_HEALTH_BAR = 1274,
GET_SHOWS_HEALTH_BAR = 1275, GET_SHOWS_HEALTH_BAR = 1275,

View File

@@ -27,6 +27,20 @@ enum class ePermissionMap : uint64_t {
* The character has restricted chat access, bit 6. * The character has restricted chat access, bit 6.
*/ */
RestrictedChatAccess = 0x1 << 6, RestrictedChatAccess = 0x1 << 6,
//
// Combined permissions
//
/**
* The character is marked as 'old', restricted from trade and mail.
*/
Old = RestrictedTradeAccess | RestrictedMailAccess,
/**
* The character is soft banned, restricted from trade, mail, and chat.
*/
SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess,
}; };
#endif //!__EPERMISSIONMAP__H__ #endif //!__EPERMISSIONMAP__H__

View File

@@ -101,7 +101,7 @@ enum class eReplicaComponentType : uint32_t {
TRADE, TRADE,
USER_CONTROL, USER_CONTROL,
IGNORE_LIST, IGNORE_LIST,
MULTI_ZONE_ENTRANCE, ROCKET_LAUNCH_LUP,
BUFF_REAL, // the real buff component, should just be name BUFF BUFF_REAL, // the real buff component, should just be name BUFF
INTERACTION_MANAGER, INTERACTION_MANAGER,
DONATION_VENDOR, DONATION_VENDOR,

110
dCommon/dLogger.cpp Normal file
View File

@@ -0,0 +1,110 @@
#include "dLogger.h"
dLogger::dLogger(const std::string& outpath, bool logToConsole, bool logDebugStatements) {
m_logToConsole = logToConsole;
m_logDebugStatements = logDebugStatements;
m_outpath = outpath;
#ifdef _WIN32
mFile = std::ofstream(m_outpath);
if (!mFile) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
#else
fp = fopen(outpath.c_str(), "wt");
if (fp == NULL) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
#endif
}
dLogger::~dLogger() {
#ifdef _WIN32
mFile.close();
#else
if (fp != nullptr) {
fclose(fp);
fp = nullptr;
}
#endif
}
void dLogger::vLog(const char* format, va_list args) {
#ifdef _WIN32
time_t t = time(NULL);
struct tm time;
localtime_s(&time, &t);
char timeStr[70];
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time);
char message[2048];
vsnprintf(message, 2048, format, args);
if (m_logToConsole) std::cout << "[" << timeStr << "] " << message;
mFile << "[" << timeStr << "] " << message;
#else
time_t t = time(NULL);
struct tm* time = localtime(&t);
char timeStr[70];
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", time);
char message[2048];
vsnprintf(message, 2048, format, args);
if (m_logToConsole) {
fputs("[", stdout);
fputs(timeStr, stdout);
fputs("] ", stdout);
fputs(message, stdout);
}
if (fp != nullptr) {
fputs("[", fp);
fputs(timeStr, fp);
fputs("] ", fp);
fputs(message, fp);
} else {
printf("Logger not initialized!\n");
}
#endif
}
void dLogger::LogBasic(const char* format, ...) {
va_list args;
va_start(args, format);
vLog(format, args);
va_end(args);
}
void dLogger::LogBasic(const std::string& message) {
LogBasic(message.c_str());
}
void dLogger::Log(const char* className, const char* format, ...) {
va_list args;
std::string log = "[" + std::string(className) + "] " + std::string(format) + "\n";
va_start(args, format);
vLog(log.c_str(), args);
va_end(args);
}
void dLogger::Log(const std::string& className, const std::string& message) {
Log(className.c_str(), message.c_str());
}
void dLogger::LogDebug(const char* className, const char* format, ...) {
if (!m_logDebugStatements) return;
va_list args;
std::string log = "[" + std::string(className) + "] " + std::string(format) + "\n";
va_start(args, format);
vLog(log.c_str(), args);
va_end(args);
}
void dLogger::LogDebug(const std::string& className, const std::string& message) {
LogDebug(className.c_str(), message.c_str());
}
void dLogger::Flush() {
#ifdef _WIN32
mFile.flush();
#else
if (fp != nullptr) {
std::fflush(fp);
}
#endif
}

38
dCommon/dLogger.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <ctime>
#include <cstdarg>
#include <string>
#include <fstream>
#include <iostream>
class dLogger {
public:
dLogger(const std::string& outpath, bool logToConsole, bool logDebugStatements);
~dLogger();
void SetLogToConsole(bool logToConsole) { m_logToConsole = logToConsole; }
void SetLogDebugStatements(bool logDebugStatements) { m_logDebugStatements = logDebugStatements; }
void vLog(const char* format, va_list args);
void LogBasic(const std::string& message);
void LogBasic(const char* format, ...);
void Log(const char* className, const char* format, ...);
void Log(const std::string& className, const std::string& message);
void LogDebug(const std::string& className, const std::string& message);
void LogDebug(const char* className, const char* format, ...);
void Flush();
const bool GetIsLoggingToConsole() const { return m_logToConsole; }
private:
bool m_logDebugStatements;
bool m_logToConsole;
std::string m_outpath;
std::ofstream mFile;
#ifndef _WIN32
//Glorious linux can run with SPEED:
FILE* fp = nullptr;
#endif
};

View File

@@ -13,6 +13,14 @@
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
// Enable this to cache all entries in each table for fast access, comes with more memory cost
//#define CDCLIENT_CACHE_ALL
/*!
\file CDClientDatabase.hpp
\brief An interface between the CDClient.sqlite file and the server
*/
//! The CDClient Database namespace //! The CDClient Database namespace
namespace CDClientDatabase { namespace CDClientDatabase {

View File

@@ -38,53 +38,43 @@
#include "CDFeatureGatingTable.h" #include "CDFeatureGatingTable.h"
#include "CDRailActivatorComponent.h" #include "CDRailActivatorComponent.h"
// Uncomment this to cache the full cdclient database into memory. This will make the server load faster, but will use more memory.
// A vanilla CDClient takes about 46MB of memory + the regular world data.
// #define CDCLIENT_CACHE_ALL
#ifdef CDCLIENT_CACHE_ALL
#define CDCLIENT_DONT_CACHE_TABLE(x) x
#else
#define CDCLIENT_DONT_CACHE_TABLE(x)
#endif
CDClientManager::CDClientManager() { CDClientManager::CDClientManager() {
CDActivityRewardsTable::Instance().LoadValuesFromDatabase(); CDActivityRewardsTable::Instance();
CDActivitiesTable::Instance().LoadValuesFromDatabase(); CDAnimationsTable::Instance();
CDCLIENT_DONT_CACHE_TABLE(CDAnimationsTable::Instance().LoadValuesFromDatabase()); CDBehaviorParameterTable::Instance();
CDBehaviorParameterTable::Instance().LoadValuesFromDatabase(); CDBehaviorTemplateTable::Instance();
CDBehaviorTemplateTable::Instance().LoadValuesFromDatabase(); CDComponentsRegistryTable::Instance();
CDBrickIDTableTable::Instance().LoadValuesFromDatabase(); CDCurrencyTableTable::Instance();
CDCLIENT_DONT_CACHE_TABLE(CDComponentsRegistryTable::Instance().LoadValuesFromDatabase()); CDDestructibleComponentTable::Instance();
CDCurrencyTableTable::Instance().LoadValuesFromDatabase(); CDEmoteTableTable::Instance();
CDDestructibleComponentTable::Instance().LoadValuesFromDatabase(); CDInventoryComponentTable::Instance();
CDEmoteTableTable::Instance().LoadValuesFromDatabase(); CDItemComponentTable::Instance();
CDFeatureGatingTable::Instance().LoadValuesFromDatabase(); CDItemSetsTable::Instance();
CDInventoryComponentTable::Instance().LoadValuesFromDatabase(); CDItemSetSkillsTable::Instance();
CDCLIENT_DONT_CACHE_TABLE(CDItemComponentTable::Instance().LoadValuesFromDatabase()); CDLevelProgressionLookupTable::Instance();
CDItemSetSkillsTable::Instance().LoadValuesFromDatabase(); CDLootMatrixTable::Instance();
CDItemSetsTable::Instance().LoadValuesFromDatabase(); CDLootTableTable::Instance();
CDLevelProgressionLookupTable::Instance().LoadValuesFromDatabase(); CDMissionNPCComponentTable::Instance();
CDCLIENT_DONT_CACHE_TABLE(CDLootMatrixTable::Instance().LoadValuesFromDatabase()); CDMissionTasksTable::Instance();
CDCLIENT_DONT_CACHE_TABLE(CDLootTableTable::Instance().LoadValuesFromDatabase()); CDMissionsTable::Instance();
CDMissionEmailTable::Instance().LoadValuesFromDatabase(); CDObjectSkillsTable::Instance();
CDMissionNPCComponentTable::Instance().LoadValuesFromDatabase(); CDObjectsTable::Instance();
CDMissionTasksTable::Instance().LoadValuesFromDatabase(); CDPhysicsComponentTable::Instance();
CDMissionsTable::Instance().LoadValuesFromDatabase(); CDRebuildComponentTable::Instance();
CDMovementAIComponentTable::Instance().LoadValuesFromDatabase(); CDScriptComponentTable::Instance();
CDObjectSkillsTable::Instance().LoadValuesFromDatabase(); CDSkillBehaviorTable::Instance();
CDCLIENT_DONT_CACHE_TABLE(CDObjectsTable::Instance().LoadValuesFromDatabase()); CDZoneTableTable::Instance();
CDPhysicsComponentTable::Instance().LoadValuesFromDatabase(); CDVendorComponentTable::Instance();
CDPackageComponentTable::Instance().LoadValuesFromDatabase(); CDActivitiesTable::Instance();
CDProximityMonitorComponentTable::Instance().LoadValuesFromDatabase(); CDPackageComponentTable::Instance();
CDPropertyEntranceComponentTable::Instance().LoadValuesFromDatabase(); CDProximityMonitorComponentTable::Instance();
CDPropertyTemplateTable::Instance().LoadValuesFromDatabase(); CDMovementAIComponentTable::Instance();
CDRailActivatorComponentTable::Instance().LoadValuesFromDatabase(); CDBrickIDTableTable::Instance();
CDRarityTableTable::Instance().LoadValuesFromDatabase(); CDRarityTableTable::Instance();
CDRebuildComponentTable::Instance().LoadValuesFromDatabase(); CDMissionEmailTable::Instance();
CDRewardsTable::Instance().LoadValuesFromDatabase(); CDRewardsTable::Instance();
CDScriptComponentTable::Instance().LoadValuesFromDatabase(); CDPropertyEntranceComponentTable::Instance();
CDSkillBehaviorTable::Instance().LoadValuesFromDatabase(); CDPropertyTemplateTable::Instance();
CDVendorComponentTable::Instance().LoadValuesFromDatabase(); CDFeatureGatingTable::Instance();
CDZoneTableTable::Instance().LoadValuesFromDatabase(); CDRailActivatorComponentTable::Instance();
} }

View File

@@ -1,7 +1,7 @@
#include "Database.h" #include "Database.h"
#include "Game.h" #include "Game.h"
#include "dConfig.h" #include "dConfig.h"
#include "Logger.h" #include "dLogger.h"
using namespace std; using namespace std;
#pragma warning (disable:4251) //Disables SQL warnings #pragma warning (disable:4251) //Disables SQL warnings
@@ -64,8 +64,8 @@ void Database::Destroy(std::string source, bool log) {
if (!con) return; if (!con) return;
if (log) { if (log) {
if (source != "") LOG("Destroying MySQL connection from %s!", source.c_str()); if (source != "") Game::logger->Log("Database", "Destroying MySQL connection from %s!", source.c_str());
else LOG("Destroying MySQL connection!"); else Game::logger->Log("Database", "Destroying MySQL connection!");
} }
con->close(); con->close();
@@ -84,7 +84,7 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) {
if (!con) { if (!con) {
Connect(); Connect();
LOG("Trying to reconnect to MySQL"); Game::logger->Log("Database", "Trying to reconnect to MySQL");
} }
if (!con->isValid() || con->isClosed()) { if (!con->isValid() || con->isClosed()) {
@@ -93,7 +93,7 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) {
con = nullptr; con = nullptr;
Connect(); Connect();
LOG("Trying to reconnect to MySQL from invalid or closed connection"); Game::logger->Log("Database", "Trying to reconnect to MySQL from invalid or closed connection");
} }
auto* stmt = con->prepareStatement(str); auto* stmt = con->prepareStatement(str);

View File

@@ -5,10 +5,10 @@
#include "Database.h" #include "Database.h"
#include "Game.h" #include "Game.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "Logger.h" #include "dLogger.h"
#include "BinaryPathFinder.h" #include "BinaryPathFinder.h"
#include <fstream> #include <istream>
Migration LoadMigration(std::string path) { Migration LoadMigration(std::string path) {
Migration migration{}; Migration migration{};
@@ -53,7 +53,7 @@ void MigrationRunner::RunMigrations() {
delete stmt; delete stmt;
if (doExit) continue; if (doExit) continue;
LOG("Running migration: %s", migration.name.c_str()); Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str());
if (migration.name == "dlu/5_brick_model_sd0.sql") { if (migration.name == "dlu/5_brick_model_sd0.sql") {
runSd0Migrations = true; runSd0Migrations = true;
} else { } else {
@@ -67,7 +67,7 @@ void MigrationRunner::RunMigrations() {
} }
if (finalSQL.empty() && !runSd0Migrations) { if (finalSQL.empty() && !runSd0Migrations) {
LOG("Server database is up to date."); Game::logger->Log("MigrationRunner", "Server database is up to date.");
return; return;
} }
@@ -79,7 +79,7 @@ void MigrationRunner::RunMigrations() {
if (query.empty()) continue; if (query.empty()) continue;
simpleStatement->execute(query.c_str()); simpleStatement->execute(query.c_str());
} catch (sql::SQLException& e) { } catch (sql::SQLException& e) {
LOG("Encountered error running migration: %s", e.what()); Game::logger->Log("MigrationRunner", "Encountered error running migration: %s", e.what());
} }
} }
} }
@@ -87,9 +87,9 @@ void MigrationRunner::RunMigrations() {
// Do this last on the off chance none of the other migrations have been run yet. // Do this last on the off chance none of the other migrations have been run yet.
if (runSd0Migrations) { if (runSd0Migrations) {
uint32_t numberOfUpdatedModels = BrickByBrickFix::UpdateBrickByBrickModelsToSd0(); uint32_t numberOfUpdatedModels = BrickByBrickFix::UpdateBrickByBrickModelsToSd0();
LOG("%i models were updated from zlib to sd0.", numberOfUpdatedModels); Game::logger->Log("MasterServer", "%i models were updated from zlib to sd0.", numberOfUpdatedModels);
uint32_t numberOfTruncatedModels = BrickByBrickFix::TruncateBrokenBrickByBrickXml(); uint32_t numberOfTruncatedModels = BrickByBrickFix::TruncateBrokenBrickByBrickXml();
LOG("%i models were truncated from the database.", numberOfTruncatedModels); Game::logger->Log("MasterServer", "%i models were truncated from the database.", numberOfTruncatedModels);
} }
} }
@@ -135,14 +135,14 @@ void MigrationRunner::RunSQLiteMigrations() {
// Doing these 1 migration at a time since one takes a long time and some may think it is crashing. // Doing these 1 migration at a time since one takes a long time and some may think it is crashing.
// This will at the least guarentee that the full migration needs to be run in order to be counted as "migrated". // This will at the least guarentee that the full migration needs to be run in order to be counted as "migrated".
LOG("Executing migration: %s. This may take a while. Do not shut down server.", migration.name.c_str()); Game::logger->Log("MigrationRunner", "Executing migration: %s. This may take a while. Do not shut down server.", migration.name.c_str());
CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;"); CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
for (const auto& dml : GeneralUtils::SplitString(migration.data, ';')) { for (const auto& dml : GeneralUtils::SplitString(migration.data, ';')) {
if (dml.empty()) continue; if (dml.empty()) continue;
try { try {
CDClientDatabase::ExecuteDML(dml.c_str()); CDClientDatabase::ExecuteDML(dml.c_str());
} catch (CppSQLite3Exception& e) { } catch (CppSQLite3Exception& e) {
LOG("Encountered error running DML command: (%i) : %s", e.errorCode(), e.errorMessage()); Game::logger->Log("MigrationRunner", "Encountered error running DML command: (%i) : %s", e.errorCode(), e.errorMessage());
} }
} }
@@ -154,5 +154,5 @@ void MigrationRunner::RunSQLiteMigrations() {
CDClientDatabase::ExecuteQuery("COMMIT;"); CDClientDatabase::ExecuteQuery("COMMIT;");
} }
LOG("CDServer database is up to date."); Game::logger->Log("MigrationRunner", "CDServer database is up to date.");
} }

View File

@@ -1,6 +1,7 @@
#include "CDActivitiesTable.h" #include "CDActivitiesTable.h"
void CDActivitiesTable::LoadValuesFromDatabase() { CDActivitiesTable::CDActivitiesTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Activities"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Activities");
@@ -54,3 +55,8 @@ std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActiviti
return data; return data;
} }
std::vector<CDActivities> CDActivitiesTable::GetEntries(void) const {
return this->entries;
}

View File

@@ -30,10 +30,9 @@ private:
std::vector<CDActivities> entries; std::vector<CDActivities> entries;
public: public:
void LoadValuesFromDatabase(); CDActivitiesTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDActivities> Query(std::function<bool(CDActivities)> predicate); std::vector<CDActivities> Query(std::function<bool(CDActivities)> predicate);
const std::vector<CDActivities>& GetEntries() const { return this->entries; } std::vector<CDActivities> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,6 @@
#include "CDActivityRewardsTable.h" #include "CDActivityRewardsTable.h"
void CDActivityRewardsTable::LoadValuesFromDatabase() { CDActivityRewardsTable::CDActivityRewardsTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -43,3 +43,8 @@ std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool(
return data; return data;
} }
std::vector<CDActivityRewards> CDActivityRewardsTable::GetEntries(void) const {
return this->entries;
}

View File

@@ -18,10 +18,10 @@ private:
std::vector<CDActivityRewards> entries; std::vector<CDActivityRewards> entries;
public: public:
void LoadValuesFromDatabase(); CDActivityRewardsTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate); std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate);
std::vector<CDActivityRewards> GetEntries() const; std::vector<CDActivityRewards> GetEntries(void) const;
}; };

View File

@@ -2,35 +2,6 @@
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "Game.h" #include "Game.h"
void CDAnimationsTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
while (!tableData.eof()) {
std::string animation_type = tableData.getStringField("animation_type", "");
DluAssert(!animation_type.empty());
AnimationGroupID animationGroupID = tableData.getIntField("animationGroupID", -1);
DluAssert(animationGroupID != -1);
CDAnimation entry;
entry.animation_name = tableData.getStringField("animation_name", "");
entry.chance_to_play = tableData.getFloatField("chance_to_play", 1.0f);
UNUSED_COLUMN(entry.min_loops = tableData.getIntField("min_loops", 0);)
UNUSED_COLUMN(entry.max_loops = tableData.getIntField("max_loops", 0);)
entry.animation_length = tableData.getFloatField("animation_length", 0.0f);
UNUSED_COLUMN(entry.hideEquip = tableData.getIntField("hideEquip", 0) == 1;)
UNUSED_COLUMN(entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", 0) == 1;)
UNUSED_COLUMN(entry.restartable = tableData.getIntField("restartable", 0) == 1;)
UNUSED_COLUMN(entry.face_animation_name = tableData.getStringField("face_animation_name", "");)
UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);)
UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);)
this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
tableData.nextRow();
}
tableData.finalize();
}
bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) { bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) {
auto tableData = queryToCache.execQuery(); auto tableData = queryToCache.execQuery();
// If we received a bad lookup, cache it anyways so we do not run the query again. // If we received a bad lookup, cache it anyways so we do not run the query again.

View File

@@ -27,7 +27,6 @@ class CDAnimationsTable : public CDTable<CDAnimationsTable> {
typedef std::string AnimationID; typedef std::string AnimationID;
typedef std::pair<std::string, AnimationGroupID> CDAnimationKey; typedef std::pair<std::string, AnimationGroupID> CDAnimationKey;
public: public:
void LoadValuesFromDatabase();
/** /**
* Given an animationType and the previousAnimationName played, return the next animationType to play. * Given an animationType and the previousAnimationName played, return the next animationType to play.
* If there are more than 1 animationTypes that can be played, one is selected at random but also does not allow * If there are more than 1 animationTypes that can be played, one is selected at random but also does not allow

View File

@@ -1,15 +1,15 @@
#include "CDBehaviorParameterTable.h" #include "CDBehaviorParameterTable.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
uint64_t GetKey(const uint32_t behaviorID, const uint32_t parameterID) { uint64_t GetHash(const uint32_t behaviorID, const uint32_t parameterID) {
uint64_t key = behaviorID; uint64_t hash = behaviorID;
key <<= 31U; hash <<= 31U;
key |= parameterID; hash |= parameterID;
return key; return hash;
} }
void CDBehaviorParameterTable::LoadValuesFromDatabase() { CDBehaviorParameterTable::CDBehaviorParameterTable() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
while (!tableData.eof()) { while (!tableData.eof()) {
uint32_t behaviorID = tableData.getIntField("behaviorID", -1); uint32_t behaviorID = tableData.getIntField("behaviorID", -1);
@@ -21,7 +21,7 @@ void CDBehaviorParameterTable::LoadValuesFromDatabase() {
} else { } else {
parameterId = m_ParametersList.insert(std::make_pair(candidateStringToAdd, m_ParametersList.size())).first->second; parameterId = m_ParametersList.insert(std::make_pair(candidateStringToAdd, m_ParametersList.size())).first->second;
} }
uint64_t hash = GetKey(behaviorID, parameterId); uint64_t hash = GetHash(behaviorID, parameterId);
float value = tableData.getFloatField("value", -1.0f); float value = tableData.getFloatField("value", -1.0f);
m_Entries.insert(std::make_pair(hash, value)); m_Entries.insert(std::make_pair(hash, value));
@@ -34,7 +34,7 @@ void CDBehaviorParameterTable::LoadValuesFromDatabase() {
float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) { float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
auto parameterID = this->m_ParametersList.find(name); auto parameterID = this->m_ParametersList.find(name);
if (parameterID == this->m_ParametersList.end()) return defaultValue; if (parameterID == this->m_ParametersList.end()) return defaultValue;
auto hash = GetKey(behaviorID, parameterID->second); auto hash = GetHash(behaviorID, parameterID->second);
// Search for specific parameter // Search for specific parameter
auto it = m_Entries.find(hash); auto it = m_Entries.find(hash);
@@ -45,7 +45,7 @@ std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID
uint64_t hashBase = behaviorID; uint64_t hashBase = behaviorID;
std::map<std::string, float> returnInfo; std::map<std::string, float> returnInfo;
for (auto& [parameterString, parameterId] : m_ParametersList) { for (auto& [parameterString, parameterId] : m_ParametersList) {
uint64_t hash = GetKey(hashBase, parameterId); uint64_t hash = GetHash(hashBase, parameterId);
auto infoCandidate = m_Entries.find(hash); auto infoCandidate = m_Entries.find(hash);
if (infoCandidate != m_Entries.end()) { if (infoCandidate != m_Entries.end()) {
returnInfo.insert(std::make_pair(parameterString, infoCandidate->second)); returnInfo.insert(std::make_pair(parameterString, infoCandidate->second));

View File

@@ -12,7 +12,7 @@ private:
std::unordered_map<BehaviorParameterHash, BehaviorParameterValue> m_Entries; std::unordered_map<BehaviorParameterHash, BehaviorParameterValue> m_Entries;
std::unordered_map<std::string, uint32_t> m_ParametersList; std::unordered_map<std::string, uint32_t> m_ParametersList;
public: public:
void LoadValuesFromDatabase(); CDBehaviorParameterTable();
float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0);

View File

@@ -1,6 +1,6 @@
#include "CDBehaviorTemplateTable.h" #include "CDBehaviorTemplateTable.h"
void CDBehaviorTemplateTable::LoadValuesFromDatabase() { CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -48,7 +48,7 @@ std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::Query(std::function<boo
return data; return data;
} }
const std::vector<CDBehaviorTemplate>& CDBehaviorTemplateTable::GetEntries() const { std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::GetEntries(void) const {
return this->entries; return this->entries;
} }
@@ -64,3 +64,4 @@ const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behav
return entry->second; return entry->second;
} }
} }

View File

@@ -19,12 +19,11 @@ private:
std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID; std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID;
std::unordered_set<std::string> m_EffectHandles; std::unordered_set<std::string> m_EffectHandles;
public: public:
void LoadValuesFromDatabase(); CDBehaviorTemplateTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate); std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate);
const std::vector<CDBehaviorTemplate>& GetEntries(void) const; std::vector<CDBehaviorTemplate> GetEntries(void) const;
const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID); const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID);
}; };

View File

@@ -1,6 +1,6 @@
#include "CDBrickIDTableTable.h" #include "CDBrickIDTableTable.h"
void CDBrickIDTableTable::LoadValuesFromDatabase() { CDBrickIDTableTable::CDBrickIDTableTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -39,7 +39,7 @@ std::vector<CDBrickIDTable> CDBrickIDTableTable::Query(std::function<bool(CDBric
return data; return data;
} }
const std::vector<CDBrickIDTable>& CDBrickIDTableTable::GetEntries() const { std::vector<CDBrickIDTable> CDBrickIDTableTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -21,9 +21,9 @@ private:
std::vector<CDBrickIDTable> entries; std::vector<CDBrickIDTable> entries;
public: public:
void LoadValuesFromDatabase(); CDBrickIDTableTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDBrickIDTable> Query(std::function<bool(CDBrickIDTable)> predicate); std::vector<CDBrickIDTable> Query(std::function<bool(CDBrickIDTable)> predicate);
const std::vector<CDBrickIDTable>& GetEntries() const; std::vector<CDBrickIDTable> GetEntries(void) const;
}; };

View File

@@ -1,7 +1,25 @@
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
void CDComponentsRegistryTable::LoadValuesFromDatabase() { #define CDCLIENT_CACHE_ALL
CDComponentsRegistryTable::CDComponentsRegistryTable(void) {
#ifdef CDCLIENT_CACHE_ALL
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ComponentsRegistry");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
//this->entries.reserve(size);
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry");
while (!tableData.eof()) { while (!tableData.eof()) {
@@ -11,42 +29,65 @@ void CDComponentsRegistryTable::LoadValuesFromDatabase() {
entry.component_id = tableData.getIntField("component_id", -1); entry.component_id = tableData.getIntField("component_id", -1);
this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id); this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id);
this->mappedEntries.insert_or_assign(entry.id, 0);
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize(); tableData.finalize();
#endif
} }
int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) { int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) {
auto exists = mappedEntries.find(id); const auto& iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id));
if (exists != mappedEntries.end()) {
auto iter = mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); if (iter == this->mappedEntries.end()) {
return iter == mappedEntries.end() ? defaultValue : iter->second; return defaultValue;
} }
// Now get the data. Get all components of this entity so we dont do a query for each component return iter->second;
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM ComponentsRegistry WHERE id = ?;");
query.bind(1, static_cast<int32_t>(id));
auto tableData = query.execQuery(); #ifndef CDCLIENT_CACHE_ALL
// Now get the data
std::stringstream query;
query << "SELECT * FROM ComponentsRegistry WHERE id = " << std::to_string(id);
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
while (!tableData.eof()) { while (!tableData.eof()) {
CDComponentsRegistry entry; CDComponentsRegistry entry;
entry.id = tableData.getIntField("id", -1); entry.id = tableData.getIntField("id", -1);
entry.component_type = static_cast<eReplicaComponentType>(tableData.getIntField("component_type", 0)); entry.component_type = tableData.getIntField("component_type", -1);
entry.component_id = tableData.getIntField("component_id", -1); entry.component_id = tableData.getIntField("component_id", -1);
this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id); //this->entries.push_back(entry);
//Darwin's stuff:
const auto& it = this->mappedEntries.find(entry.id);
if (it != mappedEntries.end()) {
const auto& iter = it->second.find(entry.component_type);
if (iter == it->second.end()) {
it->second.insert(std::make_pair(entry.component_type, entry.component_id));
}
} else {
std::map<unsigned int, unsigned int> map;
map.insert(std::make_pair(entry.component_type, entry.component_id));
this->mappedEntries.insert(std::make_pair(entry.id, map));
}
tableData.nextRow(); tableData.nextRow();
} }
mappedEntries.insert_or_assign(id, 0); tableData.finalize();
auto iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); const auto& it2 = this->mappedEntries.find(id);
if (it2 != mappedEntries.end()) {
return iter == this->mappedEntries.end() ? defaultValue : iter->second; const auto& iter = it2->second.find(componentType);
if (iter != it2->second.end()) {
return iter->second;
}
}
return defaultValue;
#endif
} }

View File

@@ -13,9 +13,9 @@ struct CDComponentsRegistry {
class CDComponentsRegistryTable : public CDTable<CDComponentsRegistryTable> { class CDComponentsRegistryTable : public CDTable<CDComponentsRegistryTable> {
private: private:
std::unordered_map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id std::map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id
public: public:
void LoadValuesFromDatabase(); CDComponentsRegistryTable();
int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0); int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0);
}; };

View File

@@ -1,7 +1,7 @@
#include "CDCurrencyTableTable.h" #include "CDCurrencyTableTable.h"
//! Constructor //! Constructor
void CDCurrencyTableTable::LoadValuesFromDatabase() { CDCurrencyTableTable::CDCurrencyTableTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -43,7 +43,7 @@ std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCu
return data; return data;
} }
const std::vector<CDCurrencyTable>& CDCurrencyTableTable::GetEntries() const { std::vector<CDCurrencyTable> CDCurrencyTableTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -23,9 +23,9 @@ private:
std::vector<CDCurrencyTable> entries; std::vector<CDCurrencyTable> entries;
public: public:
void LoadValuesFromDatabase(); CDCurrencyTableTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate); std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate);
const std::vector<CDCurrencyTable>& GetEntries() const; std::vector<CDCurrencyTable> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,8 @@
#include "CDDestructibleComponentTable.h" #include "CDDestructibleComponentTable.h"
void CDDestructibleComponentTable::LoadValuesFromDatabase() { //! Constructor
CDDestructibleComponentTable::CDDestructibleComponentTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent");
@@ -50,7 +52,7 @@ std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::fu
return data; return data;
} }
const std::vector<CDDestructibleComponent>& CDDestructibleComponentTable::GetEntries() const { std::vector<CDDestructibleComponent> CDDestructibleComponentTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -25,9 +25,9 @@ private:
std::vector<CDDestructibleComponent> entries; std::vector<CDDestructibleComponent> entries;
public: public:
void LoadValuesFromDatabase(); CDDestructibleComponentTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate); std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate);
const std::vector<CDDestructibleComponent>& GetEntries(void) const; std::vector<CDDestructibleComponent> GetEntries(void) const;
}; };

View File

@@ -1,26 +1,40 @@
#include "CDEmoteTable.h" #include "CDEmoteTable.h"
void CDEmoteTableTable::LoadValuesFromDatabase() { //! Constructor
CDEmoteTableTable::CDEmoteTableTable(void) {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Emotes"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Emotes");
while (!tableData.eof()) { while (!tableData.eof()) {
CDEmoteTable entry; CDEmoteTable* entry = new CDEmoteTable();
entry.ID = tableData.getIntField("id", -1); entry->ID = tableData.getIntField("id", -1);
entry.animationName = tableData.getStringField("animationName", ""); entry->animationName = tableData.getStringField("animationName", "");
entry.iconFilename = tableData.getStringField("iconFilename", ""); entry->iconFilename = tableData.getStringField("iconFilename", "");
entry.channel = tableData.getIntField("channel", -1); entry->channel = tableData.getIntField("channel", -1);
entry.locked = tableData.getIntField("locked", -1) != 0; entry->locked = tableData.getIntField("locked", -1) != 0;
entry.localize = tableData.getIntField("localize", -1) != 0; entry->localize = tableData.getIntField("localize", -1) != 0;
entry.locState = tableData.getIntField("locStatus", -1); entry->locState = tableData.getIntField("locStatus", -1);
entry.gateVersion = tableData.getStringField("gate_version", ""); entry->gateVersion = tableData.getStringField("gate_version", "");
entries.insert(std::make_pair(entry.ID, entry)); entries.insert(std::make_pair(entry->ID, entry));
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize(); tableData.finalize();
} }
CDEmoteTable* CDEmoteTableTable::GetEmote(int id) { //! Destructor
auto itr = entries.find(id); CDEmoteTableTable::~CDEmoteTableTable(void) {
return itr != entries.end() ? &itr->second : nullptr; for (auto e : entries) {
if (e.second) delete e.second;
} }
entries.clear();
}
CDEmoteTable* CDEmoteTableTable::GetEmote(int id) {
for (auto e : entries) {
if (e.first == id) return e.second;
}
return nullptr;
}

View File

@@ -28,10 +28,11 @@ struct CDEmoteTable {
class CDEmoteTableTable : public CDTable<CDEmoteTableTable> { class CDEmoteTableTable : public CDTable<CDEmoteTableTable> {
private: private:
std::map<int, CDEmoteTable> entries; std::map<int, CDEmoteTable*> entries;
public: public:
void LoadValuesFromDatabase(); CDEmoteTableTable();
~CDEmoteTableTable();
// Returns an emote by ID // Returns an emote by ID
CDEmoteTable* GetEmote(int id); CDEmoteTable* GetEmote(int id);
}; };

View File

@@ -1,6 +1,7 @@
#include "CDFeatureGatingTable.h" #include "CDFeatureGatingTable.h"
void CDFeatureGatingTable::LoadValuesFromDatabase() { //! Constructor
CDFeatureGatingTable::CDFeatureGatingTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -52,7 +53,7 @@ bool CDFeatureGatingTable::FeatureUnlocked(const std::string& feature) const {
return false; return false;
} }
const std::vector<CDFeatureGating>& CDFeatureGatingTable::GetEntries() const { std::vector<CDFeatureGating> CDFeatureGatingTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -16,12 +16,11 @@ private:
std::vector<CDFeatureGating> entries; std::vector<CDFeatureGating> entries;
public: public:
void LoadValuesFromDatabase(); CDFeatureGatingTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDFeatureGating> Query(std::function<bool(CDFeatureGating)> predicate); std::vector<CDFeatureGating> Query(std::function<bool(CDFeatureGating)> predicate);
bool FeatureUnlocked(const std::string& feature) const; bool FeatureUnlocked(const std::string& feature) const;
const std::vector<CDFeatureGating>& GetEntries(void) const; std::vector<CDFeatureGating> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,7 @@
#include "CDInventoryComponentTable.h" #include "CDInventoryComponentTable.h"
void CDInventoryComponentTable::LoadValuesFromDatabase() { //! Constructor
CDInventoryComponentTable::CDInventoryComponentTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -41,7 +42,7 @@ std::vector<CDInventoryComponent> CDInventoryComponentTable::Query(std::function
return data; return data;
} }
const std::vector<CDInventoryComponent>& CDInventoryComponentTable::GetEntries() const { std::vector<CDInventoryComponent> CDInventoryComponentTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -15,9 +15,9 @@ private:
std::vector<CDInventoryComponent> entries; std::vector<CDInventoryComponent> entries;
public: public:
void LoadValuesFromDatabase(); CDInventoryComponentTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDInventoryComponent> Query(std::function<bool(CDInventoryComponent)> predicate); std::vector<CDInventoryComponent> Query(std::function<bool(CDInventoryComponent)> predicate);
const std::vector<CDInventoryComponent>& GetEntries() const; std::vector<CDInventoryComponent> GetEntries(void) const;
}; };

View File

@@ -3,7 +3,11 @@
CDItemComponent CDItemComponentTable::Default = {}; CDItemComponent CDItemComponentTable::Default = {};
void CDItemComponentTable::LoadValuesFromDatabase() { //! Constructor
CDItemComponentTable::CDItemComponentTable(void) {
Default = CDItemComponent();
#ifdef CDCLIENT_CACHE_ALL
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemComponent"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemComponent");
@@ -51,13 +55,13 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
entry.currencyLOT = tableData.getIntField("currencyLOT", -1); entry.currencyLOT = tableData.getIntField("currencyLOT", -1);
entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1); entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1);
entry.subItems = tableData.getStringField("subItems", ""); entry.subItems = tableData.getStringField("subItems", "");
UNUSED_COLUMN(entry.audioEventUse = tableData.getStringField("audioEventUse", "")); entry.audioEventUse = tableData.getStringField("audioEventUse", "");
entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false; entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false;
entry.commendationLOT = tableData.getIntField("commendationLOT", -1); entry.commendationLOT = tableData.getIntField("commendationLOT", -1);
entry.commendationCost = tableData.getIntField("commendationCost", -1); entry.commendationCost = tableData.getIntField("commendationCost", -1);
UNUSED_COLUMN(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "")); entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "");
entry.currencyCosts = tableData.getStringField("currencyCosts", ""); entry.currencyCosts = tableData.getStringField("currencyCosts", "");
UNUSED_COLUMN(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "")); entry.ingredientInfo = tableData.getStringField("ingredientInfo", "");
entry.locStatus = tableData.getIntField("locStatus", -1); entry.locStatus = tableData.getIntField("locStatus", -1);
entry.forgeType = tableData.getIntField("forgeType", -1); entry.forgeType = tableData.getIntField("forgeType", -1);
entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f); entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f);
@@ -67,6 +71,7 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
} }
tableData.finalize(); tableData.finalize();
#endif
} }
const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int skillID) { const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int skillID) {
@@ -75,10 +80,12 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s
return it->second; return it->second;
} }
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM ItemComponent WHERE id = ?;"); #ifndef CDCLIENT_CACHE_ALL
query.bind(1, static_cast<int32_t>(skillID)); std::stringstream query;
auto tableData = query.execQuery(); query << "SELECT * FROM ItemComponent WHERE id = " << std::to_string(skillID);
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
if (tableData.eof()) { if (tableData.eof()) {
entries.insert(std::make_pair(skillID, Default)); entries.insert(std::make_pair(skillID, Default));
return Default; return Default;
@@ -137,6 +144,7 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s
if (it2 != this->entries.end()) { if (it2 != this->entries.end()) {
return it2->second; return it2->second;
} }
#endif
return Default; return Default;
} }

View File

@@ -54,7 +54,7 @@ private:
std::map<unsigned int, CDItemComponent> entries; std::map<unsigned int, CDItemComponent> entries;
public: public:
void LoadValuesFromDatabase(); CDItemComponentTable();
static std::map<LOT, uint32_t> ParseCraftingCurrencies(const CDItemComponent& itemComponent); static std::map<LOT, uint32_t> ParseCraftingCurrencies(const CDItemComponent& itemComponent);
// Gets an entry by ID // Gets an entry by ID

View File

@@ -1,6 +1,7 @@
#include "CDItemSetSkillsTable.h" #include "CDItemSetSkillsTable.h"
void CDItemSetSkillsTable::LoadValuesFromDatabase() { //! Constructor
CDItemSetSkillsTable::CDItemSetSkillsTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -40,7 +41,7 @@ std::vector<CDItemSetSkills> CDItemSetSkillsTable::Query(std::function<bool(CDIt
return data; return data;
} }
const std::vector<CDItemSetSkills>& CDItemSetSkillsTable::GetEntries() const { std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -14,11 +14,11 @@ private:
std::vector<CDItemSetSkills> entries; std::vector<CDItemSetSkills> entries;
public: public:
void LoadValuesFromDatabase(); CDItemSetSkillsTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDItemSetSkills> Query(std::function<bool(CDItemSetSkills)> predicate); std::vector<CDItemSetSkills> Query(std::function<bool(CDItemSetSkills)> predicate);
const std::vector<CDItemSetSkills>& GetEntries() const; std::vector<CDItemSetSkills> GetEntries(void) const;
std::vector<CDItemSetSkills> GetBySkillID(unsigned int SkillSetID); std::vector<CDItemSetSkills> GetBySkillID(unsigned int SkillSetID);
}; };

View File

@@ -1,6 +1,7 @@
#include "CDItemSetsTable.h" #include "CDItemSetsTable.h"
void CDItemSetsTable::LoadValuesFromDatabase() { //! Constructor
CDItemSetsTable::CDItemSetsTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -52,7 +53,7 @@ std::vector<CDItemSets> CDItemSetsTable::Query(std::function<bool(CDItemSets)> p
return data; return data;
} }
const std::vector<CDItemSets>& CDItemSetsTable::GetEntries() const { std::vector<CDItemSets> CDItemSetsTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -26,10 +26,10 @@ private:
std::vector<CDItemSets> entries; std::vector<CDItemSets> entries;
public: public:
void LoadValuesFromDatabase(); CDItemSetsTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDItemSets> Query(std::function<bool(CDItemSets)> predicate); std::vector<CDItemSets> Query(std::function<bool(CDItemSets)> predicate);
const std::vector<CDItemSets>& GetEntries(void) const; std::vector<CDItemSets> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,7 @@
#include "CDLevelProgressionLookupTable.h" #include "CDLevelProgressionLookupTable.h"
void CDLevelProgressionLookupTable::LoadValuesFromDatabase() { //! Constructor
CDLevelProgressionLookupTable::CDLevelProgressionLookupTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -31,6 +32,7 @@ void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
//! Queries the table with a custom "where" clause
std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std::function<bool(CDLevelProgressionLookup)> predicate) { std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std::function<bool(CDLevelProgressionLookup)> predicate) {
std::vector<CDLevelProgressionLookup> data = cpplinq::from(this->entries) std::vector<CDLevelProgressionLookup> data = cpplinq::from(this->entries)
@@ -40,7 +42,8 @@ std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std::
return data; return data;
} }
const std::vector<CDLevelProgressionLookup>& CDLevelProgressionLookupTable::GetEntries() const { //! Gets all the entries in the table
std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -14,10 +14,10 @@ private:
std::vector<CDLevelProgressionLookup> entries; std::vector<CDLevelProgressionLookup> entries;
public: public:
void LoadValuesFromDatabase(); CDLevelProgressionLookupTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDLevelProgressionLookup> Query(std::function<bool(CDLevelProgressionLookup)> predicate); std::vector<CDLevelProgressionLookup> Query(std::function<bool(CDLevelProgressionLookup)> predicate);
const std::vector<CDLevelProgressionLookup>& GetEntries() const; // Gets all the entries in the table
std::vector<CDLevelProgressionLookup> GetEntries(void) const;
}; };

View File

@@ -1,19 +1,7 @@
#include "CDLootMatrixTable.h" #include "CDLootMatrixTable.h"
CDLootMatrix CDLootMatrixTable::ReadRow(CppSQLite3Query& tableData) const { //! Constructor
CDLootMatrix entry{}; CDLootMatrixTable::CDLootMatrixTable(void) {
if (tableData.eof()) return entry;
entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1);
entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1);
entry.percent = tableData.getFloatField("percent", -1.0f);
entry.minToDrop = tableData.getIntField("minToDrop", -1);
entry.maxToDrop = tableData.getIntField("maxToDrop", -1);
entry.flagID = tableData.getIntField("flagID", -1);
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
return entry;
}
void CDLootMatrixTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -24,6 +12,8 @@ void CDLootMatrixTable::LoadValuesFromDatabase() {
tableSize.nextRow(); tableSize.nextRow();
} }
tableSize.finalize();
// Reserve the size // Reserve the size
this->entries.reserve(size); this->entries.reserve(size);
@@ -31,28 +21,33 @@ void CDLootMatrixTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootMatrix"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootMatrix");
while (!tableData.eof()) { while (!tableData.eof()) {
CDLootMatrix entry; CDLootMatrix entry;
uint32_t lootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1);
entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1);
entry.percent = tableData.getFloatField("percent", -1.0f);
entry.minToDrop = tableData.getIntField("minToDrop", -1);
entry.maxToDrop = tableData.getIntField("maxToDrop", -1);
entry.id = tableData.getIntField("id", -1);
entry.flagID = tableData.getIntField("flagID", -1);
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
this->entries[lootMatrixIndex].push_back(ReadRow(tableData)); this->entries.push_back(entry);
tableData.nextRow();
}
}
const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) {
auto itr = this->entries.find(matrixId);
if (itr != this->entries.end()) {
return itr->second;
}
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM LootMatrix where LootMatrixIndex = ?;");
query.bind(1, static_cast<int32_t>(matrixId));
auto tableData = query.execQuery();
while (!tableData.eof()) {
this->entries[matrixId].push_back(ReadRow(tableData));
tableData.nextRow(); tableData.nextRow();
} }
return this->entries[matrixId]; tableData.finalize();
}
std::vector<CDLootMatrix> CDLootMatrixTable::Query(std::function<bool(CDLootMatrix)> predicate) {
std::vector<CDLootMatrix> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDLootMatrix>& CDLootMatrixTable::GetEntries(void) const {
return this->entries;
} }

View File

@@ -4,26 +4,26 @@
#include "CDTable.h" #include "CDTable.h"
struct CDLootMatrix { struct CDLootMatrix {
unsigned int LootMatrixIndex; //!< The Loot Matrix Index
unsigned int LootTableIndex; //!< The Loot Table Index unsigned int LootTableIndex; //!< The Loot Table Index
unsigned int RarityTableIndex; //!< The Rarity Table Index unsigned int RarityTableIndex; //!< The Rarity Table Index
float percent; //!< The percent that this matrix is used? float percent; //!< The percent that this matrix is used?
unsigned int minToDrop; //!< The minimum amount of loot from this matrix to drop unsigned int minToDrop; //!< The minimum amount of loot from this matrix to drop
unsigned int maxToDrop; //!< The maximum amount of loot from this matrix to drop unsigned int maxToDrop; //!< The maximum amount of loot from this matrix to drop
unsigned int id; //!< The ID of the Loot Matrix
unsigned int flagID; //!< ??? unsigned int flagID; //!< ???
UNUSED(std::string gate_version); //!< The Gate Version UNUSED(std::string gate_version); //!< The Gate Version
}; };
typedef uint32_t LootMatrixIndex;
typedef std::vector<CDLootMatrix> LootMatrixEntries;
class CDLootMatrixTable : public CDTable<CDLootMatrixTable> { class CDLootMatrixTable : public CDTable<CDLootMatrixTable> {
public:
void LoadValuesFromDatabase();
// Gets a matrix by ID or inserts a blank one if none existed.
const LootMatrixEntries& GetMatrix(uint32_t matrixId);
private: private:
CDLootMatrix ReadRow(CppSQLite3Query& tableData) const; std::vector<CDLootMatrix> entries;
std::unordered_map<LootMatrixIndex, LootMatrixEntries> entries;
public:
CDLootMatrixTable();
// Queries the table with a custom "where" clause
std::vector<CDLootMatrix> Query(std::function<bool(CDLootMatrix)> predicate);
const std::vector<CDLootMatrix>& GetEntries(void) const;
}; };

View File

@@ -1,43 +1,7 @@
#include "CDLootTableTable.h" #include "CDLootTableTable.h"
#include "CDClientManager.h"
#include "CDComponentsRegistryTable.h"
#include "CDItemComponentTable.h"
#include "eReplicaComponentType.h"
// Sort the tables by their rarity so the highest rarity items are first. //! Constructor
void SortTable(LootTableEntries& table) { CDLootTableTable::CDLootTableTable(void) {
auto* componentsRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
auto* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>();
// We modify the table in place so the outer loop keeps track of what is sorted
// and the inner loop finds the highest rarity item and swaps it with the current position
// of the outer loop.
for (auto oldItrOuter = table.begin(); oldItrOuter != table.end(); oldItrOuter++) {
auto lootToInsert = oldItrOuter;
// Its fine if this starts at 0, even if this doesnt match lootToInsert as the actual highest will
// either be found and overwrite these values, or the original is somehow zero and is still the highest rarity.
uint32_t highestLootRarity = 0;
for (auto oldItrInner = oldItrOuter; oldItrInner != table.end(); oldItrInner++) {
uint32_t itemComponentId = componentsRegistryTable->GetByIDAndType(oldItrInner->itemid, eReplicaComponentType::ITEM);
uint32_t rarity = itemComponentTable->GetItemComponentByID(itemComponentId).rarity;
if (rarity > highestLootRarity) {
highestLootRarity = rarity;
lootToInsert = oldItrInner;
}
}
std::swap(*oldItrOuter, *lootToInsert);
}
}
CDLootTable CDLootTableTable::ReadRow(CppSQLite3Query& tableData) const {
CDLootTable entry{};
if (tableData.eof()) return entry;
entry.itemid = tableData.getIntField("itemid", -1);
entry.MissionDrop = tableData.getIntField("MissionDrop", -1) == 1 ? true : false;
entry.sortPriority = tableData.getIntField("sortPriority", -1);
return entry;
}
void CDLootTableTable::LoadValuesFromDatabase() {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -48,6 +12,8 @@ void CDLootTableTable::LoadValuesFromDatabase() {
tableSize.nextRow(); tableSize.nextRow();
} }
tableSize.finalize();
// Reserve the size // Reserve the size
this->entries.reserve(size); this->entries.reserve(size);
@@ -55,32 +21,32 @@ void CDLootTableTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootTable"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootTable");
while (!tableData.eof()) { while (!tableData.eof()) {
CDLootTable entry; CDLootTable entry;
uint32_t lootTableIndex = tableData.getIntField("LootTableIndex", -1); entry.id = tableData.getIntField("id", -1);
entry.itemid = tableData.getIntField("itemid", -1);
entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1);
entry.id = tableData.getIntField("id", -1);
entry.MissionDrop = tableData.getIntField("MissionDrop", -1) == 1 ? true : false;
entry.sortPriority = tableData.getIntField("sortPriority", -1);
this->entries[lootTableIndex].push_back(ReadRow(tableData)); this->entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }
for (auto& [id, table] : this->entries) {
SortTable(table); tableData.finalize();
}
} }
const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) { //! Queries the table with a custom "where" clause
auto itr = this->entries.find(tableId); std::vector<CDLootTable> CDLootTableTable::Query(std::function<bool(CDLootTable)> predicate) {
if (itr != this->entries.end()) {
return itr->second; std::vector<CDLootTable> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
} }
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM LootTable WHERE LootTableIndex = ?;"); //! Gets all the entries in the table
query.bind(1, static_cast<int32_t>(tableId)); const std::vector<CDLootTable>& CDLootTableTable::GetEntries(void) const {
auto tableData = query.execQuery(); return this->entries;
while (!tableData.eof()) {
CDLootTable entry;
this->entries[tableId].push_back(ReadRow(tableData));
tableData.nextRow();
} }
SortTable(this->entries[tableId]);
return this->entries[tableId];
}

View File

@@ -6,21 +6,20 @@
struct CDLootTable { struct CDLootTable {
unsigned int itemid; //!< The LOT of the item unsigned int itemid; //!< The LOT of the item
unsigned int LootTableIndex; //!< The Loot Table Index unsigned int LootTableIndex; //!< The Loot Table Index
unsigned int id; //!< The ID
bool MissionDrop; //!< Whether or not this loot table is a mission drop bool MissionDrop; //!< Whether or not this loot table is a mission drop
unsigned int sortPriority; //!< The sorting priority unsigned int sortPriority; //!< The sorting priority
}; };
typedef uint32_t LootTableIndex;
typedef std::vector<CDLootTable> LootTableEntries;
class CDLootTableTable : public CDTable<CDLootTableTable> { class CDLootTableTable : public CDTable<CDLootTableTable> {
private: private:
CDLootTable ReadRow(CppSQLite3Query& tableData) const; std::vector<CDLootTable> entries;
std::unordered_map<LootTableIndex, LootTableEntries> entries;
public: public:
void LoadValuesFromDatabase(); CDLootTableTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
const LootTableEntries& GetTable(uint32_t tableId); std::vector<CDLootTable> Query(std::function<bool(CDLootTable)> predicate);
const std::vector<CDLootTable>& GetEntries(void) const;
}; };

View File

@@ -1,6 +1,7 @@
#include "CDMissionEmailTable.h" #include "CDMissionEmailTable.h"
void CDMissionEmailTable::LoadValuesFromDatabase() { //! Constructor
CDMissionEmailTable::CDMissionEmailTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -47,7 +48,7 @@ std::vector<CDMissionEmail> CDMissionEmailTable::Query(std::function<bool(CDMiss
} }
//! Gets all the entries in the table //! Gets all the entries in the table
const std::vector<CDMissionEmail>& CDMissionEmailTable::GetEntries() const { std::vector<CDMissionEmail> CDMissionEmailTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -20,9 +20,9 @@ private:
std::vector<CDMissionEmail> entries; std::vector<CDMissionEmail> entries;
public: public:
void LoadValuesFromDatabase(); CDMissionEmailTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDMissionEmail> Query(std::function<bool(CDMissionEmail)> predicate); std::vector<CDMissionEmail> Query(std::function<bool(CDMissionEmail)> predicate);
const std::vector<CDMissionEmail>& GetEntries() const; std::vector<CDMissionEmail> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,7 @@
#include "CDMissionNPCComponentTable.h" #include "CDMissionNPCComponentTable.h"
void CDMissionNPCComponentTable::LoadValuesFromDatabase() { //! Constructor
CDMissionNPCComponentTable::CDMissionNPCComponentTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -44,7 +45,7 @@ std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::Query(std::functi
} }
//! Gets all the entries in the table //! Gets all the entries in the table
const std::vector<CDMissionNPCComponent>& CDMissionNPCComponentTable::GetEntries() const { std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -16,12 +16,12 @@ private:
std::vector<CDMissionNPCComponent> entries; std::vector<CDMissionNPCComponent> entries;
public: public:
void LoadValuesFromDatabase(); CDMissionNPCComponentTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDMissionNPCComponent> Query(std::function<bool(CDMissionNPCComponent)> predicate); std::vector<CDMissionNPCComponent> Query(std::function<bool(CDMissionNPCComponent)> predicate);
// Gets all the entries in the table // Gets all the entries in the table
const std::vector<CDMissionNPCComponent>& GetEntries() const; std::vector<CDMissionNPCComponent> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,7 @@
#include "CDMissionTasksTable.h" #include "CDMissionTasksTable.h"
void CDMissionTasksTable::LoadValuesFromDatabase() { //! Constructor
CDMissionTasksTable::CDMissionTasksTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -55,14 +56,16 @@ std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missio
for (auto& entry : this->entries) { for (auto& entry : this->entries) {
if (entry.id == missionID) { if (entry.id == missionID) {
tasks.push_back(&entry); CDMissionTasks* task = const_cast<CDMissionTasks*>(&entry);
tasks.push_back(task);
} }
} }
return tasks; return tasks;
} }
const std::vector<CDMissionTasks>& CDMissionTasksTable::GetEntries() const { const std::vector<CDMissionTasks>& CDMissionTasksTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -24,12 +24,12 @@ private:
std::vector<CDMissionTasks> entries; std::vector<CDMissionTasks> entries;
public: public:
void LoadValuesFromDatabase(); CDMissionTasksTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDMissionTasks> Query(std::function<bool(CDMissionTasks)> predicate); std::vector<CDMissionTasks> Query(std::function<bool(CDMissionTasks)> predicate);
std::vector<CDMissionTasks*> GetByMissionID(uint32_t missionID); std::vector<CDMissionTasks*> GetByMissionID(uint32_t missionID);
const std::vector<CDMissionTasks>& GetEntries() const; const std::vector<CDMissionTasks>& GetEntries(void) const;
}; };

View File

@@ -2,7 +2,8 @@
CDMissions CDMissionsTable::Default = {}; CDMissions CDMissionsTable::Default = {};
void CDMissionsTable::LoadValuesFromDatabase() { //! Constructor
CDMissionsTable::CDMissionsTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;

View File

@@ -65,12 +65,12 @@ private:
std::vector<CDMissions> entries; std::vector<CDMissions> entries;
public: public:
void LoadValuesFromDatabase(); CDMissionsTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDMissions> Query(std::function<bool(CDMissions)> predicate); std::vector<CDMissions> Query(std::function<bool(CDMissions)> predicate);
// Gets all the entries in the table // Gets all the entries in the table
const std::vector<CDMissions>& GetEntries() const; const std::vector<CDMissions>& GetEntries(void) const;
const CDMissions* GetPtrByMissionID(uint32_t missionID) const; const CDMissions* GetPtrByMissionID(uint32_t missionID) const;

View File

@@ -1,6 +1,7 @@
#include "CDMovementAIComponentTable.h" #include "CDMovementAIComponentTable.h"
void CDMovementAIComponentTable::LoadValuesFromDatabase() { //! Constructor
CDMovementAIComponentTable::CDMovementAIComponentTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -36,6 +37,7 @@ void CDMovementAIComponentTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
//! Queries the table with a custom "where" clause
std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::function<bool(CDMovementAIComponent)> predicate) { std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::function<bool(CDMovementAIComponent)> predicate) {
std::vector<CDMovementAIComponent> data = cpplinq::from(this->entries) std::vector<CDMovementAIComponent> data = cpplinq::from(this->entries)
@@ -45,7 +47,8 @@ std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::functi
return data; return data;
} }
const std::vector<CDMovementAIComponent>& CDMovementAIComponentTable::GetEntries(void) const { //! Gets all the entries in the table
std::vector<CDMovementAIComponent> CDMovementAIComponentTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -19,10 +19,10 @@ private:
std::vector<CDMovementAIComponent> entries; std::vector<CDMovementAIComponent> entries;
public: public:
void LoadValuesFromDatabase(); CDMovementAIComponentTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDMovementAIComponent> Query(std::function<bool(CDMovementAIComponent)> predicate); std::vector<CDMovementAIComponent> Query(std::function<bool(CDMovementAIComponent)> predicate);
// Gets all the entries in the table // Gets all the entries in the table
const std::vector<CDMovementAIComponent>& GetEntries() const; std::vector<CDMovementAIComponent> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,7 @@
#include "CDObjectSkillsTable.h" #include "CDObjectSkillsTable.h"
void CDObjectSkillsTable::LoadValuesFromDatabase() { //! Constructor
CDObjectSkillsTable::CDObjectSkillsTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -32,6 +33,7 @@ void CDObjectSkillsTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
//! Queries the table with a custom "where" clause
std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObjectSkills)> predicate) { std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObjectSkills)> predicate) {
std::vector<CDObjectSkills> data = cpplinq::from(this->entries) std::vector<CDObjectSkills> data = cpplinq::from(this->entries)
@@ -41,6 +43,7 @@ std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObje
return data; return data;
} }
const std::vector<CDObjectSkills>& CDObjectSkillsTable::GetEntries() const { //! Gets all the entries in the table
std::vector<CDObjectSkills> CDObjectSkillsTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -15,12 +15,12 @@ private:
std::vector<CDObjectSkills> entries; std::vector<CDObjectSkills> entries;
public: public:
void LoadValuesFromDatabase(); CDObjectSkillsTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDObjectSkills> Query(std::function<bool(CDObjectSkills)> predicate); std::vector<CDObjectSkills> Query(std::function<bool(CDObjectSkills)> predicate);
// Gets all the entries in the table // Gets all the entries in the table
const std::vector<CDObjectSkills>& GetEntries() const; std::vector<CDObjectSkills> GetEntries(void) const;
}; };

View File

@@ -1,6 +1,8 @@
#include "CDObjectsTable.h" #include "CDObjectsTable.h"
void CDObjectsTable::LoadValuesFromDatabase() { //! Constructor
CDObjectsTable::CDObjectsTable(void) {
#ifdef CDCLIENT_CACHE_ALL
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Objects"); auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Objects");
@@ -18,24 +20,25 @@ void CDObjectsTable::LoadValuesFromDatabase() {
CDObjects entry; CDObjects entry;
entry.id = tableData.getIntField("id", -1); entry.id = tableData.getIntField("id", -1);
entry.name = tableData.getStringField("name", ""); entry.name = tableData.getStringField("name", "");
UNUSED_COLUMN(entry.placeable = tableData.getIntField("placeable", -1);) entry.placeable = tableData.getIntField("placeable", -1);
entry.type = tableData.getStringField("type", ""); entry.type = tableData.getStringField("type", "");
UNUSED_COLUMN(entry.description = tableData.getStringField("description", "");) entry.description = tableData.getStringField("description", "");
UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1);) entry.localize = tableData.getIntField("localize", -1);
UNUSED_COLUMN(entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1);) entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1);
UNUSED_COLUMN(entry.displayName = tableData.getStringField("displayName", "");) entry.displayName = tableData.getStringField("displayName", "");
entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f); entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f);
UNUSED_COLUMN(entry.nametag = tableData.getIntField("nametag", -1);) entry.nametag = tableData.getIntField("nametag", -1);
UNUSED_COLUMN(entry._internalNotes = tableData.getStringField("_internalNotes", "");) entry._internalNotes = tableData.getStringField("_internalNotes", "");
UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1);) entry.locStatus = tableData.getIntField("locStatus", -1);
UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "");) entry.gate_version = tableData.getStringField("gate_version", "");
UNUSED_COLUMN(entry.HQ_valid = tableData.getIntField("HQ_valid", -1);) entry.HQ_valid = tableData.getIntField("HQ_valid", -1);
this->entries.insert(std::make_pair(entry.id, entry)); this->entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize(); tableData.finalize();
#endif
m_default.id = 0; m_default.id = 0;
} }
@@ -46,10 +49,12 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) {
return it->second; return it->second;
} }
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Objects WHERE id = ?;"); #ifndef CDCLIENT_CACHE_ALL
query.bind(1, static_cast<int32_t>(LOT)); std::stringstream query;
auto tableData = query.execQuery(); query << "SELECT * FROM Objects WHERE id = " << std::to_string(LOT);
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
if (tableData.eof()) { if (tableData.eof()) {
this->entries.insert(std::make_pair(LOT, m_default)); this->entries.insert(std::make_pair(LOT, m_default));
return m_default; return m_default;
@@ -83,6 +88,7 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) {
if (it2 != entries.end()) { if (it2 != entries.end()) {
return it2->second; return it2->second;
} }
#endif
return m_default; return m_default;
} }

View File

@@ -26,7 +26,7 @@ private:
CDObjects m_default; CDObjects m_default;
public: public:
void LoadValuesFromDatabase(); CDObjectsTable();
// Gets an entry by ID // Gets an entry by ID
const CDObjects& GetByID(unsigned int LOT); const CDObjects& GetByID(unsigned int LOT);
}; };

View File

@@ -1,6 +1,7 @@
#include "CDPackageComponentTable.h" #include "CDPackageComponentTable.h"
void CDPackageComponentTable::LoadValuesFromDatabase() { //! Constructor
CDPackageComponentTable::CDPackageComponentTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -42,7 +43,7 @@ std::vector<CDPackageComponent> CDPackageComponentTable::Query(std::function<boo
} }
//! Gets all the entries in the table //! Gets all the entries in the table
const std::vector<CDPackageComponent>& CDPackageComponentTable::GetEntries() const { std::vector<CDPackageComponent> CDPackageComponentTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -14,9 +14,9 @@ private:
std::vector<CDPackageComponent> entries; std::vector<CDPackageComponent> entries;
public: public:
void LoadValuesFromDatabase(); CDPackageComponentTable(void);
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDPackageComponent> Query(std::function<bool(CDPackageComponent)> predicate); std::vector<CDPackageComponent> Query(std::function<bool(CDPackageComponent)> predicate);
const std::vector<CDPackageComponent>& GetEntries() const; std::vector<CDPackageComponent> GetEntries(void) const;
}; };

View File

@@ -1,35 +1,46 @@
#include "CDPhysicsComponentTable.h" #include "CDPhysicsComponentTable.h"
void CDPhysicsComponentTable::LoadValuesFromDatabase() { CDPhysicsComponentTable::CDPhysicsComponentTable(void) {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent");
while (!tableData.eof()) { while (!tableData.eof()) {
CDPhysicsComponent entry; CDPhysicsComponent* entry = new CDPhysicsComponent();
entry.id = tableData.getIntField("id", -1); entry->id = tableData.getIntField("id", -1);
entry.bStatic = tableData.getIntField("static", -1) != 0; entry->bStatic = tableData.getIntField("static", -1) != 0;
entry.physicsAsset = tableData.getStringField("physics_asset", ""); entry->physicsAsset = tableData.getStringField("physics_asset", "");
UNUSED(entry->jump = tableData.getIntField("jump", -1) != 0); UNUSED(entry->jump = tableData.getIntField("jump", -1) != 0);
UNUSED(entry->doublejump = tableData.getIntField("doublejump", -1) != 0); UNUSED(entry->doublejump = tableData.getIntField("doublejump", -1) != 0);
entry.speed = tableData.getFloatField("speed", -1); entry->speed = tableData.getFloatField("speed", -1);
UNUSED(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1)); UNUSED(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1));
entry.playerHeight = tableData.getFloatField("playerHeight"); entry->playerHeight = tableData.getFloatField("playerHeight");
entry.playerRadius = tableData.getFloatField("playerRadius"); entry->playerRadius = tableData.getFloatField("playerRadius");
entry.pcShapeType = tableData.getIntField("pcShapeType"); entry->pcShapeType = tableData.getIntField("pcShapeType");
entry.collisionGroup = tableData.getIntField("collisionGroup"); entry->collisionGroup = tableData.getIntField("collisionGroup");
UNUSED(entry->airSpeed = tableData.getFloatField("airSpeed")); UNUSED(entry->airSpeed = tableData.getFloatField("airSpeed"));
UNUSED(entry->boundaryAsset = tableData.getStringField("boundaryAsset")); UNUSED(entry->boundaryAsset = tableData.getStringField("boundaryAsset"));
UNUSED(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed")); UNUSED(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed"));
UNUSED(entry->friction = tableData.getFloatField("friction")); UNUSED(entry->friction = tableData.getFloatField("friction"));
UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset")); UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset"));
m_entries.insert(std::make_pair(entry.id, entry)); m_entries.insert(std::make_pair(entry->id, entry));
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize(); tableData.finalize();
} }
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) { CDPhysicsComponentTable::~CDPhysicsComponentTable() {
auto itr = m_entries.find(componentID); for (auto e : m_entries) {
return itr != m_entries.end() ? &itr->second : nullptr; if (e.second) delete e.second;
}
m_entries.clear();
}
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) {
for (auto e : m_entries) {
if (e.first == componentID) return e.second;
}
return nullptr;
} }

View File

@@ -23,11 +23,12 @@ struct CDPhysicsComponent {
class CDPhysicsComponentTable : public CDTable<CDPhysicsComponentTable> { class CDPhysicsComponentTable : public CDTable<CDPhysicsComponentTable> {
public: public:
void LoadValuesFromDatabase(); CDPhysicsComponentTable();
~CDPhysicsComponentTable();
static const std::string GetTableName() { return "PhysicsComponent"; }; static const std::string GetTableName() { return "PhysicsComponent"; };
CDPhysicsComponent* GetByID(unsigned int componentID); CDPhysicsComponent* GetByID(unsigned int componentID);
private: private:
std::map<unsigned int, CDPhysicsComponent> m_entries; std::map<unsigned int, CDPhysicsComponent*> m_entries;
}; };

View File

@@ -1,6 +1,7 @@
#include "CDPropertyEntranceComponentTable.h" #include "CDPropertyEntranceComponentTable.h"
void CDPropertyEntranceComponentTable::LoadValuesFromDatabase() { CDPropertyEntranceComponentTable::CDPropertyEntranceComponentTable() {
// First, get the size of the table // First, get the size of the table
size_t size = 0; size_t size = 0;

View File

@@ -11,12 +11,12 @@ struct CDPropertyEntranceComponent {
class CDPropertyEntranceComponentTable : public CDTable<CDPropertyEntranceComponentTable> { class CDPropertyEntranceComponentTable : public CDTable<CDPropertyEntranceComponentTable> {
public: public:
void LoadValuesFromDatabase(); CDPropertyEntranceComponentTable();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
CDPropertyEntranceComponent GetByID(uint32_t id); CDPropertyEntranceComponent GetByID(uint32_t id);
// Gets all the entries in the table // Gets all the entries in the table
[[nodiscard]] const std::vector<CDPropertyEntranceComponent>& GetEntries() const { return entries; } [[nodiscard]] std::vector<CDPropertyEntranceComponent> GetEntries() const { return entries; }
private: private:
std::vector<CDPropertyEntranceComponent> entries{}; std::vector<CDPropertyEntranceComponent> entries{};
CDPropertyEntranceComponent defaultEntry{}; CDPropertyEntranceComponent defaultEntry{};

View File

@@ -1,6 +1,6 @@
#include "CDPropertyTemplateTable.h" #include "CDPropertyTemplateTable.h"
void CDPropertyTemplateTable::LoadValuesFromDatabase() { CDPropertyTemplateTable::CDPropertyTemplateTable() {
// First, get the size of the table // First, get the size of the table
size_t size = 0; size_t size = 0;

View File

@@ -10,7 +10,7 @@ struct CDPropertyTemplate {
class CDPropertyTemplateTable : public CDTable<CDPropertyTemplateTable> { class CDPropertyTemplateTable : public CDTable<CDPropertyTemplateTable> {
public: public:
void LoadValuesFromDatabase(); CDPropertyTemplateTable();
static const std::string GetTableName() { return "PropertyTemplate"; }; static const std::string GetTableName() { return "PropertyTemplate"; };
CDPropertyTemplate GetByMapID(uint32_t mapID); CDPropertyTemplate GetByMapID(uint32_t mapID);

View File

@@ -1,6 +1,7 @@
#include "CDProximityMonitorComponentTable.h" #include "CDProximityMonitorComponentTable.h"
void CDProximityMonitorComponentTable::LoadValuesFromDatabase() { //! Constructor
CDProximityMonitorComponentTable::CDProximityMonitorComponentTable(void) {
// First, get the size of the table // First, get the size of the table
unsigned int size = 0; unsigned int size = 0;
@@ -32,6 +33,7 @@ void CDProximityMonitorComponentTable::LoadValuesFromDatabase() {
tableData.finalize(); tableData.finalize();
} }
//! Queries the table with a custom "where" clause
std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::Query(std::function<bool(CDProximityMonitorComponent)> predicate) { std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::Query(std::function<bool(CDProximityMonitorComponent)> predicate) {
std::vector<CDProximityMonitorComponent> data = cpplinq::from(this->entries) std::vector<CDProximityMonitorComponent> data = cpplinq::from(this->entries)
@@ -41,7 +43,8 @@ std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::Query
return data; return data;
} }
const std::vector<CDProximityMonitorComponent>& CDProximityMonitorComponentTable::GetEntries() const { //! Gets all the entries in the table
std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::GetEntries(void) const {
return this->entries; return this->entries;
} }

View File

@@ -15,9 +15,9 @@ private:
std::vector<CDProximityMonitorComponent> entries; std::vector<CDProximityMonitorComponent> entries;
public: public:
void LoadValuesFromDatabase(); CDProximityMonitorComponentTable(void);
//! Queries the table with a custom "where" clause //! Queries the table with a custom "where" clause
std::vector<CDProximityMonitorComponent> Query(std::function<bool(CDProximityMonitorComponent)> predicate); std::vector<CDProximityMonitorComponent> Query(std::function<bool(CDProximityMonitorComponent)> predicate);
const std::vector<CDProximityMonitorComponent>& GetEntries() const; std::vector<CDProximityMonitorComponent> GetEntries(void) const;
}; };

View File

@@ -1,7 +1,7 @@
#include "CDRailActivatorComponent.h" #include "CDRailActivatorComponent.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
void CDRailActivatorComponentTable::LoadValuesFromDatabase() { CDRailActivatorComponentTable::CDRailActivatorComponentTable() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RailActivatorComponent;"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RailActivatorComponent;");
while (!tableData.eof()) { while (!tableData.eof()) {
CDRailActivatorComponent entry; CDRailActivatorComponent entry;
@@ -52,7 +52,7 @@ CDRailActivatorComponent CDRailActivatorComponentTable::GetEntryByID(int32_t id)
return {}; return {};
} }
const std::vector<CDRailActivatorComponent>& CDRailActivatorComponentTable::GetEntries() const { std::vector<CDRailActivatorComponent> CDRailActivatorComponentTable::GetEntries() const {
return m_Entries; return m_Entries;
} }

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