Merge branch 'main' into guild_temp

This commit is contained in:
Aaron Kimbre
2023-11-19 21:15:06 -06:00
170 changed files with 2306 additions and 1586 deletions

View File

@@ -27,6 +27,7 @@
#include "eConnectionType.h"
#include "eServerMessageType.h"
#include "eMasterMessageType.h"
#include "eGameMasterLevel.h"
void AuthPackets::HandleHandshake(dServer* server, Packet* packet) {
RakNet::BitStream inStream(packet->data, packet->length, false);
@@ -64,120 +65,54 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
const char* szUsername = username.c_str();
// 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);
auto accountInfo = Database::Get()->GetAccountInfo(username);
sql::ResultSet* res = stmt->executeQuery();
if (res->rowsCount() == 0) {
LOG("No user found!");
if (!accountInfo) {
LOG("No user by name %s found!", username.c_str());
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, username);
return;
}
std::string sqlPass = "";
bool sqlBanned = false;
bool sqlLocked = false;
uint32_t sqlPlayKey = 0;
uint32_t sqlGmLevel = 0;
while (res->next()) {
sqlPass = res->getString(1).c_str();
sqlBanned = res->getBoolean(2);
sqlLocked = res->getBoolean(3);
sqlPlayKey = res->getInt(4);
sqlGmLevel = res->getInt(5);
}
delete stmt;
delete res;
//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) {
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);
return;
}
if (Game::config->GetValue("dont_use_keys") != "1") {
if (Game::config->GetValue("dont_use_keys") != "1" && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) {
LOG("");
//Check to see if we have a play key:
if (sqlPlayKey == 0 && sqlGmLevel == 0) {
if (accountInfo->playKeyId == 0) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username);
LOG("User %s tried to log in, but they don't have a play key.", username.c_str());
return;
}
//Check if the play key is _valid_:
auto keyCheckStmt = Database::CreatePreppedStmt("SELECT active FROM `play_keys` WHERE id=?");
keyCheckStmt->setInt(1, sqlPlayKey);
auto keyRes = keyCheckStmt->executeQuery();
bool isKeyActive = false;
auto playKeyStatus = Database::Get()->IsPlaykeyActive(accountInfo->playKeyId);
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);
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);
return;
}
while (keyRes->next()) {
isKeyActive = (bool)keyRes->getInt(1);
}
if (!isKeyActive && sqlGmLevel == 0) {
if (!playKeyStatus.value()) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, username);
LOG("User %s tried to log in, but their play key was disabled", username.c_str());
return;
}
}
if (sqlBanned) {
if (accountInfo->banned) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, username); return;
}
if (sqlLocked) {
if (accountInfo->locked) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, username); return;
}
/*
* Updated hashing method:
* First attempt bcrypt.
* If that fails, fallback to old method and setup bcrypt for new login.
*/
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
}
bool loginSuccess = ::bcrypt_checkpw(password.c_str(), accountInfo->bcryptPassword.c_str()) == 0;
if (!loginSuccess) {
AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, username);
@@ -203,18 +138,25 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd
packet.Write(static_cast<uint8_t>(responseCode));
// Event Gating
packet.Write(LUString("Talk_Like_A_Pirate"));
packet.Write(LUString("guilds"));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
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")));
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
uint16_t version_major = 1;
uint16_t version_current = 10;
uint16_t version_minor = 64;
GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_major"), version_major);
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);
// Writes the user key
uint32_t sessionKey = GeneralUtils::GenerateRandomNumber<uint32_t>();

View File

@@ -355,30 +355,18 @@ void ClientPackets::HandleChatModerationRequest(const SystemAddress& sysAddr, Pa
LWOOBJID idOfReceiver = LWOOBJID_EMPTY;
{
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT name FROM charinfo WHERE name = ?");
stmt->setString(1, receiver);
auto characterIdFetch = Database::Get()->GetCharacterInfo(receiver);
sql::ResultSet* res = stmt->executeQuery();
if (res->next()) {
idOfReceiver = res->getInt("id");
if (characterIdFetch) {
idOfReceiver = characterIdFetch->id;
}
delete stmt;
delete res;
}
if (user->GetIsBestFriendMap().find(receiver) == user->GetIsBestFriendMap().end() && idOfReceiver != LWOOBJID_EMPTY) {
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;");
stmt->setInt(1, entity->GetObjectID());
stmt->setInt(2, idOfReceiver);
stmt->setInt(3, idOfReceiver);
stmt->setInt(4, entity->GetObjectID());
auto bffInfo = Database::Get()->GetBestFriendStatus(entity->GetObjectID(), idOfReceiver);
sql::ResultSet* res = stmt->executeQuery();
if (res->next()) {
isBestFriend = res->getInt("best_friend") == 3;
if (bffInfo) {
isBestFriend = bffInfo->bestFriendStatus == 3;
}
if (isBestFriend) {
@@ -386,9 +374,6 @@ void ClientPackets::HandleChatModerationRequest(const SystemAddress& sysAddr, Pa
tmpBestFriendMap[receiver] = true;
user->SetIsBestFriendMap(tmpBestFriendMap);
}
delete res;
delete stmt;
} else if (user->GetIsBestFriendMap().find(receiver) != user->GetIsBestFriendMap().end()) {
isBestFriend = true;
}