Merge branch 'DarkflameUniverse:main' into PetFixes

This commit is contained in:
jadebenn 2024-01-06 13:53:39 -06:00 committed by GitHub
commit 06d5a27635
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 305 additions and 145 deletions

View File

@ -1222,39 +1222,56 @@ void Entity::UpdateXMLDoc(tinyxml2::XMLDocument* doc) {
void Entity::Update(const float deltaTime) { void Entity::Update(const float deltaTime) {
uint32_t timerPosition; uint32_t timerPosition;
timerPosition = 0; for (timerPosition = 0; timerPosition < m_Timers.size();) {
while (timerPosition < m_Timers.size()) { auto& timer = m_Timers[timerPosition];
m_Timers[timerPosition]->Update(deltaTime); timer.Update(deltaTime);
if (m_Timers[timerPosition]->GetTime() <= 0) { // If the timer is expired, erase it and dont increment the position because the next timer will be at the same position.
const auto timerName = m_Timers[timerPosition]->GetName(); // Before: [0, 1, 2, 3, ..., n]
// timerPosition ^
delete m_Timers[timerPosition]; // After: [0, 1, 3, ..., n]
// timerPosition ^
if (timer.GetTime() <= 0) {
// Remove the timer from the list of timers first so that scripts and events can remove timers without causing iterator invalidation
auto timerName = timer.GetName();
m_Timers.erase(m_Timers.begin() + timerPosition); m_Timers.erase(m_Timers.begin() + timerPosition);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
script->OnTimerDone(this, timerName); script->OnTimerDone(this, timerName);
} }
TriggerEvent(eTriggerEventType::TIMER_DONE, this); TriggerEvent(eTriggerEventType::TIMER_DONE, this);
} else {
// If the timer isnt expired, go to the next timer.
timerPosition++;
}
}
for (timerPosition = 0; timerPosition < m_CallbackTimers.size(); ) {
// If the timer is expired, erase it and dont increment the position because the next timer will be at the same position.
// Before: [0, 1, 2, 3, ..., n]
// timerPosition ^
// After: [0, 1, 3, ..., n]
// timerPosition ^
auto& callbackTimer = m_CallbackTimers[timerPosition];
callbackTimer.Update(deltaTime);
if (callbackTimer.GetTime() <= 0) {
// Remove the timer from the list of timers first so that callbacks can remove timers without causing iterator invalidation
auto callback = callbackTimer.GetCallback();
m_CallbackTimers.erase(m_CallbackTimers.begin() + timerPosition);
callback();
} else { } else {
timerPosition++; timerPosition++;
} }
} }
for (int i = 0; i < m_CallbackTimers.size(); i++) { // Add pending timers to the list of timers so they start next tick.
m_CallbackTimers[i]->Update(deltaTime); if (!m_PendingTimers.empty()) {
if (m_CallbackTimers[i]->GetTime() <= 0) { m_Timers.insert(m_Timers.end(), m_PendingTimers.begin(), m_PendingTimers.end());
m_CallbackTimers[i]->GetCallback()(); m_PendingTimers.clear();
delete m_CallbackTimers[i];
m_CallbackTimers.erase(m_CallbackTimers.begin() + i);
}
} }
// Add pending timers to the list of timers so they start next tick. if (!m_PendingCallbackTimers.empty()) {
if (m_PendingTimers.size() > 0) { m_CallbackTimers.insert(m_CallbackTimers.end(), m_PendingCallbackTimers.begin(), m_PendingCallbackTimers.end());
for (auto namedTimer : m_PendingTimers) { m_PendingCallbackTimers.clear();
m_Timers.push_back(namedTimer);
}
m_PendingTimers.clear();
} }
if (IsSleeping()) { if (IsSleeping()) {
@ -1692,31 +1709,20 @@ void Entity::RemoveParent() {
} }
void Entity::AddTimer(std::string name, float time) { void Entity::AddTimer(std::string name, float time) {
EntityTimer* timer = new EntityTimer(name, time); m_PendingTimers.emplace_back(name, time);
m_PendingTimers.push_back(timer);
} }
void Entity::AddCallbackTimer(float time, std::function<void()> callback) { void Entity::AddCallbackTimer(float time, std::function<void()> callback) {
EntityCallbackTimer* timer = new EntityCallbackTimer(time, callback); m_PendingCallbackTimers.emplace_back(time, callback);
m_CallbackTimers.push_back(timer);
} }
bool Entity::HasTimer(const std::string& name) { bool Entity::HasTimer(const std::string& name) {
for (auto* timer : m_Timers) { return std::find(m_Timers.begin(), m_Timers.end(), name) != m_Timers.end();
if (timer->GetName() == name) {
return true;
}
}
return false;
} }
void Entity::CancelCallbackTimers() { void Entity::CancelCallbackTimers() {
for (auto* callback : m_CallbackTimers) {
delete callback;
}
m_CallbackTimers.clear(); m_CallbackTimers.clear();
m_PendingCallbackTimers.clear();
} }
void Entity::ScheduleKillAfterUpdate(Entity* murderer) { void Entity::ScheduleKillAfterUpdate(Entity* murderer) {
@ -1728,8 +1734,8 @@ void Entity::ScheduleKillAfterUpdate(Entity* murderer) {
void Entity::CancelTimer(const std::string& name) { void Entity::CancelTimer(const std::string& name) {
for (int i = 0; i < m_Timers.size(); i++) { for (int i = 0; i < m_Timers.size(); i++) {
if (m_Timers[i]->GetName() == name) { auto& timer = m_Timers[i];
delete m_Timers[i]; if (timer == name) {
m_Timers.erase(m_Timers.begin() + i); m_Timers.erase(m_Timers.begin() + i);
return; return;
} }
@ -1737,21 +1743,10 @@ void Entity::CancelTimer(const std::string& name) {
} }
void Entity::CancelAllTimers() { void Entity::CancelAllTimers() {
/*for (auto timer : m_Timers) {
if (timer) delete timer;
}*/
for (auto* timer : m_Timers) {
delete timer;
}
m_Timers.clear(); m_Timers.clear();
m_PendingTimers.clear();
for (auto* callBackTimer : m_CallbackTimers) {
delete callBackTimer;
}
m_CallbackTimers.clear(); m_CallbackTimers.clear();
m_PendingCallbackTimers.clear();
} }
bool Entity::IsPlayer() const { bool Entity::IsPlayer() const {

View File

@ -160,6 +160,8 @@ public:
void AddChild(Entity* child); void AddChild(Entity* child);
void RemoveChild(Entity* child); void RemoveChild(Entity* child);
void RemoveParent(); void RemoveParent();
// Adds a timer to start next frame with the given name and time.
void AddTimer(std::string name, float time); void AddTimer(std::string name, float time);
void AddCallbackTimer(float time, std::function<void()> callback); void AddCallbackTimer(float time, std::function<void()> callback);
bool HasTimer(const std::string& name); bool HasTimer(const std::string& name);
@ -324,9 +326,10 @@ protected:
std::vector<std::function<void(Entity* target)>> m_PhantomCollisionCallbacks; std::vector<std::function<void(Entity* target)>> m_PhantomCollisionCallbacks;
std::unordered_map<eReplicaComponentType, Component*> m_Components; std::unordered_map<eReplicaComponentType, Component*> m_Components;
std::vector<EntityTimer*> m_Timers; std::vector<EntityTimer> m_Timers;
std::vector<EntityTimer*> m_PendingTimers; std::vector<EntityTimer> m_PendingTimers;
std::vector<EntityCallbackTimer*> m_CallbackTimers; std::vector<EntityCallbackTimer> m_CallbackTimers;
std::vector<EntityCallbackTimer> m_PendingCallbackTimers;
bool m_ShouldDestroyAfterUpdate = false; bool m_ShouldDestroyAfterUpdate = false;

View File

@ -1,22 +1,10 @@
#include "EntityCallbackTimer.h" #include "EntityCallbackTimer.h"
EntityCallbackTimer::EntityCallbackTimer(float time, std::function<void()> callback) { EntityCallbackTimer::EntityCallbackTimer(const float time, const std::function<void()> callback) {
m_Time = time; m_Time = time;
m_Callback = callback; m_Callback = callback;
} }
EntityCallbackTimer::~EntityCallbackTimer() {
}
std::function<void()> EntityCallbackTimer::GetCallback() {
return m_Callback;
}
float EntityCallbackTimer::GetTime() {
return m_Time;
}
void EntityCallbackTimer::Update(float deltaTime) { void EntityCallbackTimer::Update(float deltaTime) {
m_Time -= deltaTime; m_Time -= deltaTime;
} }

View File

@ -5,11 +5,11 @@
class EntityCallbackTimer { class EntityCallbackTimer {
public: public:
EntityCallbackTimer(float time, std::function<void()> callback); EntityCallbackTimer(const float time, const std::function<void()> callback);
~EntityCallbackTimer();
std::function<void()> GetCallback() const { return m_Callback; };
std::function<void()> GetCallback(); float GetTime() const { return m_Time; };
float GetTime();
void Update(float deltaTime); void Update(float deltaTime);

View File

@ -1,14 +1,10 @@
#include "EntityTimer.h" #include "EntityTimer.h"
EntityTimer::EntityTimer(std::string name, float time) { EntityTimer::EntityTimer(const std::string& name, const float time) {
m_Name = name; m_Name = name;
m_Time = time; m_Time = time;
} }
EntityTimer::~EntityTimer() {
}
std::string EntityTimer::GetName() { std::string EntityTimer::GetName() {
return m_Name; return m_Name;
} }

View File

@ -4,8 +4,15 @@
class EntityTimer { class EntityTimer {
public: public:
EntityTimer(std::string name, float time); EntityTimer(const std::string& name, const float time);
~EntityTimer();
bool operator==(const EntityTimer& other) const {
return m_Name == other.m_Name;
}
bool operator==(const std::string& other) const {
return m_Name == other;
}
std::string GetName(); std::string GetName();
float GetTime(); float GetTime();

View File

@ -24,11 +24,17 @@
#include "eServerMessageType.h" #include "eServerMessageType.h"
#include "eMasterMessageType.h" #include "eMasterMessageType.h"
#include "eGameMasterLevel.h" #include "eGameMasterLevel.h"
#include "StringifiedEnum.h"
namespace { namespace {
std::vector<uint32_t> claimCodes; std::vector<uint32_t> claimCodes;
} }
void Stamp::Serialize(RakNet::BitStream* outBitStream){
outBitStream->Write(type);
outBitStream->Write(value);
outBitStream->Write(timestamp);
};
void AuthPackets::LoadClaimCodes() { void AuthPackets::LoadClaimCodes() {
if(!claimCodes.empty()) return; if(!claimCodes.empty()) return;
auto rcstring = Game::config->GetValue("rewardcodes"); auto rcstring = Game::config->GetValue("rewardcodes");
@ -42,12 +48,26 @@ void AuthPackets::LoadClaimCodes() {
} }
void AuthPackets::HandleHandshake(dServer* server, Packet* packet) { void AuthPackets::HandleHandshake(dServer* server, Packet* packet) {
RakNet::BitStream inStream(packet->data, packet->length, false); CINSTREAM_SKIP_HEADER
uint64_t header = inStream.Read(header);
uint32_t clientVersion = 0; uint32_t clientVersion = 0;
inStream.Read(clientVersion); inStream.Read(clientVersion);
inStream.IgnoreBytes(4);
ServiceId serviceId;
inStream.Read(serviceId);
if (serviceId != ServiceId::Client) LOG("WARNING: Service ID is not a Client!");
uint32_t processID;
inStream.Read(processID);
uint16_t port;
inStream.Read(port);
if (port != packet->systemAddress.port) LOG("WARNING: Port written in packet does not match the port the client is connecting over!");
inStream.IgnoreBytes(33);
LOG_DEBUG("Client Data [Version: %i, Service: %s, Process: %u, Port: %u, Sysaddr Port: %u]", clientVersion, StringifiedEnum::ToString(serviceId).data(), processID, port, packet->systemAddress.port);
LOG("Received client version: %i", clientVersion);
SendHandshake(server, packet->systemAddress, server->GetIP(), server->GetPort(), server->GetServerType()); SendHandshake(server, packet->systemAddress, server->GetIP(), server->GetPort(), server->GetServerType());
} }
@ -60,42 +80,93 @@ void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, c
if (!clientNetVersionString.empty()) GeneralUtils::TryParse(clientNetVersionString, clientNetVersion); if (!clientNetVersionString.empty()) GeneralUtils::TryParse(clientNetVersionString, clientNetVersion);
bitStream.Write<uint32_t>(clientNetVersion); bitStream.Write<uint32_t>(clientNetVersion);
bitStream.Write<uint32_t>(0x93); bitStream.Write<uint32_t>(861228100);
if (serverType == ServerType::Auth) bitStream.Write(uint32_t(1)); //Conn: auth if (serverType == ServerType::Auth) bitStream.Write(ServiceId::Auth);
else bitStream.Write<uint32_t>(4); //Conn: world else if (serverType == ServerType::World) bitStream.Write(ServiceId::World);
else bitStream.Write(ServiceId::General);
bitStream.Write<uint32_t>(0); //Server process ID bitStream.Write<uint32_t>(774909490);
bitStream.Write(nextServerPort);
server->Send(&bitStream, sysAddr, false); server->Send(&bitStream, sysAddr, false);
} }
void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) { void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
std::string username = PacketUtils::ReadString(8, packet, true); CINSTREAM_SKIP_HEADER;
std::string password = PacketUtils::ReadString(0x4A, packet, true);
const char* szUsername = username.c_str(); std::vector<Stamp> stamps;
stamps.emplace_back(eStamps::PASSPORT_AUTH_START, 0);
LUWString usernameLUString(33);
inStream.Read(usernameLUString);
const auto username = usernameLUString.GetAsString();
LUWString password(41);
inStream.Read(password);
LanguageCodeID locale_id;
inStream.Read(locale_id);
LOG_DEBUG("Locale ID: %s", StringifiedEnum::ToString(locale_id).data());
ClientOS clientOS;
inStream.Read(clientOS);
LOG_DEBUG("Operating System: %s", StringifiedEnum::ToString(clientOS).data());
stamps.emplace_back(eStamps::PASSPORT_AUTH_CLIENT_OS, 0);
LUWString memoryStats(256);
inStream.Read(memoryStats);
LOG_DEBUG("Memory Stats [%s]", memoryStats.GetAsString().c_str());
LUWString videoCard(128);
inStream.Read(videoCard);
LOG_DEBUG("VideoCard Info: [%s]", videoCard.GetAsString().c_str());
// Processor/CPU info
uint32_t numOfProcessors;
inStream.Read(numOfProcessors);
uint32_t processorType;
inStream.Read(processorType);
uint16_t processorLevel;
inStream.Read(processorLevel);
uint16_t processorRevision;
inStream.Read(processorRevision);
LOG_DEBUG("CPU Info: [#Processors: %i, Processor Type: %i, Processor Level: %i, Processor Revision: %i]", numOfProcessors, processorType, processorLevel, processorRevision);
// OS Info
uint32_t osVersionInfoSize;
inStream.Read(osVersionInfoSize);
uint32_t majorVersion;
inStream.Read(majorVersion);
uint32_t minorVersion;
inStream.Read(minorVersion);
uint32_t buildNumber;
inStream.Read(buildNumber);
uint32_t platformID;
inStream.Read(platformID);
LOG_DEBUG("OS Info: [Size: %i, Major: %i, Minor %i, Buid#: %i, platformID: %i]", osVersionInfoSize, majorVersion, minorVersion, buildNumber, platformID);
// Fetch account details // Fetch account details
auto accountInfo = Database::Get()->GetAccountInfo(username); auto accountInfo = Database::Get()->GetAccountInfo(username);
if (!accountInfo) { if (!accountInfo) {
LOG("No user by name %s found!", username.c_str()); LOG("No user by name %s found!", username.c_str());
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, username); stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, username, stamps);
return; return;
} }
//If we aren't running in live mode, then only GMs are allowed to enter: //If we aren't running in live mode, then only GMs are allowed to enter:
const auto& closedToNonDevs = Game::config->GetValue("closed_to_non_devs"); const auto& closedToNonDevs = Game::config->GetValue("closed_to_non_devs");
if (closedToNonDevs.size() > 0 && bool(std::stoi(closedToNonDevs)) && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) { if (closedToNonDevs.size() > 0 && bool(std::stoi(closedToNonDevs)) && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "The server is currently only open to developers.", "", 2001, username); stamps.emplace_back(eStamps::GM_REQUIRED, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "The server is currently only open to developers.", "", 2001, username, stamps);
return; return;
} }
if (Game::config->GetValue("dont_use_keys") != "1" && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) { if (Game::config->GetValue("dont_use_keys") != "1" && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) {
//Check to see if we have a play key: //Check to see if we have a play key:
if (accountInfo->playKeyId == 0) { if (accountInfo->playKeyId == 0) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username); stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username, stamps);
LOG("User %s tried to log in, but they don't have a play key.", username.c_str()); LOG("User %s tried to log in, but they don't have a play key.", username.c_str());
return; return;
} }
@ -104,40 +175,50 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
auto playKeyStatus = Database::Get()->IsPlaykeyActive(accountInfo->playKeyId); auto playKeyStatus = Database::Get()->IsPlaykeyActive(accountInfo->playKeyId);
if (!playKeyStatus) { if (!playKeyStatus) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a valid play key associated with it!", "", 2001, username); stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a valid play key associated with it!", "", 2001, username, stamps);
return; return;
} }
if (!playKeyStatus.value()) { if (!playKeyStatus.value()) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, username); stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, username, stamps);
LOG("User %s tried to log in, but their play key was disabled", username.c_str()); LOG("User %s tried to log in, but their play key was disabled", username.c_str());
return; return;
} }
} else if (Game::config->GetValue("dont_use_keys") == "1" || accountInfo->maxGmLevel > eGameMasterLevel::CIVILIAN){
stamps.emplace_back(eStamps::PASSPORT_AUTH_BYPASS, 1);
} }
if (accountInfo->banned) { if (accountInfo->banned) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, username); return; stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, username, stamps);
return;
} }
if (accountInfo->locked) { if (accountInfo->locked) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, username); return; stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, username, stamps);
return;
} }
bool loginSuccess = ::bcrypt_checkpw(password.c_str(), accountInfo->bcryptPassword.c_str()) == 0; bool loginSuccess = ::bcrypt_checkpw(password.GetAsString().c_str(), accountInfo->bcryptPassword.c_str()) == 0;
if (!loginSuccess) { if (!loginSuccess) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, username); stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1);
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, username, stamps);
LOG("Wrong password used"); LOG("Wrong password used");
} else { } else {
SystemAddress system = packet->systemAddress; //Copy the sysAddr before the Packet gets destroyed from main SystemAddress system = packet->systemAddress; //Copy the sysAddr before the Packet gets destroyed from main
if (!server->GetIsConnectedToMaster()) { if (!server->GetIsConnectedToMaster()) {
AuthPackets::SendLoginResponse(server, system, eLoginResponse::GENERAL_FAILED, "", "", 0, username); stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_DISCONNECT, 1);
AuthPackets::SendLoginResponse(server, system, eLoginResponse::GENERAL_FAILED, "", "", 0, username, stamps);
return; return;
} }
stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH, 1);
ZoneInstanceManager::Instance()->RequestZoneTransfer(server, 0, 0, false, [system, server, username](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string zoneIP, uint16_t zonePort) { ZoneInstanceManager::Instance()->RequestZoneTransfer(server, 0, 0, false, [system, server, username, stamps](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string zoneIP, uint16_t zonePort) mutable {
AuthPackets::SendLoginResponse(server, system, eLoginResponse::SUCCESS, "", zoneIP, zonePort, username); AuthPackets::SendLoginResponse(server, system, eLoginResponse::SUCCESS, "", zoneIP, zonePort, username, stamps);
}); });
} }
@ -146,21 +227,22 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
} }
} }
void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username) { void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username, std::vector<Stamp>& stamps) {
RakNet::BitStream packet; stamps.emplace_back(eStamps::PASSPORT_AUTH_IM_LOGIN_START, 1);
BitStreamUtils::WriteHeader(packet, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE); RakNet::BitStream loginResponse;
BitStreamUtils::WriteHeader(loginResponse, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE);
packet.Write<uint8_t>(GeneralUtils::CastUnderlyingType(responseCode)); loginResponse.Write<uint8_t>(GeneralUtils::CastUnderlyingType(responseCode));
// Event Gating // Event Gating
packet.Write(LUString(Game::config->GetValue("event_1"))); loginResponse.Write(LUString(Game::config->GetValue("event_1")));
packet.Write(LUString(Game::config->GetValue("event_2"))); loginResponse.Write(LUString(Game::config->GetValue("event_2")));
packet.Write(LUString(Game::config->GetValue("event_3"))); loginResponse.Write(LUString(Game::config->GetValue("event_3")));
packet.Write(LUString(Game::config->GetValue("event_4"))); loginResponse.Write(LUString(Game::config->GetValue("event_4")));
packet.Write(LUString(Game::config->GetValue("event_5"))); loginResponse.Write(LUString(Game::config->GetValue("event_5")));
packet.Write(LUString(Game::config->GetValue("event_6"))); loginResponse.Write(LUString(Game::config->GetValue("event_6")));
packet.Write(LUString(Game::config->GetValue("event_7"))); loginResponse.Write(LUString(Game::config->GetValue("event_7")));
packet.Write(LUString(Game::config->GetValue("event_8"))); loginResponse.Write(LUString(Game::config->GetValue("event_8")));
uint16_t version_major = 1; uint16_t version_major = 1;
uint16_t version_current = 10; uint16_t version_current = 10;
@ -169,53 +251,52 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd
GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_current"), version_current); GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_current"), version_current);
GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_minor"), version_minor); GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_minor"), version_minor);
packet.Write(version_major); loginResponse.Write(version_major);
packet.Write(version_current); loginResponse.Write(version_current);
packet.Write(version_minor); loginResponse.Write(version_minor);
// Writes the user key // Writes the user key
uint32_t sessionKey = GeneralUtils::GenerateRandomNumber<uint32_t>(); uint32_t sessionKey = GeneralUtils::GenerateRandomNumber<uint32_t>();
std::string userHash = std::to_string(sessionKey); std::string userHash = std::to_string(sessionKey);
userHash = md5(userHash); userHash = md5(userHash);
packet.Write(LUWString(userHash)); loginResponse.Write(LUWString(userHash));
// Write the Character and Chat IPs // World Server IP
packet.Write(LUString(wServerIP)); loginResponse.Write(LUString(wServerIP));
packet.Write(LUString("")); // Chat Server IP (unused)
loginResponse.Write(LUString(""));
// Write the Character and Chat Ports // World Server Redirect port
packet.Write<uint16_t>(wServerPort); loginResponse.Write(wServerPort);
packet.Write<uint16_t>(0); // Char Server Redirect port (unused)
loginResponse.Write(static_cast<uint16_t>(0));
// CDN Key // CDN Key
packet.Write(LUString("")); loginResponse.Write(LUString(""));
// CDN Ticket // CDN Ticket
packet.Write(LUString("00000000-0000-0000-0000-000000000000", 37)); loginResponse.Write(LUString("00000000-0000-0000-0000-000000000000", 37));
packet.Write<uint32_t>(0); // Language // Language
loginResponse.Write(Language::en_US);
// Write the localization // Write the localization
packet.Write(LUString("US", 3)); loginResponse.Write(LUString("US", 3));
packet.Write<uint8_t>(false); // Just upgraded from F2P loginResponse.Write<uint8_t>(false); // Just upgraded from F2P
packet.Write<uint8_t>(false); // User is F2P loginResponse.Write<uint8_t>(false); // User is F2P
packet.Write<uint64_t>(0); // Time Remaining in F2P loginResponse.Write<uint64_t>(0); // Time Remaining in F2P
// Write custom error message // Write custom error message
packet.Write<uint16_t>(errorMsg.length()); loginResponse.Write<uint16_t>(errorMsg.length());
packet.Write(LUWString(errorMsg, static_cast<uint32_t>(errorMsg.length()))); loginResponse.Write(LUWString(errorMsg, static_cast<uint32_t>(errorMsg.length())));
// Here write auth logs stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH, 1);
packet.Write<uint32_t>(20);
for (uint32_t i = 0; i < 20; ++i) {
packet.Write<uint32_t>(8);
packet.Write<uint32_t>(44);
packet.Write<uint32_t>(14000);
packet.Write<uint32_t>(0);
}
server->Send(&packet, sysAddr, false); loginResponse.Write<uint32_t>((sizeof(Stamp) * stamps.size()) + sizeof(uint32_t));
for (auto& stamp : stamps) stamp.Serialize(&loginResponse);
server->Send(&loginResponse, sysAddr, false);
//Inform the master server that we've created a session for this user: //Inform the master server that we've created a session for this user:
if (responseCode == eLoginResponse::SUCCESS) { if (responseCode == eLoginResponse::SUCCESS) {

View File

@ -4,17 +4,99 @@
#define _VARIADIC_MAX 10 #define _VARIADIC_MAX 10
#include "dCommonVars.h" #include "dCommonVars.h"
#include "dNetCommon.h" #include "dNetCommon.h"
#include "magic_enum.hpp"
enum class ServerType : uint32_t; enum class ServerType : uint32_t;
enum class eLoginResponse : uint8_t; enum class eLoginResponse : uint8_t;
class dServer; class dServer;
enum class eStamps : uint32_t {
PASSPORT_AUTH_START,
PASSPORT_AUTH_BYPASS,
PASSPORT_AUTH_ERROR,
PASSPORT_AUTH_DB_SELECT_START,
PASSPORT_AUTH_DB_SELECT_FINISH,
PASSPORT_AUTH_DB_INSERT_START,
PASSPORT_AUTH_DB_INSERT_FINISH,
PASSPORT_AUTH_LEGOINT_COMMUNICATION_START,
PASSPORT_AUTH_LEGOINT_RECEIVED,
PASSPORT_AUTH_LEGOINT_THREAD_SPAWN,
PASSPORT_AUTH_LEGOINT_WEBSERVICE_START,
PASSPORT_AUTH_LEGOINT_WEBSERVICE_FINISH,
PASSPORT_AUTH_LEGOINT_LEGOCLUB_START,
PASSPORT_AUTH_LEGOINT_LEGOCLUB_FINISH,
PASSPORT_AUTH_LEGOINT_THREAD_FINISH,
PASSPORT_AUTH_LEGOINT_REPLY,
PASSPORT_AUTH_LEGOINT_ERROR,
PASSPORT_AUTH_LEGOINT_COMMUNICATION_END,
PASSPORT_AUTH_LEGOINT_DISCONNECT,
PASSPORT_AUTH_WORLD_COMMUNICATION_START,
PASSPORT_AUTH_CLIENT_OS,
PASSPORT_AUTH_WORLD_PACKET_RECEIVED,
PASSPORT_AUTH_IM_COMMUNICATION_START,
PASSPORT_AUTH_IM_LOGIN_START,
PASSPORT_AUTH_IM_LOGIN_ALREADY_LOGGED_IN,
PASSPORT_AUTH_IM_OTHER_LOGIN_REMOVED,
PASSPORT_AUTH_IM_LOGIN_QUEUED,
PASSPORT_AUTH_IM_LOGIN_RESPONSE,
PASSPORT_AUTH_IM_COMMUNICATION_END,
PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH,
PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH,
PASSPORT_AUTH_WORLD_DISCONNECT,
NO_LEGO_INTERFACE,
DB_ERROR,
GM_REQUIRED,
NO_LEGO_WEBSERVICE_XML,
LEGO_WEBSERVICE_TIMEOUT,
LEGO_WEBSERVICE_ERROR,
NO_WORLD_SERVER
};
struct Stamp {
eStamps type;
uint32_t value;
uint64_t timestamp;
Stamp(eStamps type, uint32_t value, uint64_t timestamp = time(nullptr)){
this->type = type;
this->value = value;
this->timestamp = timestamp;
}
void Serialize(RakNet::BitStream* outBitStream);
};
enum class ClientOS : uint8_t {
UNKNOWN,
WINDOWS,
MACOS
};
enum class LanguageCodeID : uint16_t {
de_DE = 0x0407,
en_US = 0x0409,
en_GB = 0x0809
};
template <>
struct magic_enum::customize::enum_range<LanguageCodeID> {
static constexpr int min = 1031;
static constexpr int max = 2057;
};
enum class Language : uint32_t {
en_US,
pl_US,
de_DE,
en_GB,
};
namespace AuthPackets { namespace AuthPackets {
void HandleHandshake(dServer* server, Packet* packet); void HandleHandshake(dServer* server, Packet* packet);
void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType); void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType);
void HandleLoginRequest(dServer* server, Packet* packet); void HandleLoginRequest(dServer* server, Packet* packet);
void SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username); void SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username, std::vector<Stamp>& stamps);
void LoadClaimCodes(); void LoadClaimCodes();
} }

View File

@ -16,6 +16,14 @@ enum class ServerType : uint32_t {
World World
}; };
enum class ServiceId : uint32_t{
General = 0,
Auth = 1,
Chat = 2,
World = 4,
Client = 5,
};
namespace Game { namespace Game {
using signal_t = volatile std::sig_atomic_t; using signal_t = volatile std::sig_atomic_t;
} }