mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-01-29 06:59:54 +00:00
Merge branch 'main' into fix/cmake-libs-2
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
#include "AuthPackets.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "BitStreamUtils.h"
|
||||
|
||||
#include "dNetCommon.h"
|
||||
@@ -24,11 +23,17 @@
|
||||
#include "eServerMessageType.h"
|
||||
#include "eMasterMessageType.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
|
||||
#include "StringifiedEnum.h"
|
||||
namespace {
|
||||
std::vector<uint32_t> claimCodes;
|
||||
}
|
||||
|
||||
void Stamp::Serialize(RakNet::BitStream* outBitStream){
|
||||
outBitStream->Write(type);
|
||||
outBitStream->Write(value);
|
||||
outBitStream->Write(timestamp);
|
||||
};
|
||||
|
||||
void AuthPackets::LoadClaimCodes() {
|
||||
if(!claimCodes.empty()) return;
|
||||
auto rcstring = Game::config->GetValue("rewardcodes");
|
||||
@@ -42,12 +47,26 @@ void AuthPackets::LoadClaimCodes() {
|
||||
}
|
||||
|
||||
void AuthPackets::HandleHandshake(dServer* server, Packet* packet) {
|
||||
RakNet::BitStream inStream(packet->data, packet->length, false);
|
||||
uint64_t header = inStream.Read(header);
|
||||
CINSTREAM_SKIP_HEADER
|
||||
uint32_t clientVersion = 0;
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -60,42 +79,93 @@ void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, c
|
||||
if (!clientNetVersionString.empty()) GeneralUtils::TryParse(clientNetVersionString, 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
|
||||
else bitStream.Write<uint32_t>(4); //Conn: world
|
||||
|
||||
bitStream.Write<uint32_t>(0); //Server process ID
|
||||
bitStream.Write(nextServerPort);
|
||||
if (serverType == ServerType::Auth) bitStream.Write(ServiceId::Auth);
|
||||
else if (serverType == ServerType::World) bitStream.Write(ServiceId::World);
|
||||
else bitStream.Write(ServiceId::General);
|
||||
bitStream.Write<uint32_t>(774909490);
|
||||
|
||||
server->Send(&bitStream, sysAddr, false);
|
||||
}
|
||||
|
||||
void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
|
||||
std::string username = PacketUtils::ReadString(8, packet, true);
|
||||
std::string password = PacketUtils::ReadString(0x4A, packet, true);
|
||||
const char* szUsername = username.c_str();
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
std::vector<Stamp> stamps;
|
||||
stamps.emplace_back(eStamps::PASSPORT_AUTH_START, 0);
|
||||
|
||||
LUWString usernameLUString;
|
||||
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
|
||||
auto accountInfo = Database::Get()->GetAccountInfo(username);
|
||||
|
||||
if (!accountInfo) {
|
||||
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;
|
||||
}
|
||||
|
||||
//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");
|
||||
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;
|
||||
}
|
||||
|
||||
if (Game::config->GetValue("dont_use_keys") != "1" && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) {
|
||||
//Check to see if we have a play key:
|
||||
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());
|
||||
return;
|
||||
}
|
||||
@@ -104,40 +174,50 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
|
||||
auto playKeyStatus = Database::Get()->IsPlaykeyActive(accountInfo->playKeyId);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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());
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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");
|
||||
} else {
|
||||
SystemAddress system = packet->systemAddress; //Copy the sysAddr before the Packet gets destroyed from main
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
AuthPackets::SendLoginResponse(server, system, eLoginResponse::SUCCESS, "", zoneIP, zonePort, username);
|
||||
stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH, 1);
|
||||
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, stamps);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -146,21 +226,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) {
|
||||
RakNet::BitStream packet;
|
||||
BitStreamUtils::WriteHeader(packet, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE);
|
||||
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) {
|
||||
stamps.emplace_back(eStamps::PASSPORT_AUTH_IM_LOGIN_START, 1);
|
||||
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
|
||||
packet.Write(LUString(Game::config->GetValue("event_1")));
|
||||
packet.Write(LUString(Game::config->GetValue("event_2")));
|
||||
packet.Write(LUString(Game::config->GetValue("event_3")));
|
||||
packet.Write(LUString(Game::config->GetValue("event_4")));
|
||||
packet.Write(LUString(Game::config->GetValue("event_5")));
|
||||
packet.Write(LUString(Game::config->GetValue("event_6")));
|
||||
packet.Write(LUString(Game::config->GetValue("event_7")));
|
||||
packet.Write(LUString(Game::config->GetValue("event_8")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_1")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_2")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_3")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_4")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_5")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_6")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_7")));
|
||||
loginResponse.Write(LUString(Game::config->GetValue("event_8")));
|
||||
|
||||
uint16_t version_major = 1;
|
||||
uint16_t version_current = 10;
|
||||
@@ -169,60 +250,58 @@ 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_minor"), version_minor);
|
||||
|
||||
packet.Write(version_major);
|
||||
packet.Write(version_current);
|
||||
packet.Write(version_minor);
|
||||
loginResponse.Write(version_major);
|
||||
loginResponse.Write(version_current);
|
||||
loginResponse.Write(version_minor);
|
||||
|
||||
// Writes the user key
|
||||
uint32_t sessionKey = GeneralUtils::GenerateRandomNumber<uint32_t>();
|
||||
std::string userHash = std::to_string(sessionKey);
|
||||
userHash = md5(userHash);
|
||||
packet.Write(LUWString(userHash));
|
||||
loginResponse.Write(LUWString(userHash));
|
||||
|
||||
// Write the Character and Chat IPs
|
||||
packet.Write(LUString(wServerIP));
|
||||
packet.Write(LUString(""));
|
||||
// World Server IP
|
||||
loginResponse.Write(LUString(wServerIP));
|
||||
// Chat Server IP (unused)
|
||||
loginResponse.Write(LUString(""));
|
||||
|
||||
// Write the Character and Chat Ports
|
||||
packet.Write<uint16_t>(wServerPort);
|
||||
packet.Write<uint16_t>(0);
|
||||
// World Server Redirect port
|
||||
loginResponse.Write(wServerPort);
|
||||
// Char Server Redirect port (unused)
|
||||
loginResponse.Write(static_cast<uint16_t>(0));
|
||||
|
||||
// CDN Key
|
||||
packet.Write(LUString(""));
|
||||
loginResponse.Write(LUString(""));
|
||||
|
||||
// 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
|
||||
packet.Write(LUString("US", 3));
|
||||
loginResponse.Write(LUString("US", 3));
|
||||
|
||||
packet.Write<uint8_t>(false); // Just upgraded from F2P
|
||||
packet.Write<uint8_t>(false); // User is F2P
|
||||
packet.Write<uint64_t>(0); // Time Remaining in F2P
|
||||
loginResponse.Write<uint8_t>(false); // Just upgraded from F2P
|
||||
loginResponse.Write<uint8_t>(false); // User is F2P
|
||||
loginResponse.Write<uint64_t>(0); // Time Remaining in F2P
|
||||
|
||||
// Write custom error message
|
||||
packet.Write<uint16_t>(errorMsg.length());
|
||||
packet.Write(LUWString(errorMsg, static_cast<uint32_t>(errorMsg.length())));
|
||||
loginResponse.Write<uint16_t>(errorMsg.length());
|
||||
loginResponse.Write(LUWString(errorMsg, static_cast<uint32_t>(errorMsg.length())));
|
||||
|
||||
// Here write auth logs
|
||||
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);
|
||||
}
|
||||
stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH, 1);
|
||||
|
||||
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:
|
||||
if (responseCode == eLoginResponse::SUCCESS) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY);
|
||||
bitStream.Write(sessionKey);
|
||||
bitStream.Write(LUString(username, 66));
|
||||
bitStream.Write(LUString(username));
|
||||
server->SendToMaster(&bitStream);
|
||||
|
||||
LOG("Set sessionKey: %i for user %s", sessionKey, username.c_str());
|
||||
|
||||
@@ -4,17 +4,99 @@
|
||||
#define _VARIADIC_MAX 10
|
||||
#include "dCommonVars.h"
|
||||
#include "dNetCommon.h"
|
||||
#include "magic_enum.hpp"
|
||||
|
||||
enum class ServerType : uint32_t;
|
||||
enum class eLoginResponse : uint8_t;
|
||||
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 {
|
||||
void HandleHandshake(dServer* server, Packet* packet);
|
||||
void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType);
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ struct LUString {
|
||||
std::string string;
|
||||
uint32_t size;
|
||||
|
||||
LUString(uint32_t size) {
|
||||
LUString(uint32_t size = 33) {
|
||||
this->size = size;
|
||||
};
|
||||
LUString(std::string string, uint32_t size = 33) {
|
||||
@@ -28,7 +28,7 @@ struct LUWString {
|
||||
std::u16string string;
|
||||
uint32_t size;
|
||||
|
||||
LUWString(uint32_t size) {
|
||||
LUWString(uint32_t size = 33) {
|
||||
this->size = size;
|
||||
};
|
||||
LUWString(std::u16string string, uint32_t size = 33) {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "RakNetTypes.h"
|
||||
#include "BitStream.h"
|
||||
#include "Game.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dServer.h"
|
||||
#include "eConnectionType.h"
|
||||
|
||||
@@ -4,422 +4,120 @@
|
||||
*/
|
||||
|
||||
#include "ClientPackets.h"
|
||||
#include "UserManager.h"
|
||||
#include "User.h"
|
||||
#include "Character.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Entity.h"
|
||||
#include "ControllablePhysicsComponent.h"
|
||||
#include "Game.h"
|
||||
#include "Logger.h"
|
||||
#include "WorldPackets.h"
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "BitStream.h"
|
||||
#include "dChatFilter.h"
|
||||
#include "WorldPackets.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "dServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "Player.h"
|
||||
#include "Zone.h"
|
||||
#include "PossessorComponent.h"
|
||||
#include "PossessableComponent.h"
|
||||
#include "HavokVehiclePhysicsComponent.h"
|
||||
#include "dConfig.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "Database.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "CheatDetection.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) {
|
||||
User* user = UserManager::Instance()->GetUser(sysAddr);
|
||||
if (!user) {
|
||||
LOG("Unable to get user to parse chat message");
|
||||
return;
|
||||
}
|
||||
|
||||
if (user->GetIsMuted()) {
|
||||
user->GetLastUsedChar()->SendMuteNotice();
|
||||
return;
|
||||
}
|
||||
#include "PositionUpdate.h"
|
||||
|
||||
ChatMessage ClientPackets::HandleChatMessage(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
char chatChannel;
|
||||
uint16_t unknown;
|
||||
ChatMessage message;
|
||||
uint32_t messageLength;
|
||||
std::u16string message;
|
||||
|
||||
inStream.Read(chatChannel);
|
||||
inStream.Read(unknown);
|
||||
inStream.Read(message.chatChannel);
|
||||
inStream.Read(message.unknown);
|
||||
inStream.Read(messageLength);
|
||||
|
||||
for (uint32_t i = 0; i < (messageLength - 1); ++i) {
|
||||
uint16_t character;
|
||||
inStream.Read(character);
|
||||
message.push_back(character);
|
||||
message.message.push_back(character);
|
||||
}
|
||||
|
||||
std::string playerName = user->GetLastUsedChar()->GetName();
|
||||
bool isMythran = user->GetLastUsedChar()->GetGMLevel() > eGameMasterLevel::CIVILIAN;
|
||||
bool isOk = Game::chatFilter->IsSentenceOkay(GeneralUtils::UTF16ToWTF8(message), user->GetLastUsedChar()->GetGMLevel()).empty();
|
||||
LOG_DEBUG("Msg: %s was approved previously? %i", GeneralUtils::UTF16ToWTF8(message).c_str(), user->GetLastChatMessageApproved());
|
||||
if (!isOk) {
|
||||
// Add a limit to the string converted by general utils because it is a user received string and may be a bad actor.
|
||||
CheatDetection::ReportCheat(
|
||||
user,
|
||||
sysAddr,
|
||||
"Player %s attempted to bypass chat filter with message: %s",
|
||||
playerName.c_str(),
|
||||
GeneralUtils::UTF16ToWTF8(message, 512).c_str());
|
||||
}
|
||||
if (!isOk && !isMythran) return;
|
||||
|
||||
std::string sMessage = GeneralUtils::UTF16ToWTF8(message);
|
||||
LOG("%s: %s", playerName.c_str(), sMessage.c_str());
|
||||
ChatPackets::SendChatMessage(sysAddr, chatChannel, playerName, user->GetLoggedInChar(), isMythran, message);
|
||||
return message;
|
||||
}
|
||||
|
||||
void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Packet* packet) {
|
||||
User* user = UserManager::Instance()->GetUser(sysAddr);
|
||||
if (!user) {
|
||||
LOG("Unable to get user to parse position update");
|
||||
return;
|
||||
}
|
||||
|
||||
PositionUpdate ClientPackets::HandleClientPositionUpdate(Packet* packet) {
|
||||
PositionUpdate update;
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
Entity* entity = Game::entityManager->GetEntity(user->GetLastUsedChar()->GetObjectID());
|
||||
if (!entity) return;
|
||||
inStream.Read(update.position.x);
|
||||
inStream.Read(update.position.y);
|
||||
inStream.Read(update.position.z);
|
||||
|
||||
ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS));
|
||||
if (!comp) return;
|
||||
inStream.Read(update.rotation.x);
|
||||
inStream.Read(update.rotation.y);
|
||||
inStream.Read(update.rotation.z);
|
||||
inStream.Read(update.rotation.w);
|
||||
|
||||
/*
|
||||
//If we didn't move, this will match and stop our velocity
|
||||
if (packet->length == 37) {
|
||||
NiPoint3 zeroVel(0.0f, 0.0f, 0.0f);
|
||||
comp->SetVelocity(zeroVel);
|
||||
comp->SetAngularVelocity(zeroVel);
|
||||
comp->SetIsOnGround(true); //probably8
|
||||
Game::entityManager->SerializeEntity(entity);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
auto* possessorComponent = entity->GetComponent<PossessorComponent>();
|
||||
|
||||
NiPoint3 position;
|
||||
inStream.Read(position.x);
|
||||
inStream.Read(position.y);
|
||||
inStream.Read(position.z);
|
||||
|
||||
NiQuaternion rotation;
|
||||
inStream.Read(rotation.x);
|
||||
inStream.Read(rotation.y);
|
||||
inStream.Read(rotation.z);
|
||||
inStream.Read(rotation.w);
|
||||
|
||||
bool onGround = false;
|
||||
bool onRail = false;
|
||||
inStream.Read(onGround);
|
||||
inStream.Read(onRail);
|
||||
inStream.Read(update.onGround);
|
||||
inStream.Read(update.onRail);
|
||||
|
||||
bool velocityFlag = false;
|
||||
inStream.Read(velocityFlag);
|
||||
NiPoint3 velocity{};
|
||||
if (velocityFlag) {
|
||||
inStream.Read(velocity.x);
|
||||
inStream.Read(velocity.y);
|
||||
inStream.Read(velocity.z);
|
||||
inStream.Read(update.velocity.x);
|
||||
inStream.Read(update.velocity.y);
|
||||
inStream.Read(update.velocity.z);
|
||||
}
|
||||
|
||||
bool angVelocityFlag = false;
|
||||
inStream.Read(angVelocityFlag);
|
||||
NiPoint3 angVelocity{};
|
||||
if (angVelocityFlag) {
|
||||
inStream.Read(angVelocity.x);
|
||||
inStream.Read(angVelocity.y);
|
||||
inStream.Read(angVelocity.z);
|
||||
inStream.Read(update.angularVelocity.x);
|
||||
inStream.Read(update.angularVelocity.y);
|
||||
inStream.Read(update.angularVelocity.z);
|
||||
}
|
||||
|
||||
// TODO figure out how to use these. Ignoring for now, but reading in if they exist.
|
||||
bool hasLocalSpaceInfo{};
|
||||
LWOOBJID objectId{};
|
||||
NiPoint3 localSpacePosition{};
|
||||
bool hasLinearVelocity{};
|
||||
NiPoint3 linearVelocity{};
|
||||
if (inStream.Read(hasLocalSpaceInfo) && hasLocalSpaceInfo) {
|
||||
inStream.Read(objectId);
|
||||
inStream.Read(localSpacePosition.x);
|
||||
inStream.Read(localSpacePosition.y);
|
||||
inStream.Read(localSpacePosition.z);
|
||||
inStream.Read(update.localSpaceInfo.objectId);
|
||||
inStream.Read(update.localSpaceInfo.position.x);
|
||||
inStream.Read(update.localSpaceInfo.position.y);
|
||||
inStream.Read(update.localSpaceInfo.position.z);
|
||||
bool hasLinearVelocity = false;
|
||||
if (inStream.Read(hasLinearVelocity) && hasLinearVelocity) {
|
||||
inStream.Read(linearVelocity.x);
|
||||
inStream.Read(linearVelocity.y);
|
||||
inStream.Read(linearVelocity.z);
|
||||
inStream.Read(update.localSpaceInfo.linearVelocity.x);
|
||||
inStream.Read(update.localSpaceInfo.linearVelocity.y);
|
||||
inStream.Read(update.localSpaceInfo.linearVelocity.z);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasRemoteInputInfo{};
|
||||
RemoteInputInfo remoteInput{};
|
||||
|
||||
if (inStream.Read(hasRemoteInputInfo) && hasRemoteInputInfo) {
|
||||
inStream.Read(remoteInput.m_RemoteInputX);
|
||||
inStream.Read(remoteInput.m_RemoteInputY);
|
||||
inStream.Read(remoteInput.m_IsPowersliding);
|
||||
inStream.Read(remoteInput.m_IsModified);
|
||||
inStream.Read(update.remoteInputInfo.m_RemoteInputX);
|
||||
inStream.Read(update.remoteInputInfo.m_RemoteInputY);
|
||||
inStream.Read(update.remoteInputInfo.m_IsPowersliding);
|
||||
inStream.Read(update.remoteInputInfo.m_IsModified);
|
||||
}
|
||||
|
||||
bool updateChar = true;
|
||||
|
||||
if (possessorComponent != nullptr) {
|
||||
auto* possassableEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable());
|
||||
|
||||
if (possassableEntity != nullptr) {
|
||||
auto* possessableComponent = possassableEntity->GetComponent<PossessableComponent>();
|
||||
if (possessableComponent) {
|
||||
// While possessing something, only update char if we are attached to the thing we are possessing
|
||||
if (possessableComponent->GetPossessionType() != ePossessionType::ATTACHED_VISIBLE) updateChar = false;
|
||||
}
|
||||
|
||||
auto* havokVehiclePhysicsComponent = possassableEntity->GetComponent<HavokVehiclePhysicsComponent>();
|
||||
if (havokVehiclePhysicsComponent != nullptr) {
|
||||
havokVehiclePhysicsComponent->SetPosition(position);
|
||||
havokVehiclePhysicsComponent->SetRotation(rotation);
|
||||
havokVehiclePhysicsComponent->SetIsOnGround(onGround);
|
||||
havokVehiclePhysicsComponent->SetIsOnRail(onRail);
|
||||
havokVehiclePhysicsComponent->SetVelocity(velocity);
|
||||
havokVehiclePhysicsComponent->SetDirtyVelocity(velocityFlag);
|
||||
havokVehiclePhysicsComponent->SetAngularVelocity(angVelocity);
|
||||
havokVehiclePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag);
|
||||
havokVehiclePhysicsComponent->SetRemoteInputInfo(remoteInput);
|
||||
} else {
|
||||
// Need to get the mount's controllable physics
|
||||
auto* controllablePhysicsComponent = possassableEntity->GetComponent<ControllablePhysicsComponent>();
|
||||
if (!controllablePhysicsComponent) return;
|
||||
controllablePhysicsComponent->SetPosition(position);
|
||||
controllablePhysicsComponent->SetRotation(rotation);
|
||||
controllablePhysicsComponent->SetIsOnGround(onGround);
|
||||
controllablePhysicsComponent->SetIsOnRail(onRail);
|
||||
controllablePhysicsComponent->SetVelocity(velocity);
|
||||
controllablePhysicsComponent->SetDirtyVelocity(velocityFlag);
|
||||
controllablePhysicsComponent->SetAngularVelocity(angVelocity);
|
||||
controllablePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag);
|
||||
}
|
||||
Game::entityManager->SerializeEntity(possassableEntity);
|
||||
}
|
||||
}
|
||||
|
||||
if (!updateChar) {
|
||||
velocity = NiPoint3::ZERO;
|
||||
angVelocity = NiPoint3::ZERO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Handle statistics
|
||||
auto* characterComponent = entity->GetComponent<CharacterComponent>();
|
||||
if (characterComponent != nullptr) {
|
||||
characterComponent->TrackPositionUpdate(position);
|
||||
}
|
||||
|
||||
comp->SetPosition(position);
|
||||
comp->SetRotation(rotation);
|
||||
comp->SetIsOnGround(onGround);
|
||||
comp->SetIsOnRail(onRail);
|
||||
comp->SetVelocity(velocity);
|
||||
comp->SetDirtyVelocity(velocityFlag);
|
||||
comp->SetAngularVelocity(angVelocity);
|
||||
comp->SetDirtyAngularVelocity(angVelocityFlag);
|
||||
|
||||
auto* player = static_cast<Player*>(entity);
|
||||
player->SetGhostReferencePoint(position);
|
||||
Game::entityManager->QueueGhostUpdate(player->GetObjectID());
|
||||
|
||||
if (updateChar) Game::entityManager->SerializeEntity(entity);
|
||||
|
||||
//TODO: add moving platform stuffs
|
||||
/*bool movingPlatformFlag;
|
||||
inStream.Read(movingPlatformFlag);
|
||||
if (movingPlatformFlag) {
|
||||
LWOOBJID objectID;
|
||||
NiPoint3 niData2;
|
||||
|
||||
inStream.Read(objectID);
|
||||
inStream.Read(niData2.x);
|
||||
inStream.Read(niData2.y);
|
||||
inStream.Read(niData2.z);
|
||||
|
||||
|
||||
|
||||
bool niData3Flag;
|
||||
inStream.Read(niData3Flag);
|
||||
if (niData3Flag) {
|
||||
NiPoint3 niData3;
|
||||
inStream.Read(niData3.x);
|
||||
inStream.Read(niData3.y);
|
||||
inStream.Read(niData3.z);
|
||||
|
||||
controllablePhysics->GetLocationData()->GetMovingPlatformData()->SetData3(niData3);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
for (int i = 0; i < Game::server->GetReplicaManager()->GetParticipantCount(); ++i)
|
||||
{
|
||||
const auto& player = Game::server->GetReplicaManager()->GetParticipantAtIndex(i);
|
||||
|
||||
if (entity->GetSystemAddress() == player)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(entity, player);
|
||||
}
|
||||
*/
|
||||
return update;
|
||||
}
|
||||
|
||||
void ClientPackets::HandleChatModerationRequest(const SystemAddress& sysAddr, Packet* packet) {
|
||||
User* user = UserManager::Instance()->GetUser(sysAddr);
|
||||
if (!user) {
|
||||
LOG("Unable to get user to parse chat moderation request");
|
||||
return;
|
||||
}
|
||||
ChatModerationRequest ClientPackets::HandleChatModerationRequest(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
ChatModerationRequest request;
|
||||
|
||||
auto* entity = Player::GetPlayer(sysAddr);
|
||||
|
||||
if (entity == nullptr) {
|
||||
LOG("Unable to get player to parse chat moderation request");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the player has restricted chat access
|
||||
auto* character = entity->GetCharacter();
|
||||
|
||||
if (character->HasPermission(ePermissionMap::RestrictedChatAccess)) {
|
||||
// Send a message to the player
|
||||
ChatPackets::SendSystemMessage(
|
||||
sysAddr,
|
||||
u"This character has restricted chat access."
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RakNet::BitStream stream(packet->data, packet->length, false);
|
||||
|
||||
uint64_t header;
|
||||
stream.Read(header);
|
||||
|
||||
// Data
|
||||
uint8_t chatLevel;
|
||||
uint8_t requestID;
|
||||
uint16_t messageLength;
|
||||
|
||||
std::string receiver = "";
|
||||
std::string message = "";
|
||||
|
||||
stream.Read(chatLevel);
|
||||
stream.Read(requestID);
|
||||
inStream.Read(request.chatLevel);
|
||||
inStream.Read(request.requestID);
|
||||
|
||||
for (uint32_t i = 0; i < 42; ++i) {
|
||||
uint16_t character;
|
||||
stream.Read(character);
|
||||
receiver.push_back(static_cast<uint8_t>(character));
|
||||
inStream.Read(character);
|
||||
request.receiver.push_back(static_cast<uint8_t>(character));
|
||||
}
|
||||
|
||||
if (!receiver.empty()) {
|
||||
if (std::string(receiver.c_str(), 4) == "[GM]") { // Shift the string forward if we are speaking to a GM as the client appends "[GM]" if they are
|
||||
receiver = std::string(receiver.c_str() + 4, receiver.size() - 4);
|
||||
if (!request.receiver.empty()) {
|
||||
if (std::string(request.receiver.c_str(), 4) == "[GM]") { // Shift the string forward if we are speaking to a GM as the client appends "[GM]" if they are
|
||||
request.receiver = std::string(request.receiver.c_str() + 4, request.receiver.size() - 4);
|
||||
}
|
||||
}
|
||||
|
||||
stream.Read(messageLength);
|
||||
uint16_t messageLength;
|
||||
inStream.Read(messageLength);
|
||||
for (uint32_t i = 0; i < messageLength; ++i) {
|
||||
uint16_t character;
|
||||
stream.Read(character);
|
||||
message.push_back(static_cast<uint8_t>(character));
|
||||
inStream.Read(character);
|
||||
request.message.push_back(static_cast<uint8_t>(character));
|
||||
}
|
||||
|
||||
bool isBestFriend = false;
|
||||
|
||||
if (chatLevel == 1) {
|
||||
// Private chat
|
||||
LWOOBJID idOfReceiver = LWOOBJID_EMPTY;
|
||||
|
||||
{
|
||||
auto characterIdFetch = Database::Get()->GetCharacterInfo(receiver);
|
||||
|
||||
if (characterIdFetch) {
|
||||
idOfReceiver = characterIdFetch->id;
|
||||
}
|
||||
}
|
||||
const auto& bffMap = user->GetIsBestFriendMap();
|
||||
if (bffMap.find(receiver) == bffMap.end() && idOfReceiver != LWOOBJID_EMPTY) {
|
||||
auto bffInfo = Database::Get()->GetBestFriendStatus(entity->GetObjectID(), idOfReceiver);
|
||||
|
||||
if (bffInfo) {
|
||||
isBestFriend = bffInfo->bestFriendStatus == 3;
|
||||
}
|
||||
|
||||
if (isBestFriend) {
|
||||
user->UpdateBestFriendValue(receiver, true);
|
||||
}
|
||||
} else if (bffMap.find(receiver) != bffMap.end()) {
|
||||
isBestFriend = true;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<uint8_t, uint8_t>> segments = Game::chatFilter->IsSentenceOkay(message, entity->GetGMLevel(), !(isBestFriend && chatLevel == 1));
|
||||
|
||||
bool bAllClean = segments.empty();
|
||||
|
||||
if (user->GetIsMuted()) {
|
||||
bAllClean = false;
|
||||
}
|
||||
|
||||
user->SetLastChatMessageApproved(bAllClean);
|
||||
WorldPackets::SendChatModerationResponse(sysAddr, bAllClean, requestID, receiver, segments);
|
||||
return request;
|
||||
}
|
||||
|
||||
void ClientPackets::SendTop5HelpIssues(Packet* packet) {
|
||||
auto* user = UserManager::Instance()->GetUser(packet->systemAddress);
|
||||
if (!user) return;
|
||||
auto* character = user->GetLastUsedChar();
|
||||
if (!character) return;
|
||||
auto * entity = character->GetEntity();
|
||||
if (!entity) return;
|
||||
|
||||
int32_t ClientPackets::SendTop5HelpIssues(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
int32_t language = 0;
|
||||
inStream.Read(language);
|
||||
|
||||
// TODO: Handle different languages in a nice way
|
||||
// 0: en_US
|
||||
// 1: pl_US
|
||||
// 2: de_DE
|
||||
// 3: en_GB
|
||||
|
||||
AMFArrayValue data;
|
||||
// Summaries
|
||||
data.Insert("Summary0", Game::config->GetValue("help_0_summary"));
|
||||
data.Insert("Summary1", Game::config->GetValue("help_1_summary"));
|
||||
data.Insert("Summary2", Game::config->GetValue("help_2_summary"));
|
||||
data.Insert("Summary3", Game::config->GetValue("help_3_summary"));
|
||||
data.Insert("Summary4", Game::config->GetValue("help_4_summary"));
|
||||
|
||||
// Descriptions
|
||||
data.Insert("Description0", Game::config->GetValue("help_0_description"));
|
||||
data.Insert("Description1", Game::config->GetValue("help_1_description"));
|
||||
data.Insert("Description2", Game::config->GetValue("help_2_description"));
|
||||
data.Insert("Description3", Game::config->GetValue("help_3_description"));
|
||||
data.Insert("Description4", Game::config->GetValue("help_4_description"));
|
||||
|
||||
GameMessages::SendUIMessageServerToSingleClient(entity, packet->systemAddress, "UIHelpTop5", data);
|
||||
|
||||
return language;
|
||||
}
|
||||
|
||||
@@ -6,13 +6,31 @@
|
||||
#ifndef CLIENTPACKETS_H
|
||||
#define CLIENTPACKETS_H
|
||||
|
||||
#include "RakNetTypes.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
class PositionUpdate;
|
||||
|
||||
struct Packet;
|
||||
|
||||
struct ChatMessage {
|
||||
uint8_t chatChannel = 0;
|
||||
uint16_t unknown = 0;
|
||||
std::u16string message;
|
||||
};
|
||||
|
||||
struct ChatModerationRequest {
|
||||
uint8_t chatLevel = 0;
|
||||
uint8_t requestID = 0;
|
||||
std::string receiver;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
namespace ClientPackets {
|
||||
void HandleChatMessage(const SystemAddress& sysAddr, Packet* packet);
|
||||
void HandleClientPositionUpdate(const SystemAddress& sysAddr, Packet* packet);
|
||||
void HandleChatModerationRequest(const SystemAddress& sysAddr, Packet* packet);
|
||||
void SendTop5HelpIssues(Packet* packet);
|
||||
ChatMessage HandleChatMessage(Packet* packet);
|
||||
PositionUpdate HandleClientPositionUpdate(Packet* packet);
|
||||
ChatModerationRequest HandleChatModerationRequest(Packet* packet);
|
||||
int32_t SendTop5HelpIssues(Packet* packet);
|
||||
};
|
||||
|
||||
#endif // CLIENTPACKETS_H
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "MasterPackets.h"
|
||||
#include "BitStream.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
#include "eConnectionType.h"
|
||||
@@ -88,7 +87,7 @@ void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddres
|
||||
bitStream.Write(zoneInstance);
|
||||
bitStream.Write(zoneClone);
|
||||
bitStream.Write<uint16_t>(serverPort);
|
||||
bitStream.Write(LUString(serverIP, static_cast<uint32_t>(serverIP.size() + 1)));
|
||||
bitStream.Write(LUString(serverIP, 255));
|
||||
|
||||
server->Send(&bitStream, sysAddr, false);
|
||||
}
|
||||
@@ -100,12 +99,12 @@ void MasterPackets::HandleServerInfo(Packet* packet) {
|
||||
uint32_t theirPort = 0;
|
||||
uint32_t theirZoneID = 0;
|
||||
uint32_t theirInstanceID = 0;
|
||||
std::string theirIP = "";
|
||||
LUString theirIP;
|
||||
|
||||
inStream.Read(theirPort);
|
||||
inStream.Read(theirZoneID);
|
||||
inStream.Read(theirInstanceID);
|
||||
theirIP = PacketUtils::ReadString(inStream.GetReadOffset(), packet, false); //20 is the current offset
|
||||
inStream.Read(theirIP);
|
||||
|
||||
//TODO: Actually mark this server as an available server in the manager
|
||||
}
|
||||
@@ -118,7 +117,7 @@ void MasterPackets::SendServerInfo(dServer* server, Packet* packet) {
|
||||
bitStream.Write(server->GetZoneID());
|
||||
bitStream.Write(server->GetInstanceID());
|
||||
bitStream.Write(server->GetServerType());
|
||||
bitStream.Write(LUString(server->GetIP(), server->GetIP().size()));
|
||||
bitStream.Write(LUString(server->GetIP()));
|
||||
|
||||
server->SendToMaster(&bitStream);
|
||||
}
|
||||
|
||||
@@ -1,64 +1,8 @@
|
||||
#include "PacketUtils.h"
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "Logger.h"
|
||||
#include "Game.h"
|
||||
|
||||
uint16_t PacketUtils::ReadU16(uint32_t startLoc, Packet* packet) {
|
||||
if (startLoc + 2 > packet->length) return 0;
|
||||
|
||||
std::vector<unsigned char> t;
|
||||
for (uint32_t i = startLoc; i < startLoc + 2; i++) t.push_back(packet->data[i]);
|
||||
return *(uint16_t*)t.data();
|
||||
}
|
||||
|
||||
uint32_t PacketUtils::ReadU32(uint32_t startLoc, Packet* packet) {
|
||||
if (startLoc + 4 > packet->length) return 0;
|
||||
|
||||
std::vector<unsigned char> t;
|
||||
for (uint32_t i = startLoc; i < startLoc + 4; i++) {
|
||||
t.push_back(packet->data[i]);
|
||||
}
|
||||
return *(uint32_t*)t.data();
|
||||
}
|
||||
|
||||
uint64_t PacketUtils::ReadU64(uint32_t startLoc, Packet* packet) {
|
||||
if (startLoc + 8 > packet->length) return 0;
|
||||
|
||||
std::vector<unsigned char> t;
|
||||
for (uint32_t i = startLoc; i < startLoc + 8; i++) t.push_back(packet->data[i]);
|
||||
return *(uint64_t*)t.data();
|
||||
}
|
||||
|
||||
int64_t PacketUtils::ReadS64(uint32_t startLoc, Packet* packet) {
|
||||
if (startLoc + 8 > packet->length) return 0;
|
||||
|
||||
std::vector<unsigned char> t;
|
||||
for (size_t i = startLoc; i < startLoc + 8; i++) t.push_back(packet->data[i]);
|
||||
return *(int64_t*)t.data();
|
||||
}
|
||||
|
||||
std::string PacketUtils::ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen) {
|
||||
std::string readString = "";
|
||||
|
||||
if (wide) maxLen *= 2;
|
||||
|
||||
if (packet->length > startLoc) {
|
||||
uint32_t i = 0;
|
||||
while (packet->data[startLoc + i] != '\0' && packet->length > static_cast<uint32_t>(startLoc + i) && maxLen > i) {
|
||||
readString.push_back(packet->data[startLoc + i]);
|
||||
|
||||
if (wide) {
|
||||
i += 2; // Wide-char string
|
||||
} else {
|
||||
i++; // Regular string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return readString;
|
||||
}
|
||||
|
||||
//! Saves a packet to the filesystem
|
||||
void PacketUtils::SavePacket(const std::string& filename, const char* data, size_t length) {
|
||||
//If we don't log to the console, don't save the bin files either. This takes up a lot of time.
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
enum class eConnectionType : uint16_t;
|
||||
|
||||
namespace PacketUtils {
|
||||
uint16_t ReadU16(uint32_t startLoc, Packet* packet);
|
||||
uint32_t ReadU32(uint32_t startLoc, Packet* packet);
|
||||
uint64_t ReadU64(uint32_t startLoc, Packet* packet);
|
||||
int64_t ReadS64(uint32_t startLoc, Packet* packet);
|
||||
std::string ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen = 33);
|
||||
void SavePacket(const std::string& filename, const char* data, size_t length);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,26 +1,21 @@
|
||||
#include "dCommonVars.h"
|
||||
#include "WorldPackets.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "BitStream.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "User.h"
|
||||
#include "Character.h"
|
||||
#include "Logger.h"
|
||||
#include <iostream>
|
||||
#include "Game.h"
|
||||
#include "LDFFormat.h"
|
||||
#include "dServer.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "ZCompression.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "BitStreamUtils.h"
|
||||
|
||||
void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) {
|
||||
#include <iostream>
|
||||
|
||||
void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum, LWOZONEID zone) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE);
|
||||
|
||||
auto zone = Game::zoneManager->GetZone()->GetZoneID();
|
||||
bitStream.Write<uint16_t>(zone.GetMapID());
|
||||
bitStream.Write<uint16_t>(zone.GetInstanceID());
|
||||
//bitStream.Write<uint32_t>(zone.GetCloneID());
|
||||
@@ -38,57 +33,6 @@ void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, flo
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) {
|
||||
if (!user) return;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE);
|
||||
|
||||
std::vector<Character*> characters = user->GetCharacters();
|
||||
bitStream.Write<uint8_t>(characters.size());
|
||||
bitStream.Write<uint8_t>(0); //character index in front, just picking 0
|
||||
|
||||
for (uint32_t i = 0; i < characters.size(); ++i) {
|
||||
bitStream.Write(characters[i]->GetObjectID());
|
||||
bitStream.Write<uint32_t>(0);
|
||||
|
||||
bitStream.Write(LUWString(characters[i]->GetName()));
|
||||
bitStream.Write(LUWString(characters[i]->GetUnapprovedName()));
|
||||
|
||||
bitStream.Write<uint8_t>(characters[i]->GetNameRejected());
|
||||
bitStream.Write<uint8_t>(false);
|
||||
|
||||
bitStream.Write(LUString("", 10));
|
||||
|
||||
bitStream.Write(characters[i]->GetShirtColor());
|
||||
bitStream.Write(characters[i]->GetShirtStyle());
|
||||
bitStream.Write(characters[i]->GetPantsColor());
|
||||
bitStream.Write(characters[i]->GetHairStyle());
|
||||
bitStream.Write(characters[i]->GetHairColor());
|
||||
bitStream.Write(characters[i]->GetLeftHand());
|
||||
bitStream.Write(characters[i]->GetRightHand());
|
||||
bitStream.Write(characters[i]->GetEyebrows());
|
||||
bitStream.Write(characters[i]->GetEyes());
|
||||
bitStream.Write(characters[i]->GetMouth());
|
||||
bitStream.Write<uint32_t>(0);
|
||||
|
||||
bitStream.Write<uint16_t>(characters[i]->GetZoneID());
|
||||
bitStream.Write<uint16_t>(characters[i]->GetZoneInstance());
|
||||
bitStream.Write(characters[i]->GetZoneClone());
|
||||
|
||||
bitStream.Write(characters[i]->GetLastLogin());
|
||||
|
||||
const auto& equippedItems = characters[i]->GetEquippedItems();
|
||||
bitStream.Write<uint16_t>(equippedItems.size());
|
||||
|
||||
for (uint32_t j = 0; j < equippedItems.size(); ++j) {
|
||||
bitStream.Write(equippedItems[j]);
|
||||
}
|
||||
}
|
||||
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCharacterCreationResponse(const SystemAddress& sysAddr, eCharacterCreationResponse response) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_CREATE_RESPONSE);
|
||||
@@ -128,26 +72,20 @@ void WorldPackets::SendServerState(const SystemAddress& sysAddr) {
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) {
|
||||
void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, int64_t reputation, LWOOBJID player, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CREATE_CHARACTER);
|
||||
|
||||
RakNet::BitStream data;
|
||||
data.Write<uint32_t>(7); //LDF key count
|
||||
|
||||
auto character = entity->GetComponent<CharacterComponent>();
|
||||
if (!character) {
|
||||
LOG("Entity is not a character?? what??");
|
||||
return;
|
||||
}
|
||||
|
||||
LDFData<LWOOBJID>* objid = new LDFData<LWOOBJID>(u"objid", entity->GetObjectID());
|
||||
LDFData<LOT>* lot = new LDFData<LOT>(u"template", 1);
|
||||
LDFData<std::string>* xmlConfigData = new LDFData<std::string>(u"xmlData", xmlData);
|
||||
LDFData<std::u16string>* name = new LDFData<std::u16string>(u"name", username);
|
||||
LDFData<int32_t>* gmlevel = new LDFData<int32_t>(u"gmlevel", static_cast<int32_t>(gm));
|
||||
LDFData<int32_t>* chatmode = new LDFData<int32_t>(u"chatmode", static_cast<int32_t>(gm));
|
||||
LDFData<int64_t>* reputation = new LDFData<int64_t>(u"reputation", character->GetReputation());
|
||||
std::unique_ptr<LDFData<LWOOBJID>> objid(new LDFData<LWOOBJID>(u"objid", player));
|
||||
std::unique_ptr<LDFData<LOT>> lot(new LDFData<LOT>(u"template", 1));
|
||||
std::unique_ptr<LDFData<std::string>> xmlConfigData(new LDFData<std::string>(u"xmlData", xmlData));
|
||||
std::unique_ptr<LDFData<std::u16string>> name(new LDFData<std::u16string>(u"name", username));
|
||||
std::unique_ptr<LDFData<int32_t>> gmlevel(new LDFData<int32_t>(u"gmlevel", static_cast<int32_t>(gm)));
|
||||
std::unique_ptr<LDFData<int32_t>> chatmode(new LDFData<int32_t>(u"chatmode", static_cast<int32_t>(gm)));
|
||||
std::unique_ptr<LDFData<int64_t>> reputationLdf(new LDFData<int64_t>(u"reputation", reputation));
|
||||
|
||||
objid->WriteToPacket(&data);
|
||||
lot->WriteToPacket(&data);
|
||||
@@ -155,15 +93,7 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent
|
||||
gmlevel->WriteToPacket(&data);
|
||||
chatmode->WriteToPacket(&data);
|
||||
xmlConfigData->WriteToPacket(&data);
|
||||
reputation->WriteToPacket(&data);
|
||||
|
||||
delete objid;
|
||||
delete lot;
|
||||
delete xmlConfigData;
|
||||
delete gmlevel;
|
||||
delete chatmode;
|
||||
delete name;
|
||||
delete reputation;
|
||||
reputationLdf->WriteToPacket(&data);
|
||||
|
||||
//Compress the data before sending:
|
||||
const uint32_t reservedSize = ZCompression::GetMaxCompressedLength(data.GetNumberOfBytesUsed());
|
||||
@@ -187,14 +117,12 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent
|
||||
* an assertion is done to prevent bad data from being saved or sent.
|
||||
*/
|
||||
#pragma warning(disable:6385) // C6385 Reading invalid data from 'compressedData'.
|
||||
for (size_t i = 0; i < size; i++)
|
||||
bitStream.Write(compressedData[i]);
|
||||
bitStream.WriteAlignedBytes(compressedData, size);
|
||||
#pragma warning(default:6385)
|
||||
|
||||
// PacketUtils::SavePacket("chardata.bin", (const char*)bitStream.GetData(), static_cast<uint32_t>(bitStream.GetNumberOfBytesUsed()));
|
||||
SEND_PACKET;
|
||||
delete[] compressedData;
|
||||
LOG("Sent CreateCharacter for ID: %llu", entity->GetObjectID());
|
||||
LOG("Sent CreateCharacter for ID: %llu", player);
|
||||
}
|
||||
|
||||
void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems) {
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
#define WORLDPACKETS_H
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "Entity.h"
|
||||
|
||||
class User;
|
||||
struct SystemAddress;
|
||||
@@ -13,14 +12,13 @@ enum class eCharacterCreationResponse : uint8_t;
|
||||
enum class eRenameResponse : uint8_t;
|
||||
|
||||
namespace WorldPackets {
|
||||
void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum);
|
||||
void SendCharacterList(const SystemAddress& sysAddr, User* user);
|
||||
void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum, LWOZONEID zone);
|
||||
void SendCharacterCreationResponse(const SystemAddress& sysAddr, eCharacterCreationResponse response);
|
||||
void SendCharacterRenameResponse(const SystemAddress& sysAddr, eRenameResponse response);
|
||||
void SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response);
|
||||
void SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift);
|
||||
void SendServerState(const SystemAddress& sysAddr);
|
||||
void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm);
|
||||
void SendCreateCharacter(const SystemAddress& sysAddr, int64_t reputation, LWOOBJID player, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm);
|
||||
void SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems);
|
||||
void SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
// Custom Classes
|
||||
#include "MasterPackets.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "dServer.h"
|
||||
|
||||
// C++
|
||||
@@ -25,20 +24,30 @@ void ZoneInstanceManager::RequestZoneTransfer(dServer* server, uint32_t zoneID,
|
||||
}
|
||||
|
||||
//! Handles a zone transfer response
|
||||
void ZoneInstanceManager::HandleRequestZoneTransferResponse(uint64_t requestID, Packet* packet) {
|
||||
|
||||
bool mythranShift = static_cast<bool>(packet->data[16]);
|
||||
uint32_t zoneID = PacketUtils::ReadU32(17, packet);
|
||||
uint32_t zoneInstance = PacketUtils::ReadU32(21, packet);
|
||||
uint32_t zoneClone = PacketUtils::ReadU32(25, packet);
|
||||
uint16_t serverPort = PacketUtils::ReadU16(29, packet);
|
||||
std::string serverIP = PacketUtils::ReadString(31, packet, false);
|
||||
void ZoneInstanceManager::HandleRequestZoneTransferResponse(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
uint64_t requestID;
|
||||
inStream.Read(requestID);
|
||||
bool mythranShift;
|
||||
uint8_t tmp;
|
||||
inStream.Read(tmp);
|
||||
mythranShift = tmp > 0;
|
||||
uint32_t zoneID;
|
||||
inStream.Read(zoneID);
|
||||
uint32_t zoneInstance;
|
||||
inStream.Read(zoneInstance);
|
||||
uint32_t zoneClone;
|
||||
inStream.Read(zoneClone);
|
||||
uint16_t serverPort;
|
||||
inStream.Read(serverPort);
|
||||
LUString serverIP(255);
|
||||
inStream.Read(serverIP);
|
||||
|
||||
for (uint32_t i = 0; i < this->requests.size(); ++i) {
|
||||
if (this->requests[i]->requestID == requestID) {
|
||||
|
||||
// Call the request callback
|
||||
this->requests[i]->callback(mythranShift, zoneID, zoneInstance, zoneClone, serverIP, serverPort);
|
||||
this->requests[i]->callback(mythranShift, zoneID, zoneInstance, zoneClone, serverIP.string, serverPort);
|
||||
|
||||
delete this->requests[i];
|
||||
this->requests.erase(this->requests.begin() + i);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// C++
|
||||
#define _VARIADIC_MAX 10
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -56,7 +54,7 @@ public:
|
||||
\param requestID The request ID
|
||||
\param packet The packet
|
||||
*/
|
||||
void HandleRequestZoneTransferResponse(uint64_t requestID, Packet* packet);
|
||||
void HandleRequestZoneTransferResponse(Packet* packet);
|
||||
|
||||
void CreatePrivateZone(dServer* server, uint32_t zoneID, uint32_t zoneClone, const std::string& password);
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "eServerMessageType.h"
|
||||
#include "eMasterMessageType.h"
|
||||
|
||||
#include "PacketUtils.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "MasterPackets.h"
|
||||
#include "ZoneInstanceManager.h"
|
||||
@@ -127,8 +126,7 @@ Packet* dServer::ReceiveFromMaster() {
|
||||
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::MASTER) {
|
||||
switch (static_cast<eMasterMessageType>(packet->data[3])) {
|
||||
case eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE: {
|
||||
uint64_t requestID = PacketUtils::ReadU64(8, packet);
|
||||
ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet);
|
||||
ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(packet);
|
||||
break;
|
||||
}
|
||||
case eMasterMessageType::SHUTDOWN:
|
||||
|
||||
@@ -16,6 +16,14 @@ enum class ServerType : uint32_t {
|
||||
World
|
||||
};
|
||||
|
||||
enum class ServiceId : uint32_t{
|
||||
General = 0,
|
||||
Auth = 1,
|
||||
Chat = 2,
|
||||
World = 4,
|
||||
Client = 5,
|
||||
};
|
||||
|
||||
namespace Game {
|
||||
using signal_t = volatile std::sig_atomic_t;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user