mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-09 20:24:16 +00:00
Make PacketUtils only for packetAdd BitstreamUtils and make better read/writesupdate
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#include "AuthPackets.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "BitstreamUtils.h"
|
||||
|
||||
#include "dNetCommon.h"
|
||||
#include "dServer.h"
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <BitStream.h>
|
||||
#include <future>
|
||||
|
||||
#include "PacketUtils.h"
|
||||
#include "Game.h"
|
||||
#include "dConfig.h"
|
||||
#include "eServerDisconnectIdentifiers.h"
|
||||
@@ -26,46 +27,136 @@
|
||||
#include "eConnectionType.h"
|
||||
#include "eServerMessageType.h"
|
||||
#include "eMasterMessageType.h"
|
||||
#include "eStamps.h"
|
||||
|
||||
enum class ClientOS : uint8_t {
|
||||
UNKNOWN,
|
||||
WINDOWS,
|
||||
MACOS
|
||||
};
|
||||
|
||||
enum class LCID : uint16_t {
|
||||
en_US = 0x0409,
|
||||
de_DE = 0x0407,
|
||||
en_GB = 0x0809
|
||||
};
|
||||
|
||||
enum class Language : uint32_t {
|
||||
en_US,
|
||||
pl_US,
|
||||
de_DE,
|
||||
en_GB,
|
||||
};
|
||||
|
||||
void Stamp::Serialize(RakNet::BitStream* outBitStream){
|
||||
outBitStream->Write(type);
|
||||
outBitStream->Write(value);
|
||||
outBitStream->Write(timestamp);
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
server->GetLogger()->Log("AuthPackets", "Received client version: %i", clientVersion);
|
||||
uint32_t paddingZero;
|
||||
inStream.Read(paddingZero);
|
||||
if (paddingZero != 0) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: ZeroPadding is not Zero!");
|
||||
|
||||
ServiceId serviceId;
|
||||
inStream.Read(serviceId);
|
||||
if (serviceId != ServiceId::Client) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: Service ID is not a Client!");
|
||||
|
||||
uint32_t processID;
|
||||
inStream.Read(processID);
|
||||
|
||||
uint16_t port;
|
||||
inStream.Read(port);
|
||||
|
||||
LUWString paddingString(33);
|
||||
inStream.Read(paddingString);
|
||||
if (!paddingString.string.empty()) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: StringPadding is not empty!");
|
||||
|
||||
if (inStream.GetNumberOfUnreadBits() != 8) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: End padding is incorrect!");
|
||||
Game::logger->Log("AuthPackets::HandleHandShake", "Client Data [Version: %i, PaddingZero: %i, Service: %u, Process: %u, Port: %u, paddingString: %s, Sysaddr Port: %u]", clientVersion, paddingZero, serviceId, processID, port, paddingString.string.c_str(), packet->systemAddress.port);
|
||||
SendHandshake(server, packet->systemAddress, server->GetIP(), server->GetPort(), server->GetServerType());
|
||||
}
|
||||
|
||||
void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM);
|
||||
bitStream.Write<unsigned int>(NET_VERSION);
|
||||
bitStream.Write(uint32_t(0x93));
|
||||
RakNet::BitStream handshakeResponse;
|
||||
BitstreamUtils::WriteHeader(handshakeResponse, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM);
|
||||
handshakeResponse.Write<uint32_t>(NET_VERSION);
|
||||
handshakeResponse.Write<uint32_t>(0); // Unused/Unknown/Padding
|
||||
|
||||
if (serverType == ServerType::Auth) bitStream.Write(uint32_t(1)); //Conn: auth
|
||||
else bitStream.Write(uint32_t(4)); //Conn: world
|
||||
if (serverType == ServerType::Auth) handshakeResponse.Write(ServiceId::Auth);
|
||||
else if (serverType == ServerType::World) handshakeResponse.Write(ServiceId::World);
|
||||
else handshakeResponse.Write(ServiceId::General);
|
||||
|
||||
bitStream.Write(uint32_t(0)); //Server process ID
|
||||
bitStream.Write(nextServerPort);
|
||||
|
||||
server->Send(&bitStream, sysAddr, false);
|
||||
server->Send(&handshakeResponse, 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;
|
||||
|
||||
LUWString username(33);
|
||||
inStream.Read(username);
|
||||
std::string usernameString = GeneralUtils::UTF16ToWTF8(username.string);
|
||||
|
||||
LUWString password(41);
|
||||
inStream.Read(password);
|
||||
|
||||
LCID locale_id;
|
||||
inStream.Read(locale_id);
|
||||
Game::logger->Log("AuthPackets", "Locale ID: %i", locale_id);
|
||||
|
||||
ClientOS clientOS;
|
||||
inStream.Read(clientOS);
|
||||
std::string clientOSString = "Unknown";
|
||||
if (clientOS == ClientOS::WINDOWS) clientOSString = "Windows";
|
||||
else if (clientOS == ClientOS::MACOS) clientOSString = "MacOS";
|
||||
Game::logger->Log("AuthPackets", "Operating System: %s",clientOSString.c_str());
|
||||
|
||||
LUWString memoryStats(256);
|
||||
inStream.Read(memoryStats);
|
||||
Game::logger->Log("AuthPackets", "Memory Stats [%s]", memoryStats.GetAsString().c_str());
|
||||
|
||||
LUWString videoCard(128);
|
||||
inStream.Read(videoCard);
|
||||
Game::logger->Log("AuthPackets", "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);
|
||||
Game::logger->Log("AuthPackets", "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);
|
||||
Game::logger->Log("AuthPackets", "OS Info: [Size: %i, Major: %i, Minor %i, Buid#: %i, platformID: %i]", osVersionInfoSize, majorVersion, minorVersion, buildNumber, platformID);
|
||||
|
||||
// Fetch account details
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT password, banned, locked, play_key_id, gm_level FROM accounts WHERE name=? LIMIT 1;");
|
||||
stmt->setString(1, szUsername);
|
||||
std::unique_ptr<sql::PreparedStatement> stmt(Database::CreatePreppedStmt("SELECT password, banned, locked, play_key_id, gm_level FROM accounts WHERE name=? LIMIT 1;"));
|
||||
stmt->setString(1, usernameString.c_str());
|
||||
|
||||
sql::ResultSet* res = stmt->executeQuery();
|
||||
std::unique_ptr<sql::ResultSet> res(stmt->executeQuery());
|
||||
|
||||
if (res->rowsCount() == 0) {
|
||||
server->GetLogger()->Log("AuthPackets", "No user found!");
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, username);
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, usernameString);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -83,21 +174,25 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
|
||||
sqlGmLevel = res->getInt(5);
|
||||
}
|
||||
|
||||
delete stmt;
|
||||
delete res;
|
||||
int32_t bcryptState = ::bcrypt_checkpw(GeneralUtils::UTF16ToWTF8(password.string).c_str(), sqlPass.c_str());
|
||||
if (bcryptState != 0) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, usernameString);
|
||||
server->GetLogger()->Log("AuthPackets", "Wrong password used");
|
||||
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)) && sqlGmLevel == 0) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "The server is currently only open to developers.", "", 2001, username);
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "The server is currently only open to developers.", "", 2001, usernameString);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::config->GetValue("dont_use_keys") != "1") {
|
||||
//Check to see if we have a play key:
|
||||
if (sqlPlayKey == 0 && sqlGmLevel == 0) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username);
|
||||
server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but they don't have a play key.", username.c_str());
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, usernameString);
|
||||
server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but they don't have a play key.", usernameString.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,7 +203,7 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
|
||||
bool isKeyActive = false;
|
||||
|
||||
if (keyRes->rowsCount() == 0 && sqlGmLevel == 0) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username);
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, usernameString);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -117,150 +212,133 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
|
||||
}
|
||||
|
||||
if (!isKeyActive && sqlGmLevel == 0) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, username);
|
||||
server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but their play key was disabled", username.c_str());
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, usernameString);
|
||||
server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but their play key was disabled", usernameString.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sqlBanned) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, username); return;
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, usernameString);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sqlLocked) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, username); return;
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, usernameString);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updated hashing method:
|
||||
* First attempt bcrypt.
|
||||
* If that fails, fallback to old method and setup bcrypt for new login.
|
||||
*/
|
||||
auto system = packet->systemAddress; //Copy the sysAddr before the Packet gets destroyed from main
|
||||
|
||||
bool loginSuccess = true;
|
||||
|
||||
int32_t bcryptState = ::bcrypt_checkpw(password.c_str(), sqlPass.c_str());
|
||||
|
||||
if (bcryptState != 0) {
|
||||
// Fallback on old method
|
||||
|
||||
std::string oldPassword = sha512(password + username);
|
||||
|
||||
if (sqlPass != oldPassword) {
|
||||
loginSuccess = false;
|
||||
} else {
|
||||
// Generate new hash for bcrypt
|
||||
|
||||
char salt[BCRYPT_HASHSIZE];
|
||||
char hash[BCRYPT_HASHSIZE];
|
||||
|
||||
bcryptState = ::bcrypt_gensalt(12, salt);
|
||||
|
||||
assert(bcryptState == 0);
|
||||
|
||||
bcryptState = ::bcrypt_hashpw(password.c_str(), salt, hash);
|
||||
|
||||
assert(bcryptState == 0);
|
||||
|
||||
sql::PreparedStatement* accountUpdate = Database::CreatePreppedStmt("UPDATE accounts SET password = ? WHERE name = ? LIMIT 1;");
|
||||
|
||||
accountUpdate->setString(1, std::string(hash, BCRYPT_HASHSIZE).c_str());
|
||||
accountUpdate->setString(2, szUsername);
|
||||
|
||||
accountUpdate->executeUpdate();
|
||||
}
|
||||
} else {
|
||||
// Login success with bcrypt
|
||||
if (!server->GetIsConnectedToMaster()) {
|
||||
AuthPackets::SendLoginResponse(server, system, eLoginResponse::GENERAL_FAILED, "Unable to Connect to Master Server", "", 0, usernameString);
|
||||
Game::logger->Log("AuthPackets", "Unable to complete login of user %s due to no connection to Master", usernameString.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!loginSuccess) {
|
||||
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, username);
|
||||
server->GetLogger()->Log("AuthPackets", "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);
|
||||
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);
|
||||
});
|
||||
}
|
||||
ZoneInstanceManager::Instance()->RequestZoneTransfer(server, 0, 0, false, [system, server, usernameString](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, usernameString);
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
PacketUtils::WriteHeader(packet, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE);
|
||||
RakNet::BitStream loginResponse;
|
||||
BitstreamUtils::WriteHeader(loginResponse, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE);
|
||||
|
||||
packet.Write(static_cast<uint8_t>(responseCode));
|
||||
loginResponse.Write(responseCode);
|
||||
|
||||
PacketUtils::WritePacketString("Talk_Like_A_Pirate", 33, &packet);
|
||||
// Events
|
||||
loginResponse.Write(LUString("Talk_Like_A_Pirate"));
|
||||
loginResponse.Write(LUString(""));
|
||||
loginResponse.Write(LUString(""));
|
||||
loginResponse.Write(LUString(""));
|
||||
loginResponse.Write(LUString(""));
|
||||
loginResponse.Write(LUString(""));
|
||||
loginResponse.Write(LUString(""));
|
||||
loginResponse.Write(LUString(""));
|
||||
|
||||
// 7 unknown strings - perhaps other IP addresses?
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
|
||||
packet.Write(static_cast<uint16_t>(1)); // Version Major
|
||||
packet.Write(static_cast<uint16_t>(10)); // Version Current
|
||||
packet.Write(static_cast<uint16_t>(64)); // Version Minor
|
||||
loginResponse.Write(static_cast<uint16_t>(1)); // Version Major
|
||||
loginResponse.Write(static_cast<uint16_t>(10)); // Version Current
|
||||
loginResponse.Write(static_cast<uint16_t>(64)); // Version Minor
|
||||
|
||||
// Writes the user key
|
||||
uint32_t sessionKey = GeneralUtils::GenerateRandomNumber<uint32_t>();
|
||||
std::string userHash = std::to_string(sessionKey);
|
||||
userHash = md5(userHash);
|
||||
PacketUtils::WritePacketWString(userHash, 33, &packet);
|
||||
loginResponse.Write(LUWString(userHash));
|
||||
|
||||
// Write the Character and Chat IPs
|
||||
PacketUtils::WritePacketString(wServerIP, 33, &packet);
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
// World Server IP
|
||||
loginResponse.Write(LUString(wServerIP));
|
||||
// Chat Server IP (unused)
|
||||
loginResponse.Write(LUString(""));
|
||||
|
||||
// Write the Character and Chat Ports
|
||||
packet.Write(static_cast<uint16_t>(wServerPort));
|
||||
packet.Write(static_cast<uint16_t>(0));
|
||||
// World Server Redirect port
|
||||
loginResponse.Write(wServerPort);
|
||||
// Char Server Redirect port (unused)
|
||||
loginResponse.Write(static_cast<uint16_t>(0));
|
||||
|
||||
// Write another IP
|
||||
PacketUtils::WritePacketString("", 33, &packet);
|
||||
// CDN Key
|
||||
loginResponse.Write(LUString(""));
|
||||
|
||||
// Write a GUID or something...
|
||||
PacketUtils::WritePacketString("00000000-0000-0000-0000-000000000000", 37, &packet);
|
||||
// CDN Ticket
|
||||
loginResponse.Write(LUString("00000000-0000-0000-0000-000000000000", 37));
|
||||
|
||||
packet.Write(static_cast<uint32_t>(0)); // ???
|
||||
// Language
|
||||
loginResponse.Write(Language::en_US);
|
||||
|
||||
// Write the localization
|
||||
PacketUtils::WritePacketString("US", 3, &packet);
|
||||
// Country Code
|
||||
loginResponse.Write(LUString("US", 3));
|
||||
|
||||
packet.Write(static_cast<uint8_t>(false)); // User first logged in?
|
||||
packet.Write(static_cast<uint8_t>(false)); // User is F2P?
|
||||
packet.Write(static_cast<uint64_t>(0)); // ???
|
||||
|
||||
// Just upgraded from FTP
|
||||
loginResponse.Write(static_cast<uint8_t>(false));
|
||||
// Is FTP, static_cast<uint32_t>(errorMsg.length()))
|
||||
loginResponse.Write(static_cast<uint8_t>(false));
|
||||
// Time remaining in FTP
|
||||
loginResponse.Write(static_cast<uint64_t>(0));
|
||||
|
||||
// Write custom error message
|
||||
packet.Write(static_cast<uint16_t>(errorMsg.length()));
|
||||
PacketUtils::WritePacketWString(errorMsg, static_cast<uint32_t>(errorMsg.length()), &packet);
|
||||
loginResponse.Write(static_cast<uint16_t>(errorMsg.length()));
|
||||
loginResponse.Write(errorMsg);
|
||||
|
||||
// Here write auth logs
|
||||
packet.Write(static_cast<uint32_t>(20));
|
||||
for (uint32_t i = 0; i < 20; ++i) {
|
||||
packet.Write(static_cast<uint32_t>(8));
|
||||
packet.Write(static_cast<uint32_t>(44));
|
||||
packet.Write(static_cast<uint32_t>(14000));
|
||||
packet.Write(static_cast<uint32_t>(0));
|
||||
// Stamps
|
||||
std::vector<Stamp> stamps;
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_START, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_COMMUNICATION_START, 207, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_RECEIVED, 13, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_THREAD_SPAWN, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_WEBSERVICE_START, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_WEBSERVICE_FINISH, 1, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_THREAD_FINISH, 1, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_REPLY, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_COMMUNICATION_END, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_DB_INSERT_START, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_DB_INSERT_FINISH, 1, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_CLIENT_OS, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_COMMUNICATION_START, 16087, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_PACKET_RECEIVED, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_COMMUNICATION_START, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_LOGIN_START, 5926, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_LOGIN_RESPONSE, 5926, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_COMMUNICATION_END, 1, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH, 0, time(nullptr)));
|
||||
stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH, 16087, time(nullptr)));
|
||||
|
||||
loginResponse.Write(static_cast<uint32_t>((sizeof(Stamp) * stamps.size()) + sizeof(uint32_t)));
|
||||
for (auto& stamp : stamps) {
|
||||
stamp.Serialize(&loginResponse);
|
||||
}
|
||||
|
||||
server->Send(&packet, sysAddr, false);
|
||||
PacketUtils::SavePacket("loginresponse",(const char*)loginResponse.GetData(), loginResponse.GetNumberOfBytesUsed());
|
||||
Game::logger->Log("AuthPackets", "Sending Login Response...");
|
||||
server->Send(&loginResponse, sysAddr, false);
|
||||
|
||||
//Inform the master server that we've created a session for this user:
|
||||
{
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY);
|
||||
bitStream.Write(sessionKey);
|
||||
PacketUtils::WriteString(bitStream, username, 66);
|
||||
bitStream.Write(LUString(username, 66));
|
||||
|
||||
server->SendToMaster(&bitStream);
|
||||
|
||||
server->GetLogger()->Log("AuthPackets", "Set sessionKey: %i for user %s", sessionKey, username.c_str());
|
||||
|
@@ -7,8 +7,23 @@
|
||||
|
||||
enum class ServerType : uint32_t;
|
||||
enum class eLoginResponse : uint8_t;
|
||||
enum class eStamps : uint32_t;
|
||||
class dServer;
|
||||
|
||||
struct Stamp {
|
||||
eStamps type;
|
||||
uint32_t value;
|
||||
uint64_t timestamp;
|
||||
|
||||
Stamp(eStamps type, uint32_t value, uint64_t timestamp){
|
||||
this->type = type;
|
||||
this->value = value;
|
||||
this->timestamp = timestamp;
|
||||
}
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream);
|
||||
};
|
||||
|
||||
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);
|
||||
|
127
dNet/BitstreamUtils.h
Normal file
127
dNet/BitstreamUtils.h
Normal file
@@ -0,0 +1,127 @@
|
||||
|
||||
#ifndef __BITSTREAMUTILS__H__
|
||||
#define __BITSTREAMUTILS__H__
|
||||
|
||||
#include "GeneralUtils.h"
|
||||
#include <MessageIdentifiers.h>
|
||||
#include <BitStream.h>
|
||||
#include <string>
|
||||
|
||||
enum class eConnectionType : uint16_t;
|
||||
|
||||
struct LUString {
|
||||
std::string string;
|
||||
uint32_t size;
|
||||
|
||||
LUString(uint32_t size) {
|
||||
this->size = size;
|
||||
};
|
||||
LUString(std::string string, uint32_t size = 33) {
|
||||
this->string = string;
|
||||
this->size = size;
|
||||
};
|
||||
std::u16string GetAsU16String() const {
|
||||
return GeneralUtils::ASCIIToUTF16(this->string);
|
||||
};
|
||||
};
|
||||
|
||||
struct LUWString {
|
||||
std::u16string string;
|
||||
uint32_t size;
|
||||
|
||||
LUWString(uint32_t size) {
|
||||
this->size = size;
|
||||
};
|
||||
LUWString(std::u16string string, uint32_t size = 33) {
|
||||
this->string = string;
|
||||
this->size = size;
|
||||
};
|
||||
LUWString(std::string string, uint32_t size = 33) {
|
||||
this->string = GeneralUtils::ASCIIToUTF16(string);
|
||||
this->size = size;
|
||||
};
|
||||
std::string GetAsString() const {
|
||||
return GeneralUtils::UTF16ToWTF8(this->string);
|
||||
};
|
||||
};
|
||||
|
||||
namespace BitstreamUtils {
|
||||
template<typename T>
|
||||
void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) {
|
||||
bitStream.Write<uint8_t>(MessageID(ID_USER_PACKET_ENUM));
|
||||
bitStream.Write<eConnectionType>(connectionType);
|
||||
bitStream.Write<uint32_t>(static_cast<uint32_t>(internalPacketID));
|
||||
bitStream.Write<uint8_t>(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace RakNet {
|
||||
template <>
|
||||
inline bool RakNet::BitStream::Read<LUString>(LUString& value) {
|
||||
bool noMoreLetters = false;
|
||||
char character;
|
||||
for (uint32_t j = 0; j < value.size; j++) {
|
||||
if (!Read(character)) return false;
|
||||
if (character == '\0') noMoreLetters = true;
|
||||
if (!noMoreLetters) value.string.push_back(character);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool RakNet::BitStream::Read<LUWString>(LUWString& value) {
|
||||
bool noMoreLetters = false;
|
||||
char16_t character;
|
||||
for (uint32_t j = 0; j < value.size; j++) {
|
||||
if (!Read(character)) return false;
|
||||
if (character == '\0') noMoreLetters = true;
|
||||
if (!noMoreLetters) value.string.push_back(character);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void RakNet::BitStream::Write<LUString>(LUString value) {
|
||||
uint32_t size = value.string.size();
|
||||
uint32_t emptySize = value.size - size;
|
||||
|
||||
if (size > value.size) size = value.size;
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
this->Write(static_cast<char>(value.string[i]));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < emptySize; i++) {
|
||||
this->Write(static_cast<char>(0));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void RakNet::BitStream::Write<LUWString>(LUWString value) {
|
||||
uint32_t size = static_cast<uint32_t>(value.string.length());
|
||||
uint32_t remSize = static_cast<uint32_t>(value.size - size);
|
||||
|
||||
if (size > value.size) size = value.size;
|
||||
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
this->Write(static_cast<uint16_t>(value.string[i]));
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < remSize; ++j) {
|
||||
this->Write(static_cast<uint16_t>(0));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void RakNet::BitStream::Write<std::string>(std::string value) {
|
||||
this->WriteBits(reinterpret_cast<const unsigned char*>(value.data()), BYTES_TO_BITS(value.size()));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void RakNet::BitStream::Write<std::u16string>(std::u16string value) {
|
||||
this->WriteBits(reinterpret_cast<const unsigned char*>(value.data()), BYTES_TO_BITS(value.size()) * 2);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //!__BITSTREAMUTILS__H__
|
@@ -7,20 +7,20 @@
|
||||
#include "RakNetTypes.h"
|
||||
#include "BitStream.h"
|
||||
#include "Game.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "BitstreamUtils.h"
|
||||
#include "dServer.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "eChatMessageType.h"
|
||||
|
||||
void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel, const std::string& senderName, LWOOBJID playerObjectID, bool senderMythran, const std::u16string& message) {
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE);
|
||||
|
||||
bitStream.Write(static_cast<uint64_t>(0));
|
||||
bitStream.Write(chatChannel);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(message.size()));
|
||||
PacketUtils::WriteWString(bitStream, senderName, 33);
|
||||
bitStream.Write(LUWString(senderName));
|
||||
|
||||
bitStream.Write(playerObjectID);
|
||||
bitStream.Write(static_cast<uint16_t>(0));
|
||||
@@ -36,13 +36,13 @@ void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel
|
||||
|
||||
void ChatPackets::SendSystemMessage(const SystemAddress& sysAddr, const std::u16string& message, const bool broadcast) {
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE);
|
||||
|
||||
bitStream.Write(static_cast<uint64_t>(0));
|
||||
bitStream.Write(static_cast<char>(4));
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(message.size()));
|
||||
PacketUtils::WriteWString(bitStream, "", 33);
|
||||
bitStream.Write(LUWString(""));
|
||||
|
||||
bitStream.Write(static_cast<uint64_t>(0));
|
||||
bitStream.Write(static_cast<uint16_t>(0));
|
||||
@@ -68,7 +68,7 @@ void ChatPackets::SendMessageFail(const SystemAddress& sysAddr) {
|
||||
//0x01 - "Upgrade to a full LEGO Universe Membership to chat with other players."
|
||||
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SEND_CANNED_TEXT);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SEND_CANNED_TEXT);
|
||||
bitStream.Write<uint8_t>(0); //response type, options above ^
|
||||
//docs say there's a wstring here-- no idea what it's for, or if it's even needed so leaving it as is for now.
|
||||
SEND_PACKET;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include "MasterPackets.h"
|
||||
#include "BitStream.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "BitstreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
#include "eConnectionType.h"
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
void MasterPackets::SendPersistentIDRequest(dServer* server, uint64_t requestID) {
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID);
|
||||
bitStream.Write(requestID);
|
||||
server->SendToMaster(&bitStream);
|
||||
}
|
||||
|
||||
void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, uint32_t objID) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(objID);
|
||||
@@ -27,7 +27,7 @@ void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddres
|
||||
|
||||
void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t cloneID) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
@@ -39,7 +39,7 @@ void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID,
|
||||
|
||||
void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint32_t cloneID, const std::string& password) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::CREATE_PRIVATE_ZONE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::CREATE_PRIVATE_ZONE);
|
||||
|
||||
bitStream.Write(zoneID);
|
||||
bitStream.Write(cloneID);
|
||||
@@ -54,7 +54,7 @@ void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint
|
||||
|
||||
void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID, bool mythranShift, const std::string& password) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PRIVATE_ZONE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PRIVATE_ZONE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
@@ -69,7 +69,7 @@ void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID,
|
||||
|
||||
void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCEID instanceId) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::WORLD_READY);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::WORLD_READY);
|
||||
|
||||
bitStream.Write(zoneId);
|
||||
bitStream.Write(instanceId);
|
||||
@@ -79,7 +79,7 @@ void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCE
|
||||
|
||||
void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, const std::string& serverIP, uint32_t serverPort) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
@@ -87,7 +87,7 @@ void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddres
|
||||
bitStream.Write(zoneInstance);
|
||||
bitStream.Write(zoneClone);
|
||||
bitStream.Write(static_cast<uint16_t>(serverPort));
|
||||
PacketUtils::WriteString(bitStream, serverIP, static_cast<uint32_t>(serverIP.size() + 1));
|
||||
bitStream.Write(LUString(serverIP, 255));
|
||||
|
||||
server->Send(&bitStream, sysAddr, false);
|
||||
}
|
||||
@@ -99,25 +99,26 @@ void MasterPackets::HandleServerInfo(Packet* packet) {
|
||||
uint32_t theirPort = 0;
|
||||
uint32_t theirZoneID = 0;
|
||||
uint32_t theirInstanceID = 0;
|
||||
std::string theirIP = "";
|
||||
LUString theirIP(33);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void MasterPackets::SendServerInfo(dServer* server, Packet* packet) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SERVER_INFO);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SERVER_INFO);
|
||||
|
||||
bitStream.Write(server->GetPort());
|
||||
bitStream.Write(server->GetZoneID());
|
||||
bitStream.Write(server->GetInstanceID());
|
||||
bitStream.Write(server->GetServerType());
|
||||
PacketUtils::WriteString(bitStream, server->GetIP(), server->GetIP().size());
|
||||
bitStream.Write<uint32_t>(server->GetIP().size());
|
||||
bitStream.Write(server->GetIP());
|
||||
|
||||
server->SendToMaster(&bitStream);
|
||||
}
|
||||
|
@@ -1,139 +1,8 @@
|
||||
#include "PacketUtils.h"
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "dLogger.h"
|
||||
#include "Game.h"
|
||||
|
||||
uint16_t PacketUtils::ReadPacketU16(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::ReadPacketU32(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::ReadPacketU64(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::ReadPacketS64(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 > (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;
|
||||
}
|
||||
|
||||
void PacketUtils::WritePacketString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream) {
|
||||
uint32_t size = static_cast<uint32_t>(string.size());
|
||||
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
|
||||
|
||||
if (size > maxSize) size = maxSize;
|
||||
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
bitStream->Write(static_cast<char>(string[i]));
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < remSize; ++j) {
|
||||
bitStream->Write(static_cast<char>(0));
|
||||
}
|
||||
}
|
||||
|
||||
void PacketUtils::WriteString(RakNet::BitStream& bitStream, const std::string& s, uint32_t maxSize) {
|
||||
uint32_t size = s.size();
|
||||
uint32_t emptySize = maxSize - size;
|
||||
|
||||
if (size > maxSize) size = maxSize;
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
bitStream.Write((char)s[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < emptySize; i++) {
|
||||
bitStream.Write((char)0);
|
||||
}
|
||||
}
|
||||
|
||||
void PacketUtils::WriteWString(RakNet::BitStream& bitStream, const std::string& string, uint32_t maxSize) {
|
||||
uint32_t size = static_cast<uint32_t>(string.length());
|
||||
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
|
||||
|
||||
if (size > maxSize) size = maxSize;
|
||||
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
bitStream.Write(static_cast<uint16_t>(string[i]));
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < remSize; ++j) {
|
||||
bitStream.Write(static_cast<uint16_t>(0));
|
||||
}
|
||||
}
|
||||
|
||||
void PacketUtils::WriteWString(RakNet::BitStream& bitStream, const std::u16string& string, uint32_t maxSize) {
|
||||
uint32_t size = static_cast<uint32_t>(string.length());
|
||||
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
|
||||
|
||||
if (size > maxSize) size = maxSize;
|
||||
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
bitStream.Write(static_cast<uint16_t>(string[i]));
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < remSize; ++j) {
|
||||
bitStream.Write(static_cast<uint16_t>(0));
|
||||
}
|
||||
}
|
||||
|
||||
void PacketUtils::WritePacketWString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream) {
|
||||
uint32_t size = static_cast<uint32_t>(string.length());
|
||||
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
|
||||
|
||||
if (size > maxSize) size = maxSize;
|
||||
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
bitStream->Write(static_cast<uint16_t>(string[i]));
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < remSize; ++j) {
|
||||
bitStream->Write(static_cast<uint16_t>(0));
|
||||
}
|
||||
}
|
||||
|
||||
//! 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.
|
||||
|
@@ -1,33 +1,12 @@
|
||||
#ifndef PACKETUTILS_H
|
||||
#define PACKETUTILS_H
|
||||
|
||||
#include <MessageIdentifiers.h>
|
||||
#include <BitStream.h>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "RakNetTypes.h"
|
||||
|
||||
enum class eConnectionType : uint16_t;
|
||||
|
||||
namespace PacketUtils {
|
||||
template<typename T>
|
||||
void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) {
|
||||
bitStream.Write<uint8_t>(MessageID(ID_USER_PACKET_ENUM));
|
||||
bitStream.Write<eConnectionType>(connectionType);
|
||||
bitStream.Write<uint32_t>(static_cast<uint32_t>(internalPacketID));
|
||||
bitStream.Write<uint8_t>(0);
|
||||
}
|
||||
|
||||
uint16_t ReadPacketU16(uint32_t startLoc, Packet* packet);
|
||||
uint32_t ReadPacketU32(uint32_t startLoc, Packet* packet);
|
||||
uint64_t ReadPacketU64(uint32_t startLoc, Packet* packet);
|
||||
int64_t ReadPacketS64(uint32_t startLoc, Packet* packet);
|
||||
std::string ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen = 33);
|
||||
|
||||
void WritePacketString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream);
|
||||
void WriteString(RakNet::BitStream& bitStream, const std::string& s, uint32_t maxSize);
|
||||
void WriteWString(RakNet::BitStream& bitStream, const std::string& string, uint32_t maxSize);
|
||||
void WriteWString(RakNet::BitStream& bitStream, const std::u16string& string, uint32_t maxSize);
|
||||
void WritePacketWString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream);
|
||||
|
||||
void SavePacket(const std::string& filename, const char* data, size_t length);
|
||||
};
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "dCommonVars.h"
|
||||
#include "WorldPackets.h"
|
||||
#include "BitStream.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "BitstreamUtils.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "User.h"
|
||||
#include "Character.h"
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE);
|
||||
|
||||
auto zone = Game::zoneManager->GetZone()->GetZoneID();
|
||||
bitStream.Write(static_cast<uint16_t>(zone.GetMapID()));
|
||||
@@ -41,7 +41,7 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) {
|
||||
if (!user) return;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE);
|
||||
|
||||
std::vector<Character*> characters = user->GetCharacters();
|
||||
bitStream.Write(static_cast<uint8_t>(characters.size()));
|
||||
@@ -51,13 +51,13 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) {
|
||||
bitStream.Write(characters[i]->GetObjectID());
|
||||
bitStream.Write(static_cast<uint32_t>(0));
|
||||
|
||||
PacketUtils::WriteWString(bitStream, characters[i]->GetName(), 33);
|
||||
PacketUtils::WriteWString(bitStream, characters[i]->GetUnapprovedName(), 33);
|
||||
bitStream.Write(LUWString(characters[i]->GetName()));
|
||||
bitStream.Write(LUWString(characters[i]->GetUnapprovedName()));
|
||||
|
||||
bitStream.Write(static_cast<uint8_t>(characters[i]->GetNameRejected()));
|
||||
bitStream.Write(static_cast<uint8_t>(false));
|
||||
|
||||
PacketUtils::WriteString(bitStream, "", 10);
|
||||
bitStream.Write(LUString("", 10));
|
||||
|
||||
bitStream.Write(characters[i]->GetShirtColor());
|
||||
bitStream.Write(characters[i]->GetShirtStyle());
|
||||
@@ -90,30 +90,30 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) {
|
||||
|
||||
void WorldPackets::SendCharacterCreationResponse(const SystemAddress& sysAddr, eCharacterCreationResponse response) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_CREATE_RESPONSE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_CREATE_RESPONSE);
|
||||
bitStream.Write(response);
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCharacterRenameResponse(const SystemAddress& sysAddr, eRenameResponse response) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_RENAME_RESPONSE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_RENAME_RESPONSE);
|
||||
bitStream.Write(response);
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DELETE_CHARACTER_RESPONSE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DELETE_CHARACTER_RESPONSE);
|
||||
bitStream.Write(static_cast<uint8_t>(response));
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TRANSFER_TO_WORLD);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TRANSFER_TO_WORLD);
|
||||
|
||||
PacketUtils::WriteString(bitStream, serverIP, 33);
|
||||
bitStream.Write(LUString(serverIP));
|
||||
bitStream.Write(static_cast<uint16_t>(serverPort));
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
|
||||
@@ -122,14 +122,14 @@ void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::
|
||||
|
||||
void WorldPackets::SendServerState(const SystemAddress& sysAddr) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SERVER_STATES);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SERVER_STATES);
|
||||
bitStream.Write(static_cast<uint8_t>(1)); //If the server is receiving this request, it probably is ready anyway.
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CREATE_CHARACTER);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CREATE_CHARACTER);
|
||||
|
||||
RakNet::BitStream data;
|
||||
data.Write<uint32_t>(7); //LDF key count
|
||||
@@ -198,7 +198,7 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent
|
||||
|
||||
void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems) {
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHAT_MODERATION_STRING);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHAT_MODERATION_STRING);
|
||||
|
||||
bitStream.Write<uint8_t>(unacceptedItems.empty()); // Is sentence ok?
|
||||
bitStream.Write<uint16_t>(0x16); // Source ID, unknown
|
||||
@@ -206,7 +206,7 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool
|
||||
bitStream.Write(static_cast<uint8_t>(requestID)); // request ID
|
||||
bitStream.Write(static_cast<char>(0)); // chat mode
|
||||
|
||||
PacketUtils::WritePacketWString(receiver, 42, &bitStream); // receiver name
|
||||
bitStream.Write(LUWString(receiver, 42)); // receiver name
|
||||
|
||||
for (auto it : unacceptedItems) {
|
||||
bitStream.Write<uint8_t>(it.first); // start index
|
||||
@@ -222,7 +222,7 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool
|
||||
|
||||
void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel) {
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAKE_GM_RESPONSE);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAKE_GM_RESPONSE);
|
||||
|
||||
bitStream.Write<uint8_t>(success);
|
||||
bitStream.Write(static_cast<uint16_t>(highestLevel));
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
// Custom Classes
|
||||
#include "MasterPackets.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "BitstreamUtils.h"
|
||||
#include "dServer.h"
|
||||
|
||||
// C++
|
||||
@@ -26,19 +26,29 @@ 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::ReadPacketU32(17, packet);
|
||||
uint32_t zoneInstance = PacketUtils::ReadPacketU32(21, packet);
|
||||
uint32_t zoneClone = PacketUtils::ReadPacketU32(25, packet);
|
||||
uint16_t serverPort = PacketUtils::ReadPacketU16(29, packet);
|
||||
std::string serverIP = PacketUtils::ReadString(31, packet, false);
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
uint64_t requestIDAgain;
|
||||
inStream.Read(requestIDAgain);
|
||||
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);
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include "eServerMessageType.h"
|
||||
#include "eMasterMessageType.h"
|
||||
|
||||
#include "PacketUtils.h"
|
||||
#include "BitstreamUtils.h"
|
||||
#include "MasterPackets.h"
|
||||
#include "ZoneInstanceManager.h"
|
||||
|
||||
@@ -123,7 +123,9 @@ 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::ReadPacketU64(8, packet);
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
uint64_t requestID;
|
||||
inStream.Read(requestID);
|
||||
ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet);
|
||||
break;
|
||||
}
|
||||
@@ -167,8 +169,9 @@ void dServer::SendToMaster(RakNet::BitStream* bitStream) {
|
||||
}
|
||||
|
||||
void dServer::Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID) {
|
||||
Game::logger->Log("dServer", "Disconnecting reason: %i", disconNotifyID);
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::DISCONNECT_NOTIFY);
|
||||
BitstreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::DISCONNECT_NOTIFY);
|
||||
bitStream.Write(disconNotifyID);
|
||||
mPeer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, sysAddr, false);
|
||||
|
||||
|
@@ -15,6 +15,14 @@ enum class ServerType : uint32_t {
|
||||
World
|
||||
};
|
||||
|
||||
enum class ServiceId : uint32_t{
|
||||
General = 0,
|
||||
Auth = 1,
|
||||
Chat = 2,
|
||||
World = 4,
|
||||
Client = 5,
|
||||
};
|
||||
|
||||
class dServer {
|
||||
public:
|
||||
// Default constructor should only used for testing!
|
||||
|
Reference in New Issue
Block a user