mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-11 07:38:36 +00:00
Merge branch 'master' into lsid
This commit is contained in:
+95
-59
@@ -84,6 +84,7 @@ extern ClientList client_list;
|
||||
extern EQEmu::Random emu_random;
|
||||
extern uint32 numclients;
|
||||
extern volatile bool RunLoops;
|
||||
extern volatile bool UCSServerAvailable_;
|
||||
|
||||
Client::Client(EQStreamInterface* ieqs)
|
||||
: autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)),
|
||||
@@ -170,10 +171,12 @@ void Client::SendEnterWorld(std::string name)
|
||||
void Client::SendExpansionInfo() {
|
||||
auto outapp = new EQApplicationPacket(OP_ExpansionInfo, sizeof(ExpansionInfo_Struct));
|
||||
ExpansionInfo_Struct *eis = (ExpansionInfo_Struct*)outapp->pBuffer;
|
||||
if(RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
eis->Expansions = EQEmu::versions::ConvertClientVersionToExpansion(eqs->ClientVersion());
|
||||
} else {
|
||||
eis->Expansions = (RuleI(World, ExpansionSettings));
|
||||
|
||||
if (RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
eis->Expansions = EQEmu::expansions::ConvertClientVersionToExpansionsMask(eqs->ClientVersion());
|
||||
}
|
||||
else {
|
||||
eis->Expansions = (RuleI(World, ExpansionSettings) & EQEmu::expansions::ConvertClientVersionToExpansionsMask(eqs->ClientVersion()));
|
||||
}
|
||||
|
||||
QueuePacket(outapp);
|
||||
@@ -185,7 +188,7 @@ void Client::SendCharInfo() {
|
||||
cle->SetOnline(CLE_Status_CharSelect);
|
||||
}
|
||||
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::maskRoFAndLater) {
|
||||
SendMaxCharCreate();
|
||||
SendMembership();
|
||||
SendMembershipSettings();
|
||||
@@ -210,9 +213,9 @@ void Client::SendMaxCharCreate() {
|
||||
auto outapp = new EQApplicationPacket(OP_SendMaxCharacters, sizeof(MaxCharacters_Struct));
|
||||
MaxCharacters_Struct* mc = (MaxCharacters_Struct*)outapp->pBuffer;
|
||||
|
||||
mc->max_chars = EQEmu::constants::Lookup(m_ClientVersion)->CharacterCreationLimit;
|
||||
if (mc->max_chars > EQEmu::constants::CharacterCreationMax)
|
||||
mc->max_chars = EQEmu::constants::CharacterCreationMax;
|
||||
mc->max_chars = EQEmu::constants::StaticLookup(m_ClientVersion)->CharacterCreationLimit;
|
||||
if (mc->max_chars > EQEmu::constants::CHARACTER_CREATION_LIMIT)
|
||||
mc->max_chars = EQEmu::constants::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
@@ -251,7 +254,7 @@ void Client::SendMembership() {
|
||||
mc->entries[1] = 0xffffffff; // Max Level Restriction
|
||||
mc->entries[2] = 0xffffffff; // Max Char Slots per Account (not used by client?)
|
||||
mc->entries[3] = 0xffffffff; // 1 for Silver
|
||||
mc->entries[4] = 8; // Main Inventory Size (0xffffffff on Live for Gold, but limiting to 8 until 10 is supported)
|
||||
mc->entries[4] = 0xffffffff; // Main Inventory Size (0xffffffff on Live for Gold, but limiting to 8 until 10 is supported)
|
||||
mc->entries[5] = 0xffffffff; // Max Platinum per level
|
||||
mc->entries[6] = 1; // 0 for Silver
|
||||
mc->entries[7] = 1; // 0 for Silver
|
||||
@@ -676,7 +679,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier)
|
||||
if (m_ClientVersionBit & EQEmu::versions::maskTitaniumAndEarlier)
|
||||
StartInTutorial = true;
|
||||
SendCharInfo();
|
||||
}
|
||||
@@ -724,9 +727,9 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
// This can probably be moved outside and have another method return requested info (don't forget to remove the #include "../common/shareddb.h" above)
|
||||
// (This is a literal translation of the original process..I don't see why it can't be changed to a single-target query over account iteration)
|
||||
if (!is_player_zoning) {
|
||||
size_t character_limit = EQEmu::constants::Lookup(eqs->ClientVersion())->CharacterCreationLimit;
|
||||
if (character_limit > EQEmu::constants::CharacterCreationMax) { character_limit = EQEmu::constants::CharacterCreationMax; }
|
||||
if (eqs->ClientVersion() == EQEmu::versions::ClientVersion::Titanium) { character_limit = 8; }
|
||||
size_t character_limit = EQEmu::constants::StaticLookup(eqs->ClientVersion())->CharacterCreationLimit;
|
||||
if (character_limit > EQEmu::constants::CHARACTER_CREATION_LIMIT) { character_limit = EQEmu::constants::CHARACTER_CREATION_LIMIT; }
|
||||
if (eqs->ClientVersion() == EQEmu::versions::ClientVersion::Titanium) { character_limit = Titanium::constants::CHARACTER_CREATION_LIMIT; }
|
||||
|
||||
std::string tgh_query = StringFormat(
|
||||
"SELECT "
|
||||
@@ -850,53 +853,84 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
|
||||
// set mailkey - used for duration of character session
|
||||
int MailKey = emu_random.Int(1, INT_MAX);
|
||||
|
||||
database.SetMailKey(charid, GetIP(), MailKey);
|
||||
if (UCSServerAvailable_) {
|
||||
const WorldConfig *Config = WorldConfig::get();
|
||||
std::string buffer;
|
||||
|
||||
char ConnectionType;
|
||||
EQEmu::versions::UCSVersion ConnectionType = EQEmu::versions::ucsUnknown;
|
||||
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
||||
ConnectionType = 'U';
|
||||
else if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater)
|
||||
ConnectionType = 'S';
|
||||
else
|
||||
ConnectionType = 'C';
|
||||
// chat server packet
|
||||
switch (GetClientVersion()) {
|
||||
case EQEmu::versions::ClientVersion::Titanium:
|
||||
ConnectionType = EQEmu::versions::ucsTitaniumChat;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::SoF:
|
||||
ConnectionType = EQEmu::versions::ucsSoFCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::SoD:
|
||||
ConnectionType = EQEmu::versions::ucsSoDCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::UF:
|
||||
ConnectionType = EQEmu::versions::ucsUFCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF:
|
||||
ConnectionType = EQEmu::versions::ucsRoFCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF2:
|
||||
ConnectionType = EQEmu::versions::ucsRoF2Combined;
|
||||
break;
|
||||
default:
|
||||
ConnectionType = EQEmu::versions::ucsUnknown;
|
||||
break;
|
||||
}
|
||||
|
||||
auto outapp2 = new EQApplicationPacket(OP_SetChatServer);
|
||||
char buffer[112];
|
||||
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
||||
Config->ChatHost.c_str(),
|
||||
Config->ChatPort,
|
||||
Config->ShortName.c_str(),
|
||||
GetCharName(),
|
||||
ConnectionType,
|
||||
MailKey
|
||||
);
|
||||
|
||||
const WorldConfig *Config = WorldConfig::get();
|
||||
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
|
||||
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||
outapp->pBuffer[buffer.length()] = '\0';
|
||||
|
||||
sprintf(buffer,"%s,%i,%s.%s,%c%08X",
|
||||
Config->ChatHost.c_str(),
|
||||
Config->ChatPort,
|
||||
Config->ShortName.c_str(),
|
||||
this->GetCharName(), ConnectionType, MailKey
|
||||
);
|
||||
outapp2->size=strlen(buffer)+1;
|
||||
outapp2->pBuffer = new uchar[outapp2->size];
|
||||
memcpy(outapp2->pBuffer,buffer,outapp2->size);
|
||||
QueuePacket(outapp2);
|
||||
safe_delete(outapp2);
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
outapp2 = new EQApplicationPacket(OP_SetChatServer2);
|
||||
// mail server packet
|
||||
switch (GetClientVersion()) {
|
||||
case EQEmu::versions::ClientVersion::Titanium:
|
||||
ConnectionType = EQEmu::versions::ucsTitaniumMail;
|
||||
break;
|
||||
default:
|
||||
// retain value from previous switch
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier)
|
||||
ConnectionType = 'M';
|
||||
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
||||
Config->MailHost.c_str(),
|
||||
Config->MailPort,
|
||||
Config->ShortName.c_str(),
|
||||
GetCharName(),
|
||||
ConnectionType,
|
||||
MailKey
|
||||
);
|
||||
|
||||
sprintf(buffer,"%s,%i,%s.%s,%c%08X",
|
||||
Config->MailHost.c_str(),
|
||||
Config->MailPort,
|
||||
Config->ShortName.c_str(),
|
||||
this->GetCharName(), ConnectionType, MailKey
|
||||
);
|
||||
outapp2->size=strlen(buffer)+1;
|
||||
outapp2->pBuffer = new uchar[outapp2->size];
|
||||
memcpy(outapp2->pBuffer,buffer,outapp2->size);
|
||||
QueuePacket(outapp2);
|
||||
safe_delete(outapp2);
|
||||
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
|
||||
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||
outapp->pBuffer[buffer.length()] = '\0';
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
EnterWorld();
|
||||
|
||||
@@ -917,7 +951,7 @@ bool Client::HandleDeleteCharacterPacket(const EQApplicationPacket *app) {
|
||||
|
||||
bool Client::HandleZoneChangePacket(const EQApplicationPacket *app) {
|
||||
// HoT sends this to world while zoning and wants it echoed back.
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater)
|
||||
if (m_ClientVersionBit & EQEmu::versions::maskRoFAndLater)
|
||||
{
|
||||
QueuePacket(app);
|
||||
}
|
||||
@@ -1370,6 +1404,11 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
PlayerProfile_Struct pp;
|
||||
ExtendedProfile_Struct ext;
|
||||
EQEmu::InventoryProfile inv;
|
||||
|
||||
pp.SetPlayerProfileVersion(EQEmu::versions::ConvertClientVersionToMobVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit)));
|
||||
inv.SetInventoryVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit));
|
||||
inv.SetGMInventory(false); // character cannot have gm flag at this point
|
||||
|
||||
time_t bday = time(nullptr);
|
||||
char startzone[50]={0};
|
||||
uint32 i;
|
||||
@@ -1392,7 +1431,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
Log(Logs::Detail, Logs::World_Server, "Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
|
||||
|
||||
/* Validate the char creation struct */
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::maskSoFAndLater) {
|
||||
if (!CheckCharCreateInfoSoF(cc)) {
|
||||
Log(Logs::Detail, Logs::World_Server,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
|
||||
return false;
|
||||
@@ -1449,12 +1488,9 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
|
||||
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
|
||||
|
||||
|
||||
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++)
|
||||
pp.spell_book[i] = 0xFFFFFFFF;
|
||||
|
||||
for(i = 0; i < MAX_PP_MEMSPELL; i++)
|
||||
pp.mem_spells[i] = 0xFFFFFFFF;
|
||||
memset(pp.spell_book, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELLBOOK_SIZE));
|
||||
|
||||
memset(pp.mem_spells, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELL_GEM_COUNT));
|
||||
|
||||
for(i = 0; i < BUFF_COUNT; i++)
|
||||
pp.buffs[i].spellid = 0xFFFF;
|
||||
@@ -1463,7 +1499,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
|
||||
|
||||
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::maskSoFAndLater) {
|
||||
Log(Logs::Detail, Logs::World_Server,"Found 'SoFStartZoneID' rule setting: %i", RuleI(World, SoFStartZoneID));
|
||||
if (RuleI(World, SoFStartZoneID) > 0) {
|
||||
pp.zone_id = RuleI(World, SoFStartZoneID);
|
||||
@@ -1479,7 +1515,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
}
|
||||
}
|
||||
/* use normal starting zone logic to either get defaults, or if startzone was set, load that from the db table.*/
|
||||
bool ValidStartZone = database.GetStartZone(&pp, cc, m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier);
|
||||
bool ValidStartZone = database.GetStartZone(&pp, cc, m_ClientVersionBit & EQEmu::versions::maskTitaniumAndEarlier);
|
||||
|
||||
if (!ValidStartZone){
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user