mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-02 16:46:37 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into web_interface
# Conflicts: # zone/attack.cpp # zone/entity.cpp # zone/net.cpp # zone/worldserver.cpp # zone/zone.cpp
This commit is contained in:
+210
-144
@@ -1,3 +1,21 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eq_packet.h"
|
||||
#include "../common/eq_stream_intf.h"
|
||||
@@ -14,7 +32,7 @@
|
||||
#include "../common/skills.h"
|
||||
#include "../common/extprofile.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/clientversions.h"
|
||||
#include "../common/emu_versions.h"
|
||||
#include "../common/random.h"
|
||||
#include "../common/shareddb.h"
|
||||
|
||||
@@ -43,8 +61,8 @@
|
||||
|
||||
// Disgrace: for windows compile
|
||||
#ifdef _WINDOWS
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#else
|
||||
|
||||
#ifdef FREEBSD //Timothy Whitman - January 7, 2003
|
||||
@@ -80,22 +98,22 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
|
||||
autobootup_timeout.Disable();
|
||||
connect.Disable();
|
||||
seencharsel = false;
|
||||
seen_character_select = false;
|
||||
cle = 0;
|
||||
zoneID = 0;
|
||||
zone_id = 0;
|
||||
char_name[0] = 0;
|
||||
charid = 0;
|
||||
pwaitingforbootup = 0;
|
||||
zone_waiting_for_bootup = 0;
|
||||
StartInTutorial = false;
|
||||
|
||||
m_ClientVersion = eqs->GetClientVersion();
|
||||
m_ClientVersionBit = ClientBitFromVersion(m_ClientVersion);
|
||||
m_ClientVersion = eqs->ClientVersion();
|
||||
m_ClientVersionBit = EQEmu::versions::ConvertClientVersionToClientVersionBit(m_ClientVersion);
|
||||
|
||||
numclients++;
|
||||
}
|
||||
|
||||
Client::~Client() {
|
||||
if (RunLoops && cle && zoneID == 0)
|
||||
if (RunLoops && cle && zone_id == 0)
|
||||
cle->SetOnline(CLE_Status_Offline);
|
||||
|
||||
numclients--;
|
||||
@@ -124,7 +142,7 @@ void Client::SendLogServer()
|
||||
if(RuleB(World, IsGMPetitionWindowEnabled))
|
||||
l->enable_petition_wnd = 1;
|
||||
|
||||
if(RuleI(World, FVNoDropFlag) == 1 || RuleI(World, FVNoDropFlag) == 2 && GetAdmin() > RuleI(Character, MinStatusForNoDropExemptions))
|
||||
if((RuleI(World, FVNoDropFlag) == 1 || RuleI(World, FVNoDropFlag) == 2) && GetAdmin() > RuleI(Character, MinStatusForNoDropExemptions))
|
||||
l->enable_FV = 1;
|
||||
|
||||
QueuePacket(outapp);
|
||||
@@ -134,7 +152,7 @@ void Client::SendLogServer()
|
||||
void Client::SendEnterWorld(std::string name)
|
||||
{
|
||||
char char_name[64] = { 0 };
|
||||
if (pZoning && database.GetLiveChar(GetAccountID(), char_name)) {
|
||||
if (is_player_zoning && database.GetLiveChar(GetAccountID(), char_name)) {
|
||||
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
|
||||
eqs->Close();
|
||||
return;
|
||||
@@ -152,7 +170,13 @@ 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;
|
||||
eis->Expansions = (RuleI(World, ExpansionSettings));
|
||||
if(RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
eis->Expansions = EQEmu::versions::ConvertClientVersionToExpansion(eqs->ClientVersion());
|
||||
//eis->Expansions = ExpansionFromClientVersion(this->GetCLE.
|
||||
} else {
|
||||
eis->Expansions = (RuleI(World, ExpansionSettings));
|
||||
}
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
@@ -162,13 +186,13 @@ void Client::SendCharInfo() {
|
||||
cle->SetOnline(CLE_Status_CharSelect);
|
||||
}
|
||||
|
||||
if (m_ClientVersionBit & BIT_RoFAndLater) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater) {
|
||||
SendMaxCharCreate();
|
||||
SendMembership();
|
||||
SendMembershipSettings();
|
||||
}
|
||||
|
||||
seencharsel = true;
|
||||
seen_character_select = true;
|
||||
|
||||
// Send OP_SendCharInfo
|
||||
EQApplicationPacket *outapp = nullptr;
|
||||
@@ -187,9 +211,9 @@ void Client::SendMaxCharCreate() {
|
||||
auto outapp = new EQApplicationPacket(OP_SendMaxCharacters, sizeof(MaxCharacters_Struct));
|
||||
MaxCharacters_Struct* mc = (MaxCharacters_Struct*)outapp->pBuffer;
|
||||
|
||||
mc->max_chars = EQLimits::CharacterCreationLimit(m_ClientVersion);
|
||||
if (mc->max_chars > EmuConstants::CHARACTER_CREATION_LIMIT)
|
||||
mc->max_chars = EmuConstants::CHARACTER_CREATION_LIMIT;
|
||||
mc->max_chars = EQEmu::constants::Lookup(m_ClientVersion)->CharacterCreationLimit;
|
||||
if (mc->max_chars > EQEmu::constants::CharacterCreationMax)
|
||||
mc->max_chars = EQEmu::constants::CharacterCreationMax;
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
@@ -387,7 +411,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pZoning=(li->zoning==1);
|
||||
is_player_zoning=(li->zoning==1);
|
||||
|
||||
#ifdef IPBASED_AUTH_HACK
|
||||
struct in_addr tmpip;
|
||||
@@ -412,32 +436,33 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
|
||||
#ifdef IPBASED_AUTH_HACK
|
||||
if ((cle = zoneserver_list.CheckAuth(inet_ntoa(tmpip), password)))
|
||||
#else
|
||||
if (loginserverlist.Connected() == false && !pZoning) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Error: Login server login while not connected to login server.");
|
||||
if (loginserverlist.Connected() == false && !is_player_zoning) {
|
||||
Log.Out(Logs::General, Logs::World_Server,"Error: Login server login while not connected to login server.");
|
||||
return false;
|
||||
}
|
||||
if (((cle = client_list.CheckAuth(name, password)) || (cle = client_list.CheckAuth(id, password))))
|
||||
#endif
|
||||
{
|
||||
if (cle->AccountID() == 0 || (!minilogin && cle->LSID()==0)) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"ID is 0. Is this server connected to minilogin?");
|
||||
Log.Out(Logs::General, Logs::World_Server,"ID is 0. Is this server connected to minilogin?");
|
||||
if(!minilogin)
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"If so you forget the minilogin variable...");
|
||||
Log.Out(Logs::General, Logs::World_Server,"If so you forget the minilogin variable...");
|
||||
else
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Could not find a minilogin account, verify ip address logging into minilogin is the same that is in your account table.");
|
||||
Log.Out(Logs::General, Logs::World_Server,"Could not find a minilogin account, verify ip address logging into minilogin is the same that is in your account table.");
|
||||
return false;
|
||||
}
|
||||
|
||||
cle->SetOnline();
|
||||
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Logged in. Mode=%s",pZoning ? "(Zoning)" : "(CharSel)");
|
||||
|
||||
if(minilogin){
|
||||
WorldConfig::DisableStats();
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"MiniLogin Account #%d",cle->AccountID());
|
||||
Log.Out(Logs::General, Logs::World_Server, "MiniLogin Account #%d",cle->AccountID());
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"LS Account #%d",cle->LSID());
|
||||
if (!is_player_zoning) {
|
||||
Log.Out(Logs::General, Logs::World_Server,
|
||||
"Account (%s) Logging in :: LSID: %d ", cle->AccountName(), cle->LSID());
|
||||
}
|
||||
}
|
||||
|
||||
const WorldConfig *Config=WorldConfig::get();
|
||||
@@ -455,13 +480,14 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
if (!pZoning)
|
||||
if (!is_player_zoning)
|
||||
SendGuildList();
|
||||
|
||||
SendLogServer();
|
||||
SendApproveWorld();
|
||||
SendEnterWorld(cle->name());
|
||||
SendPostEnterWorld();
|
||||
if (!pZoning) {
|
||||
if (!is_player_zoning) {
|
||||
SendExpansionInfo();
|
||||
SendCharInfo();
|
||||
database.LoginIP(cle->AccountID(), long2ip(GetIP()).c_str());
|
||||
@@ -492,7 +518,7 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
|
||||
uchar race = app->pBuffer[64];
|
||||
uchar clas = app->pBuffer[68];
|
||||
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Name approval request. Name=%s, race=%s, class=%s", char_name, GetRaceName(race), GetEQClassName(clas));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Name approval request. Name=%s, race=%s, class=%s", char_name, GetRaceIDName(race), GetClassIDName(clas));
|
||||
|
||||
EQApplicationPacket *outapp;
|
||||
outapp = new EQApplicationPacket;
|
||||
@@ -674,7 +700,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_ClientVersionBit & BIT_TitaniumAndEarlier)
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier)
|
||||
StartInTutorial = true;
|
||||
SendCharInfo();
|
||||
}
|
||||
@@ -705,7 +731,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
|
||||
EQApplicationPacket *outapp;
|
||||
uint32 tmpaccid = 0;
|
||||
charid = database.GetCharacterInfo(char_name, &tmpaccid, &zoneID, &instanceID);
|
||||
charid = database.GetCharacterInfo(char_name, &tmpaccid, &zone_id, &instance_id);
|
||||
if (charid == 0 || tmpaccid != GetAccountID()) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Could not get CharInfo for '%s'",char_name);
|
||||
eqs->Close();
|
||||
@@ -721,10 +747,10 @@ 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 (!pZoning) {
|
||||
size_t character_limit = EQLimits::CharacterCreationLimit(eqs->GetClientVersion());
|
||||
if (character_limit > EmuConstants::CHARACTER_CREATION_LIMIT) { character_limit = EmuConstants::CHARACTER_CREATION_LIMIT; }
|
||||
if (eqs->GetClientVersion() == ClientVersion::Titanium) { character_limit = 8; }
|
||||
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; }
|
||||
|
||||
std::string tgh_query = StringFormat(
|
||||
"SELECT "
|
||||
@@ -753,7 +779,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
if (home_enabled) {
|
||||
zoneID = database.MoveCharacterToBind(charid, 4);
|
||||
zone_id = database.MoveCharacterToBind(charid, 4);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "'%s' is trying to go home before they're able...", char_name);
|
||||
@@ -776,8 +802,8 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
if (tutorial_enabled) {
|
||||
zoneID = RuleI(World, TutorialZoneID);
|
||||
database.MoveCharacterToZone(charid, database.GetZoneName(zoneID));
|
||||
zone_id = RuleI(World, TutorialZoneID);
|
||||
database.MoveCharacterToZone(charid, database.GetZoneName(zone_id));
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "'%s' is trying to go to tutorial but are not allowed...", char_name);
|
||||
@@ -788,30 +814,30 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
}
|
||||
|
||||
if (zoneID == 0 || !database.GetZoneName(zoneID)) {
|
||||
if (zone_id == 0 || !database.GetZoneName(zone_id)) {
|
||||
// This is to save people in an invalid zone, once it's removed from the DB
|
||||
database.MoveCharacterToZone(charid, "arena");
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone not found in database zone_id=%i, moveing char to arena character:%s", zoneID, char_name);
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone not found in database zone_id=%i, moveing char to arena character:%s", zone_id, char_name);
|
||||
}
|
||||
|
||||
if(instanceID > 0)
|
||||
if(instance_id > 0)
|
||||
{
|
||||
if(!database.VerifyInstanceAlive(instanceID, GetCharID()))
|
||||
if(!database.VerifyInstanceAlive(instance_id, GetCharID()))
|
||||
{
|
||||
zoneID = database.MoveCharacterToBind(charid);
|
||||
instanceID = 0;
|
||||
zone_id = database.MoveCharacterToBind(charid);
|
||||
instance_id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!database.VerifyZoneInstance(zoneID, instanceID))
|
||||
if(!database.VerifyZoneInstance(zone_id, instance_id))
|
||||
{
|
||||
zoneID = database.MoveCharacterToBind(charid);
|
||||
instanceID = 0;
|
||||
zone_id = database.MoveCharacterToBind(charid);
|
||||
instance_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!pZoning) {
|
||||
if(!is_player_zoning) {
|
||||
database.SetGroupID(char_name, 0, charid);
|
||||
database.SetLoginFlags(charid, false, false, 1);
|
||||
}
|
||||
@@ -833,12 +859,12 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
outapp = new EQApplicationPacket(OP_MOTD);
|
||||
char tmp[500] = {0};
|
||||
if (database.GetVariable("MOTD", tmp, 500)) {
|
||||
outapp->size = strlen(tmp)+1;
|
||||
std::string tmp;
|
||||
if (database.GetVariable("MOTD", tmp)) {
|
||||
outapp->size = tmp.length() + 1;
|
||||
outapp->pBuffer = new uchar[outapp->size];
|
||||
memset(outapp->pBuffer,0,outapp->size);
|
||||
strcpy((char*)outapp->pBuffer, tmp);
|
||||
strcpy((char*)outapp->pBuffer, tmp.c_str());
|
||||
|
||||
} else {
|
||||
// Null Message of the Day. :)
|
||||
@@ -855,9 +881,9 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
|
||||
char ConnectionType;
|
||||
|
||||
if (m_ClientVersionBit & BIT_UFAndLater)
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
||||
ConnectionType = 'U';
|
||||
else if (m_ClientVersionBit & BIT_SoFAndLater)
|
||||
else if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater)
|
||||
ConnectionType = 'S';
|
||||
else
|
||||
ConnectionType = 'C';
|
||||
@@ -881,7 +907,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
|
||||
outapp2 = new EQApplicationPacket(OP_SetChatServer2);
|
||||
|
||||
if (m_ClientVersionBit & BIT_TitaniumAndEarlier)
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier)
|
||||
ConnectionType = 'M';
|
||||
|
||||
sprintf(buffer,"%s,%i,%s.%s,%c%08X",
|
||||
@@ -915,7 +941,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 & BIT_RoFAndLater)
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater)
|
||||
{
|
||||
QueuePacket(app);
|
||||
}
|
||||
@@ -1033,8 +1059,8 @@ bool Client::Process() {
|
||||
to.sin_addr.s_addr = ip;
|
||||
|
||||
if (autobootup_timeout.Check()) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone bootup timer expired, bootup failed or too slow.");
|
||||
ZoneUnavail();
|
||||
Log.Out(Logs::General, Logs::World_Server, "Zone bootup timer expired, bootup failed or too slow.");
|
||||
TellClientZoneUnavailable();
|
||||
}
|
||||
if(connect.Check()){
|
||||
SendGuildList();// Send OPCode: OP_GuildsList
|
||||
@@ -1075,63 +1101,63 @@ bool Client::Process() {
|
||||
}
|
||||
|
||||
void Client::EnterWorld(bool TryBootup) {
|
||||
if (zoneID == 0)
|
||||
if (zone_id == 0)
|
||||
return;
|
||||
|
||||
ZoneServer* zs = nullptr;
|
||||
if(instanceID > 0)
|
||||
ZoneServer* zone_server = nullptr;
|
||||
if(instance_id > 0)
|
||||
{
|
||||
if(database.VerifyInstanceAlive(instanceID, GetCharID()))
|
||||
if(database.VerifyInstanceAlive(instance_id, GetCharID()))
|
||||
{
|
||||
if(database.VerifyZoneInstance(zoneID, instanceID))
|
||||
if(database.VerifyZoneInstance(zone_id, instance_id))
|
||||
{
|
||||
zs = zoneserver_list.FindByInstanceID(instanceID);
|
||||
zone_server = zoneserver_list.FindByInstanceID(instance_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
instanceID = 0;
|
||||
zs = nullptr;
|
||||
instance_id = 0;
|
||||
zone_server = nullptr;
|
||||
database.MoveCharacterToBind(GetCharID());
|
||||
ZoneUnavail();
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
instanceID = 0;
|
||||
zs = nullptr;
|
||||
instance_id = 0;
|
||||
zone_server = nullptr;
|
||||
database.MoveCharacterToBind(GetCharID());
|
||||
ZoneUnavail();
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
zs = zoneserver_list.FindByZoneID(zoneID);
|
||||
zone_server = zoneserver_list.FindByZoneID(zone_id);
|
||||
|
||||
|
||||
const char *zone_name=database.GetZoneName(zoneID, true);
|
||||
if (zs) {
|
||||
const char *zone_name = database.GetZoneName(zone_id, true);
|
||||
if (zone_server) {
|
||||
// warn the world we're comming, so it knows not to shutdown
|
||||
zs->IncomingClient(this);
|
||||
zone_server->IncomingClient(this);
|
||||
}
|
||||
else {
|
||||
if (TryBootup) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Attempting autobootup of %s (%d:%d)",zone_name,zoneID,instanceID);
|
||||
Log.Out(Logs::General, Logs::World_Server, "Attempting autobootup of %s (%d:%d)", zone_name, zone_id, instance_id);
|
||||
autobootup_timeout.Start();
|
||||
pwaitingforbootup = zoneserver_list.TriggerBootup(zoneID, instanceID);
|
||||
if (pwaitingforbootup == 0) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"No zoneserver available to boot up.");
|
||||
ZoneUnavail();
|
||||
zone_waiting_for_bootup = zoneserver_list.TriggerBootup(zone_id, instance_id);
|
||||
if (zone_waiting_for_bootup == 0) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "No zoneserver available to boot up.");
|
||||
TellClientZoneUnavailable();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Requested zone %s is not running.",zone_name);
|
||||
ZoneUnavail();
|
||||
Log.Out(Logs::General, Logs::World_Server, "Requested zone %s is not running.", zone_name);
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
pwaitingforbootup = 0;
|
||||
zone_waiting_for_bootup = 0;
|
||||
|
||||
if(!cle) {
|
||||
return;
|
||||
@@ -1139,12 +1165,20 @@ void Client::EnterWorld(bool TryBootup) {
|
||||
|
||||
cle->SetChar(charid, char_name);
|
||||
database.UpdateLiveChar(char_name, GetAccountID());
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"%s %s (%d:%d)",seencharsel ? "Entering zone" : "Zoning to",zone_name,zoneID,instanceID);
|
||||
|
||||
if (seencharsel) {
|
||||
if (GetAdmin() < 80 && zoneserver_list.IsZoneLocked(zoneID)) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Enter world failed. Zone is locked.");
|
||||
ZoneUnavail();
|
||||
Log.Out(Logs::General, Logs::World_Server,
|
||||
"(%s) %s %s (Zone ID %d: Instance ID: %d) ",
|
||||
char_name,
|
||||
(seen_character_select ? "Zoning from character select" : "Zoning to"),
|
||||
zone_name,
|
||||
zone_id,
|
||||
instance_id
|
||||
);
|
||||
|
||||
if (seen_character_select) {
|
||||
if (GetAdmin() < 80 && zoneserver_list.IsZoneLocked(zone_id)) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Enter world failed. Zone is locked.");
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1156,7 +1190,7 @@ void Client::EnterWorld(bool TryBootup) {
|
||||
WorldToZone_Struct* wtz = (WorldToZone_Struct*) pack->pBuffer;
|
||||
wtz->account_id = GetAccountID();
|
||||
wtz->response = 0;
|
||||
zs->SendPacket(pack);
|
||||
zone_server->SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
else { // if they havent seen character select screen, we can assume this is a zone
|
||||
@@ -1168,13 +1202,13 @@ void Client::EnterWorld(bool TryBootup) {
|
||||
void Client::Clearance(int8 response)
|
||||
{
|
||||
ZoneServer* zs = nullptr;
|
||||
if(instanceID > 0)
|
||||
if(instance_id > 0)
|
||||
{
|
||||
zs = zoneserver_list.FindByInstanceID(instanceID);
|
||||
zs = zoneserver_list.FindByInstanceID(instance_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
zs = zoneserver_list.FindByZoneID(zoneID);
|
||||
zs = zoneserver_list.FindByZoneID(zone_id);
|
||||
}
|
||||
|
||||
if(zs == 0 || response == -1 || response == 0)
|
||||
@@ -1186,7 +1220,7 @@ void Client::Clearance(int8 response)
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Invalid response %d in Client::Clearance", response);
|
||||
}
|
||||
|
||||
ZoneUnavail();
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1194,50 +1228,59 @@ void Client::Clearance(int8 response)
|
||||
|
||||
if (zs->GetCAddress() == nullptr) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Unable to do zs->GetCAddress() in Client::Clearance!!");
|
||||
ZoneUnavail();
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
|
||||
if (zoneID == 0) {
|
||||
if (zone_id == 0) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "zoneID is nullptr in Client::Clearance!!");
|
||||
ZoneUnavail();
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
|
||||
const char* zonename = database.GetZoneName(zoneID);
|
||||
const char* zonename = database.GetZoneName(zone_id);
|
||||
if (zonename == 0) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "zonename is nullptr in Client::Clearance!!");
|
||||
ZoneUnavail();
|
||||
TellClientZoneUnavailable();
|
||||
return;
|
||||
}
|
||||
|
||||
// @bp This is the chat server
|
||||
/*
|
||||
char packetData[] = "64.37.148.34.9876,MyServer,Testchar,23cd2c95";
|
||||
outapp = new EQApplicationPacket(OP_0x0282, sizeof(packetData));
|
||||
strcpy((char*)outapp->pBuffer, packetData);
|
||||
QueuePacket(outapp);
|
||||
delete outapp;
|
||||
*/
|
||||
|
||||
// Send zone server IP data
|
||||
outapp = new EQApplicationPacket(OP_ZoneServerInfo, sizeof(ZoneServerInfo_Struct));
|
||||
ZoneServerInfo_Struct* zsi = (ZoneServerInfo_Struct*)outapp->pBuffer;
|
||||
const char *zs_addr=zs->GetCAddress();
|
||||
if (!zs_addr[0]) {
|
||||
if (cle->IsLocalClient()) {
|
||||
|
||||
const char *zs_addr = nullptr;
|
||||
if(cle && cle->IsLocalClient()) {
|
||||
const char *local_addr = zs->GetCLocalAddress();
|
||||
|
||||
if(local_addr[0]) {
|
||||
zs_addr = local_addr;
|
||||
} else {
|
||||
struct in_addr in;
|
||||
in.s_addr = zs->GetIP();
|
||||
zs_addr=inet_ntoa(in);
|
||||
if (!strcmp(zs_addr,"127.0.0.1"))
|
||||
zs_addr=WorldConfig::get()->LocalAddress.c_str();
|
||||
zs_addr = inet_ntoa(in);
|
||||
|
||||
if(strcmp(zs_addr, "127.0.0.1") == 0)
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Local zone address was %s, setting local address to: %s", zs_addr, WorldConfig::get()->LocalAddress.c_str());
|
||||
zs_addr = WorldConfig::get()->LocalAddress.c_str();
|
||||
} else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Local zone address %s", zs_addr);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
const char *addr = zs->GetCAddress();
|
||||
if(addr[0]) {
|
||||
zs_addr = addr;
|
||||
} else {
|
||||
zs_addr=WorldConfig::get()->WorldAddress.c_str();
|
||||
zs_addr = WorldConfig::get()->WorldAddress.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(zsi->ip, zs_addr);
|
||||
zsi->port =zs->GetCPort();
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Sending client to zone %s (%d:%d) at %s:%d",zonename,zoneID,instanceID,zsi->ip,zsi->port);
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Sending client to zone %s (%d:%d) at %s:%d",zonename,zone_id,instance_id,zsi->ip,zsi->port);
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
@@ -1245,17 +1288,17 @@ void Client::Clearance(int8 response)
|
||||
cle->SetOnline(CLE_Status_Zoning);
|
||||
}
|
||||
|
||||
void Client::ZoneUnavail() {
|
||||
void Client::TellClientZoneUnavailable() {
|
||||
auto outapp = new EQApplicationPacket(OP_ZoneUnavail, sizeof(ZoneUnavail_Struct));
|
||||
ZoneUnavail_Struct* ua = (ZoneUnavail_Struct*)outapp->pBuffer;
|
||||
const char* zonename = database.GetZoneName(zoneID);
|
||||
const char* zonename = database.GetZoneName(zone_id);
|
||||
if (zonename)
|
||||
strcpy(ua->zonename, zonename);
|
||||
QueuePacket(outapp);
|
||||
delete outapp;
|
||||
|
||||
zoneID = 0;
|
||||
pwaitingforbootup = 0;
|
||||
zone_id = 0;
|
||||
zone_waiting_for_bootup = 0;
|
||||
autobootup_timeout.Disable();
|
||||
}
|
||||
|
||||
@@ -1379,7 +1422,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
|
||||
|
||||
/* Validate the char creation struct */
|
||||
if (m_ClientVersionBit & BIT_SoFAndLater) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater) {
|
||||
if (!CheckCharCreateInfoSoF(cc)) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
|
||||
return false;
|
||||
@@ -1431,8 +1474,8 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
SetClassStartingSkills(&pp);
|
||||
SetClassLanguages(&pp);
|
||||
|
||||
pp.skills[SkillSwimming] = RuleI(Skills, SwimmingStartValue);
|
||||
pp.skills[SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue);
|
||||
pp.skills[EQEmu::skills::SkillSwimming] = RuleI(Skills, SwimmingStartValue);
|
||||
pp.skills[EQEmu::skills::SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue);
|
||||
|
||||
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
|
||||
|
||||
@@ -1440,7 +1483,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++)
|
||||
pp.spell_book[i] = 0xFFFFFFFF;
|
||||
|
||||
for(i = 0; i < MAX_PP_REF_MEMSPELL; i++)
|
||||
for(i = 0; i < MAX_PP_MEMSPELL; i++)
|
||||
pp.mem_spells[i] = 0xFFFFFFFF;
|
||||
|
||||
for(i = 0; i < BUFF_COUNT; i++)
|
||||
@@ -1450,7 +1493,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 & BIT_SoFAndLater) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Found 'SoFStartZoneID' rule setting: %i", RuleI(World, SoFStartZoneID));
|
||||
if (RuleI(World, SoFStartZoneID) > 0) {
|
||||
pp.zone_id = RuleI(World, SoFStartZoneID);
|
||||
@@ -1466,7 +1509,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 & BIT_TitaniumAndEarlier);
|
||||
bool ValidStartZone = database.GetStartZone(&pp, cc, m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier);
|
||||
|
||||
if (!ValidStartZone){
|
||||
return false;
|
||||
@@ -1478,7 +1521,25 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
pp.x = pp.y = pp.z = -1;
|
||||
}
|
||||
|
||||
/* Set Home Binds */
|
||||
/* Set Home Binds -- yep, all of them */
|
||||
pp.binds[1].zoneId = pp.zone_id;
|
||||
pp.binds[1].x = pp.x;
|
||||
pp.binds[1].y = pp.y;
|
||||
pp.binds[1].z = pp.z;
|
||||
pp.binds[1].heading = pp.heading;
|
||||
|
||||
pp.binds[2].zoneId = pp.zone_id;
|
||||
pp.binds[2].x = pp.x;
|
||||
pp.binds[2].y = pp.y;
|
||||
pp.binds[2].z = pp.z;
|
||||
pp.binds[2].heading = pp.heading;
|
||||
|
||||
pp.binds[3].zoneId = pp.zone_id;
|
||||
pp.binds[3].x = pp.x;
|
||||
pp.binds[3].y = pp.y;
|
||||
pp.binds[3].z = pp.z;
|
||||
pp.binds[3].heading = pp.heading;
|
||||
|
||||
pp.binds[4].zoneId = pp.zone_id;
|
||||
pp.binds[4].x = pp.x;
|
||||
pp.binds[4].y = pp.y;
|
||||
@@ -1788,17 +1849,22 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
|
||||
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
|
||||
{
|
||||
for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
|
||||
for (uint32 i = 0; i <= EQEmu::skills::HIGHEST_SKILL; ++i) {
|
||||
if (pp->skills[i] == 0) {
|
||||
// Skip specialized, tradeskills (fishing excluded), Alcohol Tolerance, and Bind Wound
|
||||
if (EQEmu::IsSpecializedSkill((SkillUseTypes)i) ||
|
||||
(EQEmu::IsTradeskill((SkillUseTypes)i) && i != SkillFishing) ||
|
||||
i == SkillAlcoholTolerance || i == SkillBindWound)
|
||||
if (EQEmu::skills::IsSpecializedSkill((EQEmu::skills::SkillType)i) ||
|
||||
(EQEmu::skills::IsTradeskill((EQEmu::skills::SkillType)i) && i != EQEmu::skills::SkillFishing) ||
|
||||
i == EQEmu::skills::SkillAlcoholTolerance || i == EQEmu::skills::SkillBindWound)
|
||||
continue;
|
||||
|
||||
pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
|
||||
pp->skills[i] = database.GetSkillCap(pp->class_, (EQEmu::skills::SkillType)i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (cle->GetClientVersion() < static_cast<uint8>(EQEmu::versions::ClientVersion::RoF2) && pp->class_ == BERSERKER) {
|
||||
pp->skills[EQEmu::skills::Skill1HPiercing] = pp->skills[EQEmu::skills::Skill2HPiercing];
|
||||
pp->skills[EQEmu::skills::Skill2HPiercing] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
|
||||
@@ -1820,41 +1886,41 @@ void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
|
||||
}
|
||||
case DARK_ELF:
|
||||
{
|
||||
pp->skills[SkillHide] = 50;
|
||||
pp->skills[EQEmu::skills::SkillHide] = 50;
|
||||
break;
|
||||
}
|
||||
case FROGLOK:
|
||||
{
|
||||
pp->skills[SkillSwimming] = 125;
|
||||
pp->skills[EQEmu::skills::SkillSwimming] = 125;
|
||||
break;
|
||||
}
|
||||
case GNOME:
|
||||
{
|
||||
pp->skills[SkillTinkering] = 50;
|
||||
pp->skills[EQEmu::skills::SkillTinkering] = 50;
|
||||
break;
|
||||
}
|
||||
case HALFLING:
|
||||
{
|
||||
pp->skills[SkillHide] = 50;
|
||||
pp->skills[SkillSneak] = 50;
|
||||
pp->skills[EQEmu::skills::SkillHide] = 50;
|
||||
pp->skills[EQEmu::skills::SkillSneak] = 50;
|
||||
break;
|
||||
}
|
||||
case IKSAR:
|
||||
{
|
||||
pp->skills[SkillForage] = 50;
|
||||
pp->skills[SkillSwimming] = 100;
|
||||
pp->skills[EQEmu::skills::SkillForage] = 50;
|
||||
pp->skills[EQEmu::skills::SkillSwimming] = 100;
|
||||
break;
|
||||
}
|
||||
case WOOD_ELF:
|
||||
{
|
||||
pp->skills[SkillForage] = 50;
|
||||
pp->skills[SkillHide] = 50;
|
||||
pp->skills[EQEmu::skills::SkillForage] = 50;
|
||||
pp->skills[EQEmu::skills::SkillHide] = 50;
|
||||
break;
|
||||
}
|
||||
case VAHSHIR:
|
||||
{
|
||||
pp->skills[SkillSafeFall] = 50;
|
||||
pp->skills[SkillSneak] = 50;
|
||||
pp->skills[EQEmu::skills::SkillSafeFall] = 50;
|
||||
pp->skills[EQEmu::skills::SkillSneak] = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1933,21 +1999,21 @@ void Client::SetRacialLanguages( PlayerProfile_Struct *pp )
|
||||
}
|
||||
case IKSAR:
|
||||
{
|
||||
pp->languages[LANG_COMMON_TONGUE] = 95;
|
||||
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, IksarCommonTongue);
|
||||
pp->languages[LANG_DARK_SPEECH] = 100;
|
||||
pp->languages[LANG_LIZARDMAN] = 100;
|
||||
break;
|
||||
}
|
||||
case OGRE:
|
||||
{
|
||||
pp->languages[LANG_COMMON_TONGUE] = 95;
|
||||
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, OgreCommonTongue);
|
||||
pp->languages[LANG_DARK_SPEECH] = 100;
|
||||
pp->languages[LANG_OGRE] = 100;
|
||||
break;
|
||||
}
|
||||
case TROLL:
|
||||
{
|
||||
pp->languages[LANG_COMMON_TONGUE] = 95;
|
||||
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, TrollCommonTongue);
|
||||
pp->languages[LANG_DARK_SPEECH] = 100;
|
||||
pp->languages[LANG_TROLL] = 100;
|
||||
break;
|
||||
|
||||
+10
-10
@@ -45,7 +45,7 @@ public:
|
||||
void SendMembership();
|
||||
void SendMembershipSettings();
|
||||
void EnterWorld(bool TryBootup = true);
|
||||
void ZoneUnavail();
|
||||
void TellClientZoneUnavailable();
|
||||
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true);
|
||||
void Clearance(int8 response);
|
||||
void SendGuildList();
|
||||
@@ -58,9 +58,9 @@ public:
|
||||
|
||||
inline uint32 GetIP() { return ip; }
|
||||
inline uint16 GetPort() { return port; }
|
||||
inline uint32 GetZoneID() { return zoneID; }
|
||||
inline uint32 GetInstanceID() { return instanceID; }
|
||||
inline uint32 WaitingForBootup() { return pwaitingforbootup; }
|
||||
inline uint32 GetZoneID() { return zone_id; }
|
||||
inline uint32 GetInstanceID() { return instance_id; }
|
||||
inline uint32 WaitingForBootup() { return zone_waiting_for_bootup; }
|
||||
inline const char * GetAccountName() { if (cle) { return cle->AccountName(); } return "NOCLE"; }
|
||||
inline int16 GetAdmin() { if (cle) { return cle->Admin(); } return 0; }
|
||||
inline uint32 GetAccountID() { if (cle) { return cle->AccountID(); } return 0; }
|
||||
@@ -77,14 +77,14 @@ private:
|
||||
uint16 port;
|
||||
uint32 charid;
|
||||
char char_name[64];
|
||||
uint32 zoneID;
|
||||
uint32 instanceID;
|
||||
bool pZoning;
|
||||
uint32 zone_id;
|
||||
uint32 instance_id;
|
||||
bool is_player_zoning;
|
||||
Timer autobootup_timeout;
|
||||
uint32 pwaitingforbootup;
|
||||
uint32 zone_waiting_for_bootup;
|
||||
|
||||
bool StartInTutorial;
|
||||
ClientVersion m_ClientVersion;
|
||||
EQEmu::versions::ClientVersion m_ClientVersion;
|
||||
uint32 m_ClientVersionBit;
|
||||
bool OPCharCreate(char *name, CharCreate_Struct *cc);
|
||||
|
||||
@@ -97,7 +97,7 @@ private:
|
||||
Timer CLE_keepalive_timer;
|
||||
Timer connect;
|
||||
bool firstlogin;
|
||||
bool seencharsel;
|
||||
bool seen_character_select;
|
||||
bool realfirstlogin;
|
||||
|
||||
bool HandlePacket(const EQApplicationPacket *app);
|
||||
|
||||
@@ -277,10 +277,10 @@ bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) {
|
||||
strn0cpy(paccountname, plsname, sizeof(paccountname));
|
||||
padmin = tmpStatus;
|
||||
}
|
||||
char lsworldadmin[15] = "0";
|
||||
database.GetVariable("honorlsworldadmin", lsworldadmin, sizeof(lsworldadmin));
|
||||
if (atoi(lsworldadmin) == 1 && pworldadmin != 0 && (padmin < pworldadmin || padmin == 0))
|
||||
padmin = pworldadmin;
|
||||
std::string lsworldadmin;
|
||||
if (database.GetVariable("honorlsworldadmin", lsworldadmin))
|
||||
if (atoi(lsworldadmin.c_str()) == 1 && pworldadmin != 0 && (padmin < pworldadmin || padmin == 0))
|
||||
padmin = pworldadmin;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2005 EQEMu Development Team (http://eqemulator.net)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -15,6 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "clientlist.h"
|
||||
#include "zoneserver.h"
|
||||
@@ -748,7 +749,7 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S
|
||||
//zoneserver_list.SendPacket(pack2); // NO NO NO WHY WOULD YOU SEND IT TO EVERY ZONE SERVER?!?
|
||||
SendPacket(to,pack2);
|
||||
safe_delete(pack2);
|
||||
safe_delete(output);
|
||||
safe_delete_array(output);
|
||||
}
|
||||
catch(...){
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Unknown error in world's SendWhoAll (probably mem error), ignoring...");
|
||||
@@ -1064,7 +1065,7 @@ void ClientList::ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct*
|
||||
|
||||
if (cle->Anon() == 2) { // Roleplay
|
||||
if (admin >= 100 && admin >= cle->Admin())
|
||||
sprintf(line, " %s[RolePlay %i %s] %s (%s)%s zone: %s%s%s", tmpgm, cle->level(), GetEQClassName(cle->class_(),cle->level()), cle->name(), GetRaceName(cle->race()), tmpguild, tmpZone, LFG, accinfo);
|
||||
sprintf(line, " %s[RolePlay %i %s] %s (%s)%s zone: %s%s%s", tmpgm, cle->level(), GetClassIDName(cle->class_(),cle->level()), cle->name(), GetRaceIDName(cle->race()), tmpguild, tmpZone, LFG, accinfo);
|
||||
else if (cle->Admin() >= 80 && admin < 80 && cle->GetGM()) {
|
||||
iterator.Advance();
|
||||
continue;
|
||||
@@ -1074,7 +1075,7 @@ void ClientList::ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct*
|
||||
}
|
||||
else if (cle->Anon() == 1) { // Anon
|
||||
if (admin >= 100 && admin >= cle->Admin())
|
||||
sprintf(line, " %s[ANON %i %s] %s (%s)%s zone: %s%s%s", tmpgm, cle->level(), GetEQClassName(cle->class_(),cle->level()), cle->name(), GetRaceName(cle->race()), tmpguild, tmpZone, LFG, accinfo);
|
||||
sprintf(line, " %s[ANON %i %s] %s (%s)%s zone: %s%s%s", tmpgm, cle->level(), GetClassIDName(cle->class_(),cle->level()), cle->name(), GetRaceIDName(cle->race()), tmpguild, tmpZone, LFG, accinfo);
|
||||
else if (cle->Admin() >= 80 && cle->GetGM()) {
|
||||
iterator.Advance();
|
||||
continue;
|
||||
@@ -1083,7 +1084,7 @@ void ClientList::ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct*
|
||||
sprintf(line, " %s[ANONYMOUS] %s%s%s", tmpgm, cle->name(), LFG, accinfo);
|
||||
}
|
||||
else
|
||||
sprintf(line, " %s[%i %s] %s (%s)%s zone: %s%s%s", tmpgm, cle->level(), GetEQClassName(cle->class_(),cle->level()), cle->name(), GetRaceName(cle->race()), tmpguild, tmpZone, LFG, accinfo);
|
||||
sprintf(line, " %s[%i %s] %s (%s)%s zone: %s%s%s", tmpgm, cle->level(), GetClassIDName(cle->class_(),cle->level()), cle->name(), GetRaceIDName(cle->race()), tmpguild, tmpZone, LFG, accinfo);
|
||||
|
||||
AppendAnyLenString(&output, &outsize, &outlen, line);
|
||||
if (outlen >= 3584) {
|
||||
@@ -1183,7 +1184,7 @@ void ClientList::ZoneBootup(ZoneServer* zs) {
|
||||
iterator.GetData()->EnterWorld(false);
|
||||
}
|
||||
else if (iterator.GetData()->WaitingForBootup() == zs->GetID()) {
|
||||
iterator.GetData()->ZoneUnavail();
|
||||
iterator.GetData()->TellClientZoneUnavailable();
|
||||
}
|
||||
}
|
||||
iterator.Advance();
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -193,9 +193,9 @@ std::map<std::string,std::string> EQW::GetPlayerDetails(Const_char *char_name) {
|
||||
res["location_id"] = itoa(cle->zone());
|
||||
res["ip"] = long2ip(cle->GetIP());
|
||||
res["level"] = itoa(cle->level());
|
||||
res["race"] = GetRaceName(cle->race());
|
||||
res["race"] = GetRaceIDName(cle->race());
|
||||
res["race_id"] = itoa(cle->race());
|
||||
res["class"] = GetEQClassName(cle->class_());
|
||||
res["class"] = GetClassIDName(cle->class_());
|
||||
res["class_id"] = itoa(cle->class_());
|
||||
res["guild_id"] = itoa(cle->GuildID());
|
||||
res["guild"] = guild_mgr.GetGuildName(cle->GuildID());
|
||||
|
||||
@@ -227,7 +227,7 @@ bool EQWParser::dosub(const char * subname, const std::vector<std::string> &args
|
||||
ENTER; // everything created after here
|
||||
SAVETMPS; // ...is a temporary variable
|
||||
PUSHMARK(SP); // remember the stack pointer
|
||||
if(args.size() > 0)
|
||||
if(!args.empty())
|
||||
{
|
||||
for (auto i = args.begin(); i != args.end(); ++i) { /* push the arguments onto the perl stack */
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), i->length())));
|
||||
|
||||
+9
-42
@@ -60,7 +60,7 @@ bool LauncherLink::Process() {
|
||||
end = m_states.end();
|
||||
for(; cur != end; ++cur) {
|
||||
if(!cur->second.up) {
|
||||
StartZone(cur->first.c_str());
|
||||
StartZone(cur->first.c_str(), cur->second.port);
|
||||
}
|
||||
}
|
||||
m_bootTimer.Disable();
|
||||
@@ -184,14 +184,6 @@ bool LauncherLink::Process() {
|
||||
|
||||
bool LauncherLink::ContainsZone(const char *short_name) const {
|
||||
return(m_states.find(short_name) != m_states.end());
|
||||
|
||||
/*
|
||||
* std::map<std::string, bool>::const_iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(
|
||||
}*/
|
||||
}
|
||||
|
||||
void LauncherLink::BootZone(const char *short_name, uint16 port) {
|
||||
@@ -202,15 +194,20 @@ void LauncherLink::BootZone(const char *short_name, uint16 port) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "%s: Loaded zone '%s' on port %d", m_name.c_str(), short_name, zs.port);
|
||||
m_states[short_name] = zs;
|
||||
|
||||
StartZone(short_name);
|
||||
StartZone(short_name, port);
|
||||
}
|
||||
|
||||
void LauncherLink::StartZone(const char *short_name) {
|
||||
StartZone(short_name, 0);
|
||||
}
|
||||
|
||||
void LauncherLink::StartZone(const char *short_name, uint16 port) {
|
||||
auto pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Start;
|
||||
s->port = port;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
@@ -222,6 +219,7 @@ void LauncherLink::RestartZone(const char *short_name) {
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Restart;
|
||||
s->port = 0;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
@@ -233,6 +231,7 @@ void LauncherLink::StopZone(const char *short_name) {
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Stop;
|
||||
s->port = 0;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
@@ -332,35 +331,3 @@ void LauncherLink::Shutdown() {
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
void Shutdown();
|
||||
void BootZone(const char *short_name, uint16 port);
|
||||
void StartZone(const char *short_name);
|
||||
void StartZone(const char *short_name, uint16 port);
|
||||
void RestartZone(const char *short_name);
|
||||
void StopZone(const char *short_name);
|
||||
void BootDynamics(uint8 new_total);
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <process.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
@@ -145,7 +145,7 @@ bool LoginServer::Process() {
|
||||
break;
|
||||
}
|
||||
case ServerOP_LSClientAuth: {
|
||||
ServerLSClientAuth* slsca = (ServerLSClientAuth*) pack->pBuffer;
|
||||
ClientAuth_Struct* slsca = (ClientAuth_Struct*) pack->pBuffer;
|
||||
|
||||
if (RuleI(World, AccountSessionLimit) >= 0) {
|
||||
// Enforce the limit on the number of characters on the same account that can be
|
||||
@@ -212,8 +212,8 @@ bool LoginServer::InitLoginServer() {
|
||||
}
|
||||
|
||||
bool LoginServer::Connect() {
|
||||
char tmp[25];
|
||||
if(database.GetVariable("loginType",tmp,sizeof(tmp)) && strcasecmp(tmp,"MinILogin") == 0){
|
||||
std::string tmp;
|
||||
if(database.GetVariable("loginType", tmp) && strcasecmp(tmp.c_str(), "MinILogin") == 0) {
|
||||
minilogin = true;
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Setting World to MiniLogin Server type");
|
||||
}
|
||||
|
||||
+78
-36
@@ -107,7 +107,7 @@ volatile bool RunLoops = true;
|
||||
uint32 numclients = 0;
|
||||
uint32 numzones = 0;
|
||||
bool holdzones = false;
|
||||
|
||||
const WorldConfig *Config;
|
||||
EQEmuLogSys Log;
|
||||
|
||||
extern ConsoleList console_list;
|
||||
@@ -117,14 +117,18 @@ void CatchSignal(int sig_num);
|
||||
int main(int argc, char** argv) {
|
||||
RegisterExecutablePlatform(ExePlatformWorld);
|
||||
Log.LoadLogSettingsDefaults();
|
||||
|
||||
|
||||
|
||||
set_exception_handler();
|
||||
register_remote_call_handlers();
|
||||
|
||||
/* Database Version Check */
|
||||
uint32 Database_Version = CURRENT_BINARY_DATABASE_VERSION;
|
||||
uint32 Bots_Database_Version = CURRENT_BINARY_BOTS_DATABASE_VERSION;
|
||||
if (argc >= 2) {
|
||||
if (strcasecmp(argv[1], "db_version") == 0) {
|
||||
std::cout << "Binary Database Version: " << Database_Version << std::endl;
|
||||
std::cout << "Binary Database Version: " << Database_Version << " : " << Bots_Database_Version << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -135,7 +139,7 @@ int main(int argc, char** argv) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading server configuration failed.");
|
||||
return 1;
|
||||
}
|
||||
const WorldConfig *Config=WorldConfig::get();
|
||||
Config=WorldConfig::get();
|
||||
|
||||
Log.Out(Logs::General, Logs::World_Server, "CURRENT_VERSION: %s", CURRENT_VERSION);
|
||||
|
||||
@@ -193,7 +197,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
bool ignore_db = false;
|
||||
if (argc >= 2) {
|
||||
char tmp[2];
|
||||
std::string tmp;
|
||||
if (strcasecmp(argv[1], "help") == 0 || strcasecmp(argv[1], "?") == 0 || strcasecmp(argv[1], "/?") == 0 || strcasecmp(argv[1], "-?") == 0 || strcasecmp(argv[1], "-h") == 0 || strcasecmp(argv[1], "-help") == 0) {
|
||||
std::cout << "Worldserver command line commands:" << std::endl;
|
||||
std::cout << "adduser username password flag - adds a user account" << std::endl;
|
||||
@@ -206,8 +210,8 @@ int main(int argc, char** argv) {
|
||||
std::cout << "Reboot Zones mode ON" << std::endl;
|
||||
holdzones = true;
|
||||
}
|
||||
else if (database.GetVariable("disablecommandline", tmp, 2)) {
|
||||
if (strlen(tmp) == 1) {
|
||||
else if (database.GetVariable("disablecommandline", tmp)) {
|
||||
if (tmp.length() == 1) {
|
||||
if (tmp[0] == '1') {
|
||||
std::cerr << "Command line disabled in database... exiting" << std::endl;
|
||||
return 1;
|
||||
@@ -298,6 +302,14 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading variables..");
|
||||
database.LoadVariables();
|
||||
|
||||
std::string hotfix_name;
|
||||
if(database.GetVariable("hotfix_name", hotfix_name)) {
|
||||
if (!hotfix_name.empty()) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Current hotfix in use: '%s'", hotfix_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading zones..");
|
||||
database.LoadZoneNames();
|
||||
Log.Out(Logs::General, Logs::World_Server, "Clearing groups..");
|
||||
@@ -306,27 +318,29 @@ int main(int argc, char** argv) {
|
||||
database.ClearRaid();
|
||||
database.ClearRaidDetails();
|
||||
database.ClearRaidLeader();
|
||||
Log.Out(Logs::General, Logs::World_Server, "Clearing inventory snapshots..");
|
||||
database.ClearInvSnapshots();
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading items..");
|
||||
if (!database.LoadItems())
|
||||
if(!database.LoadItems(hotfix_name))
|
||||
Log.Out(Logs::General, Logs::World_Server, "Error: Could not load item data. But ignoring");
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading skill caps..");
|
||||
if (!database.LoadSkillCaps())
|
||||
if(!database.LoadSkillCaps(std::string(hotfix_name)))
|
||||
Log.Out(Logs::General, Logs::World_Server, "Error: Could not load skill cap data. But ignoring");
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading guilds..");
|
||||
guild_mgr.LoadGuilds();
|
||||
//rules:
|
||||
{
|
||||
char tmp[64];
|
||||
if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading rule set '%s'", tmp);
|
||||
if(!RuleManager::Instance()->LoadRules(&database, tmp)) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Failed to load ruleset '%s', falling back to defaults.", tmp);
|
||||
std::string tmp;
|
||||
if (database.GetVariable("RuleSet", tmp)) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading rule set '%s'", tmp.c_str());
|
||||
if(!RuleManager::Instance()->LoadRules(&database, tmp.c_str())) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Failed to load ruleset '%s', falling back to defaults.", tmp.c_str());
|
||||
}
|
||||
} else {
|
||||
if(!RuleManager::Instance()->LoadRules(&database, "default")) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "No rule set configured, using default rules");
|
||||
} else {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loaded default rule set 'default'", tmp);
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loaded default rule set 'default'", tmp.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,15 +349,19 @@ int main(int argc, char** argv) {
|
||||
database.ClearMerchantTemp();
|
||||
}
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading EQ time of day..");
|
||||
if (!zoneserver_list.worldclock.loadFile(Config->EQTimeFile.c_str()))
|
||||
Log.Out(Logs::General, Logs::World_Server, "Unable to load %s", Config->EQTimeFile.c_str());
|
||||
TimeOfDay_Struct eqTime;
|
||||
time_t realtime;
|
||||
eqTime = database.LoadTime(realtime);
|
||||
zoneserver_list.worldclock.SetCurrentEQTimeOfDay(eqTime, realtime);
|
||||
Timer EQTimeTimer(600000);
|
||||
EQTimeTimer.Start(600000);
|
||||
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading launcher list..");
|
||||
launcher_list.LoadList();
|
||||
|
||||
char tmp[20];
|
||||
tmp[0] = '\0';
|
||||
database.GetVariable("holdzones",tmp, 20);
|
||||
if ((strcasecmp(tmp, "1") == 0)) {
|
||||
std::string tmp;
|
||||
database.GetVariable("holdzones",tmp);
|
||||
if (tmp.length() == 1 && tmp[0] == '1') {
|
||||
holdzones = true;
|
||||
}
|
||||
Log.Out(Logs::General, Logs::World_Server, "Reboot zone modes %s",holdzones ? "ON" : "OFF");
|
||||
@@ -412,7 +430,7 @@ int main(int argc, char** argv) {
|
||||
//structures and opcodes for that patch.
|
||||
struct in_addr in;
|
||||
in.s_addr = eqs->GetRemoteIP();
|
||||
Log.Out(Logs::General, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in),ntohs(eqs->GetRemotePort()));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New connection from IP %s:%d", inet_ntoa(in),ntohs(eqs->GetRemotePort()));
|
||||
stream_identifier.AddStream(eqs); //takes the stream
|
||||
}
|
||||
|
||||
@@ -427,9 +445,9 @@ int main(int argc, char** argv) {
|
||||
struct in_addr in;
|
||||
in.s_addr = eqsi->GetRemoteIP();
|
||||
if (RuleB(World, UseBannedIPsTable)){ //Lieka: Check to see if we have the responsibility for blocking IPs.
|
||||
Log.Out(Logs::General, Logs::World_Server, "Checking inbound connection %s against BannedIPs table", inet_ntoa(in));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Checking inbound connection %s against BannedIPs table", inet_ntoa(in));
|
||||
if (!database.CheckBannedIPs(inet_ntoa(in))){ //Lieka: Check inbound IP against banned IP table.
|
||||
Log.Out(Logs::General, Logs::World_Server, "Connection %s PASSED banned IPs check. Processing connection.", inet_ntoa(in));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Connection %s PASSED banned IPs check. Processing connection.", inet_ntoa(in));
|
||||
auto client = new Client(eqsi);
|
||||
// @merth: client->zoneattempt=0;
|
||||
client_list.Add(client);
|
||||
@@ -439,7 +457,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
if (!RuleB(World, UseBannedIPsTable)){
|
||||
Log.Out(Logs::General, Logs::World_Server, "New connection from %s:%d, processing connection", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d, processing connection", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
|
||||
auto client = new Client(eqsi);
|
||||
// @merth: client->zoneattempt=0;
|
||||
client_list.Add(client);
|
||||
@@ -451,7 +469,26 @@ int main(int argc, char** argv) {
|
||||
while ((tcpc = tcps.NewQueuePop())) {
|
||||
struct in_addr in;
|
||||
in.s_addr = tcpc->GetrIP();
|
||||
Log.Out(Logs::General, Logs::World_Server, "New TCP connection from %s:%d", inet_ntoa(in),tcpc->GetrPort());
|
||||
|
||||
/* World - Tell what is being connected */
|
||||
if (tcpc->GetMode() == EmuTCPConnection::modePacket) {
|
||||
if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "New Zone Server from %s:%d", inet_ntoa(in), tcpc->GetrPort());
|
||||
}
|
||||
else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "New Launcher from %s:%d", inet_ntoa(in), tcpc->GetrPort());
|
||||
}
|
||||
else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "New UCS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort());
|
||||
}
|
||||
else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeQueryServ) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "New QS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort());
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Unsupported packet mode from %s:%d", inet_ntoa(in), tcpc->GetrPort());
|
||||
}
|
||||
}
|
||||
|
||||
console_list.Add(new Console(tcpc));
|
||||
}
|
||||
|
||||
@@ -460,6 +497,16 @@ int main(int argc, char** argv) {
|
||||
database.PurgeExpiredInstances();
|
||||
}
|
||||
|
||||
if (EQTimeTimer.Check())
|
||||
{
|
||||
TimeOfDay_Struct tod;
|
||||
zoneserver_list.worldclock.GetCurrentEQTimeOfDay(time(0), &tod);
|
||||
if (!database.SaveTime(tod.minute, tod.hour, tod.day, tod.month, tod.year))
|
||||
Log.Out(Logs::General, Logs::World_Server, "Failed to save eqtime.");
|
||||
else
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "EQTime successfully saved.");
|
||||
}
|
||||
|
||||
//check for timeouts in other threads
|
||||
timeout_manager.CheckTimeouts();
|
||||
loginserverlist.Process();
|
||||
@@ -478,19 +525,16 @@ int main(int argc, char** argv) {
|
||||
if (InterserverTimer.Check()) {
|
||||
InterserverTimer.Start();
|
||||
database.ping();
|
||||
// AsyncLoadVariables(dbasync, &database);
|
||||
ReconnectCounter++;
|
||||
if (ReconnectCounter >= 12) { // only create thread to reconnect every 10 minutes. previously we were creating a new thread every 10 seconds
|
||||
ReconnectCounter = 0;
|
||||
if (loginserverlist.AllConnected() == false) {
|
||||
|
||||
if (loginserverlist.AllConnected() == false) {
|
||||
#ifdef _WINDOWS
|
||||
_beginthread(AutoInitLoginServer, 0, nullptr);
|
||||
_beginthread(AutoInitLoginServer, 0, nullptr);
|
||||
#else
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, nullptr, &AutoInitLoginServer, nullptr);
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, nullptr, &AutoInitLoginServer, nullptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (numclients == 0) {
|
||||
Sleep(50);
|
||||
@@ -516,8 +560,6 @@ int main(int argc, char** argv) {
|
||||
|
||||
void CatchSignal(int sig_num) {
|
||||
Log.Out(Logs::General, Logs::World_Server,"Caught signal %d",sig_num);
|
||||
if(zoneserver_list.worldclock.saveFile(WorldConfig::get()->EQTimeFile.c_str())==false)
|
||||
Log.Out(Logs::General, Logs::World_Server,"Failed to save time file.");
|
||||
RunLoops = false;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -26,8 +26,8 @@
|
||||
#else
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
+50
-23
@@ -36,15 +36,15 @@ extern std::vector<RaceClassCombos> character_create_race_class_combos;
|
||||
void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **outApp, uint32 clientVersionBit)
|
||||
{
|
||||
/* Set Character Creation Limit */
|
||||
ClientVersion client_version = ClientVersionFromBit(clientVersionBit);
|
||||
size_t character_limit = EQLimits::CharacterCreationLimit(client_version);
|
||||
EQEmu::versions::ClientVersion client_version = EQEmu::versions::ConvertClientVersionBitToClientVersion(clientVersionBit);
|
||||
size_t character_limit = EQEmu::constants::Lookup(client_version)->CharacterCreationLimit;
|
||||
|
||||
// Validate against absolute server max
|
||||
if (character_limit > EmuConstants::CHARACTER_CREATION_LIMIT)
|
||||
character_limit = EmuConstants::CHARACTER_CREATION_LIMIT;
|
||||
if (character_limit > EQEmu::constants::CharacterCreationMax)
|
||||
character_limit = EQEmu::constants::CharacterCreationMax;
|
||||
|
||||
// Force Titanium clients to use '8'
|
||||
if (client_version == ClientVersion::Titanium)
|
||||
if (client_version == EQEmu::versions::ClientVersion::Titanium)
|
||||
character_limit = 8;
|
||||
|
||||
/* Get Character Info */
|
||||
@@ -105,6 +105,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
memset(&pp, 0, sizeof(PlayerProfile_Struct));
|
||||
|
||||
/* Fill CharacterSelectEntry_Struct */
|
||||
memset(cse->Name, 0, sizeof(cse->Name));
|
||||
strcpy(cse->Name, row[1]);
|
||||
cse->Class = (uint8)atoi(row[4]);
|
||||
cse->Race = (uint32)atoi(row[3]);
|
||||
@@ -116,13 +117,13 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
cse->Gender = (uint8)atoi(row[2]);
|
||||
cse->Face = (uint8)atoi(row[15]);
|
||||
|
||||
for (uint32 matslot = 0; matslot < _MaterialCount; matslot++) { // Processed below
|
||||
for (uint32 matslot = 0; matslot < EQEmu::textures::TextureCount; matslot++) { // Processed below
|
||||
cse->Equip[matslot].Material = 0;
|
||||
cse->Equip[matslot].Unknown1 = 0;
|
||||
cse->Equip[matslot].EliteMaterial = 0;
|
||||
cse->Equip[matslot].HeroForgeModel = 0;
|
||||
cse->Equip[matslot].Material2 = 0;
|
||||
cse->Equip[matslot].Color.Color = 0;
|
||||
cse->Equip[matslot].Color = 0;
|
||||
}
|
||||
|
||||
cse->Unknown15 = 0xFF;
|
||||
@@ -158,10 +159,22 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
}
|
||||
|
||||
/* Set Bind Point Data for any character that may possibly be missing it for any reason */
|
||||
cquery = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %i LIMIT 2", character_id);
|
||||
cquery = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `slot` FROM `character_bind` WHERE `id` = %i LIMIT 5", character_id);
|
||||
auto results_bind = database.QueryDatabase(cquery);
|
||||
auto bind_count = results_bind.RowCount();
|
||||
for (auto row_b = results_bind.begin(); row_b != results_bind.end(); ++row_b) {
|
||||
if (row_b[6] && atoi(row_b[6]) == 1){ has_home = 1; }
|
||||
if (row_b[6] && atoi(row_b[6]) == 4) {
|
||||
has_home = 1;
|
||||
// If our bind count is less than 5, we need to actually make use of this data so lets parse it
|
||||
if (bind_count < 5) {
|
||||
pp.binds[4].zoneId = atoi(row_b[0]);
|
||||
pp.binds[4].instance_id = atoi(row_b[1]);
|
||||
pp.binds[4].x = atof(row_b[2]);
|
||||
pp.binds[4].y = atof(row_b[3]);
|
||||
pp.binds[4].z = atof(row_b[4]);
|
||||
pp.binds[4].heading = atof(row_b[5]);
|
||||
}
|
||||
}
|
||||
if (row_b[6] && atoi(row_b[6]) == 0){ has_bind = 1; }
|
||||
}
|
||||
|
||||
@@ -188,19 +201,33 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
pp.binds[0] = pp.binds[4];
|
||||
/* If no home bind set, set it */
|
||||
if (has_home == 0) {
|
||||
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
|
||||
character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 1);
|
||||
character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 4);
|
||||
auto results_bset = QueryDatabase(query);
|
||||
}
|
||||
/* If no regular bind set, set it */
|
||||
if (has_bind == 0) {
|
||||
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
|
||||
character_id, pp.binds[0].zoneId, 0, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z, pp.binds[0].heading, 0);
|
||||
auto results_bset = QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
/* If our bind count is less than 5, then we have null data that needs to be filled in. */
|
||||
if (bind_count < 5) {
|
||||
// we know that home and main bind must be valid here, so we don't check those
|
||||
// we also use home to fill in the null data like live does.
|
||||
for (int i = 1; i < 4; i++) {
|
||||
if (pp.binds[i].zoneId != 0) // we assume 0 is the only invalid one ...
|
||||
continue;
|
||||
|
||||
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
|
||||
character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, i);
|
||||
auto results_bset = QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
/* Bind End */
|
||||
|
||||
/* Load Character Material Data for Char Select */
|
||||
@@ -208,21 +235,21 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
auto results_b = database.QueryDatabase(cquery); uint8 slot = 0;
|
||||
for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) {
|
||||
slot = atoi(row_b[0]);
|
||||
pp.item_tint[slot].RGB.Red = atoi(row_b[1]);
|
||||
pp.item_tint[slot].RGB.Green = atoi(row_b[2]);
|
||||
pp.item_tint[slot].RGB.Blue = atoi(row_b[3]);
|
||||
pp.item_tint[slot].RGB.UseTint = atoi(row_b[4]);
|
||||
pp.item_tint.Slot[slot].Red = atoi(row_b[1]);
|
||||
pp.item_tint.Slot[slot].Green = atoi(row_b[2]);
|
||||
pp.item_tint.Slot[slot].Blue = atoi(row_b[3]);
|
||||
pp.item_tint.Slot[slot].UseTint = atoi(row_b[4]);
|
||||
}
|
||||
/* Character Material Data End */
|
||||
|
||||
/* Load Inventory */
|
||||
// If we ensure that the material data is updated appropriately, we can do away with inventory loads
|
||||
if (GetInventory(accountID, cse->Name, &inv)) {
|
||||
const Item_Struct* item = nullptr;
|
||||
const EQEmu::ItemBase* item = nullptr;
|
||||
const ItemInst* inst = nullptr;
|
||||
int16 invslot = 0;
|
||||
|
||||
for (uint32 matslot = 0; matslot < _MaterialCount; matslot++) {
|
||||
for (uint32 matslot = 0; matslot < EQEmu::textures::TextureCount; matslot++) {
|
||||
invslot = Inventory::CalcSlotFromMaterial(matslot);
|
||||
if (invslot == INVALID_INDEX) { continue; }
|
||||
inst = inv.GetItem(invslot);
|
||||
@@ -243,7 +270,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
cse->Equip[matslot].Material = idfile;
|
||||
}
|
||||
}
|
||||
if (matslot == MaterialPrimary) {
|
||||
if (matslot == EQEmu::textures::TexturePrimary) {
|
||||
cse->PrimaryIDFile = idfile;
|
||||
}
|
||||
else {
|
||||
@@ -252,8 +279,8 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
}
|
||||
else {
|
||||
uint32 color = 0;
|
||||
if (pp.item_tint[matslot].RGB.UseTint) {
|
||||
color = pp.item_tint[matslot].Color;
|
||||
if (pp.item_tint.Slot[matslot].UseTint) {
|
||||
color = pp.item_tint.Slot[matslot].Color;
|
||||
}
|
||||
else {
|
||||
color = inst->GetColor();
|
||||
@@ -263,7 +290,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
cse->Equip[matslot].Material = item->Material;
|
||||
cse->Equip[matslot].EliteMaterial = item->EliteMaterial;
|
||||
cse->Equip[matslot].HeroForgeModel = inst->GetOrnamentHeroModel(matslot);
|
||||
cse->Equip[matslot].Color.Color = color;
|
||||
cse->Equip[matslot].Color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,7 +311,7 @@ int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum)
|
||||
bindnum = 0;
|
||||
}
|
||||
|
||||
std::string query = StringFormat("SELECT zone_id, instance_id, x, y, z FROM character_bind WHERE id = %u AND is_home = %u LIMIT 1", CharID, bindnum == 4 ? 1 : 0);
|
||||
std::string query = StringFormat("SELECT zone_id, instance_id, x, y, z FROM character_bind WHERE id = %u AND slot = %u LIMIT 1", CharID, bindnum);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success() || results.RowCount() == 0) {
|
||||
return 0;
|
||||
|
||||
+77
-43
@@ -88,7 +88,7 @@ void ZSList::Process() {
|
||||
Process();
|
||||
CatchSignal(2);
|
||||
}
|
||||
if(reminder && reminder->Check()){
|
||||
if(reminder && reminder->Check() && shutdowntimer){
|
||||
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i minutes...", ((shutdowntimer->GetRemainingTime()/1000) / 60));
|
||||
}
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
@@ -283,57 +283,84 @@ void ZSList::ListLockedZones(const char* to, WorldTCPConnection* connection) {
|
||||
}
|
||||
|
||||
void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* connection) {
|
||||
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
struct in_addr in;
|
||||
|
||||
iterator.Reset();
|
||||
char locked[4];
|
||||
if (WorldConfig::get()->Locked == true)
|
||||
if (WorldConfig::get()->Locked == true){
|
||||
strcpy(locked, "Yes");
|
||||
else
|
||||
}
|
||||
else {
|
||||
strcpy(locked, "No");
|
||||
}
|
||||
|
||||
char* output = 0;
|
||||
uint32 outsize = 0, outlen = 0;
|
||||
if (connection->IsConsole())
|
||||
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s\r\n", locked);
|
||||
else
|
||||
}
|
||||
else{
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s^", locked);
|
||||
if (connection->IsConsole())
|
||||
}
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:\r\n");
|
||||
else
|
||||
}
|
||||
else{
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:^");
|
||||
// connection->SendEmoteMessage(to, 0, 0, 0, "World Locked: %s", locked);
|
||||
// connection->SendEmoteMessage(to, 0, 0, 0, "Zoneservers online:");
|
||||
int v=0, w=0, x=0, y=0, z=0;
|
||||
char tmpStatic[2] = { 0, 0 }, tmpZone[64];
|
||||
memset(tmpZone, 0, sizeof(tmpZone));
|
||||
ZoneServer* zs = 0;
|
||||
while(iterator.MoreElements()) {
|
||||
zs = iterator.GetData();
|
||||
in.s_addr = zs->GetIP();
|
||||
}
|
||||
|
||||
if(zs->IsStaticZone())
|
||||
int v = 0, w = 0, x = 0, y = 0, z = 0;
|
||||
char is_static_string[2] = { 0, 0 }, zone_data_string[64];
|
||||
memset(zone_data_string, 0, sizeof(zone_data_string));
|
||||
|
||||
ZoneServer* zone_server_data = 0;
|
||||
|
||||
while (iterator.MoreElements()) {
|
||||
zone_server_data = iterator.GetData();
|
||||
in.s_addr = zone_server_data->GetIP();
|
||||
|
||||
if (zone_server_data->IsStaticZone()){
|
||||
z++;
|
||||
else if (zs->GetZoneID() != 0)
|
||||
}
|
||||
else if (zone_server_data->GetZoneID() != 0){
|
||||
w++;
|
||||
else if(zs->GetZoneID() == 0 && !zs->IsBootingUp())
|
||||
}
|
||||
else if (zone_server_data->GetZoneID() == 0 && !zone_server_data->IsBootingUp()){
|
||||
v++;
|
||||
}
|
||||
|
||||
if (zs->IsStaticZone())
|
||||
tmpStatic[0] = 'S';
|
||||
if (zone_server_data->IsStaticZone())
|
||||
is_static_string[0] = 'S';
|
||||
else
|
||||
tmpStatic[0] = ' ';
|
||||
is_static_string[0] = 'D';
|
||||
|
||||
if (admin >= 150) {
|
||||
if (zs->GetZoneID())
|
||||
snprintf(tmpZone, sizeof(tmpZone), "%s (%i)", zs->GetZoneName(), zs->GetZoneID());
|
||||
else if (zs->IsBootingUp())
|
||||
strcpy(tmpZone, "...");
|
||||
else
|
||||
tmpZone[0] = 0;
|
||||
if (zone_server_data->GetZoneID()){
|
||||
snprintf(zone_data_string, sizeof(zone_data_string), "%s (%i)", zone_server_data->GetZoneName(), zone_server_data->GetZoneID());
|
||||
}
|
||||
else if (zone_server_data->IsBootingUp()){
|
||||
strcpy(zone_data_string, "...");
|
||||
}
|
||||
else{
|
||||
zone_data_string[0] = 0;
|
||||
}
|
||||
|
||||
AppendAnyLenString(&output, &outsize, &outlen, " #%-3i %s %15s:%-5i %2i %s:%i %s", zs->GetID(), tmpStatic, inet_ntoa(in), zs->GetPort(), zs->NumPlayers(), zs->GetCAddress(), zs->GetCPort(), tmpZone);
|
||||
AppendAnyLenString(&output, &outsize, &outlen,
|
||||
"#%-3i :: %s :: %15s:%-5i :: %2i :: %s:%i :: %s :: (%u)",
|
||||
zone_server_data->GetID(),
|
||||
is_static_string,
|
||||
inet_ntoa(in),
|
||||
zone_server_data->GetPort(),
|
||||
zone_server_data->NumPlayers(),
|
||||
zone_server_data->GetCAddress(),
|
||||
zone_server_data->GetCPort(),
|
||||
zone_data_string,
|
||||
zone_server_data->GetZoneOSProcessID()
|
||||
);
|
||||
|
||||
if (outlen >= 3584) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
safe_delete(output);
|
||||
@@ -348,12 +375,12 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con
|
||||
}
|
||||
x++;
|
||||
}
|
||||
else if (zs->GetZoneID() != 0) {
|
||||
if (zs->GetZoneID())
|
||||
strcpy(tmpZone, zs->GetZoneName());
|
||||
else if (zone_server_data->GetZoneID() != 0) {
|
||||
if (zone_server_data->GetZoneID())
|
||||
strcpy(zone_data_string, zone_server_data->GetZoneName());
|
||||
else
|
||||
tmpZone[0] = 0;
|
||||
AppendAnyLenString(&output, &outsize, &outlen, " #%i %s %s", zs->GetID(), tmpStatic, tmpZone);
|
||||
zone_data_string[0] = 0;
|
||||
AppendAnyLenString(&output, &outsize, &outlen, " #%i %s %s", zone_server_data->GetID(), is_static_string, zone_data_string);
|
||||
if (outlen >= 3584) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
safe_delete(output);
|
||||
@@ -361,25 +388,32 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con
|
||||
outlen = 0;
|
||||
}
|
||||
else {
|
||||
if (connection->IsConsole())
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "\r\n");
|
||||
else
|
||||
}
|
||||
else{
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "^");
|
||||
}
|
||||
}
|
||||
x++;
|
||||
}
|
||||
y++;
|
||||
iterator.Advance();
|
||||
}
|
||||
if (connection->IsConsole())
|
||||
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.\r\n", x, y);
|
||||
else
|
||||
}
|
||||
else {
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.^", x, y);
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v);
|
||||
// connection->SendEmoteMessage(to, 0, 0, "%i servers listed. %i servers online.", x, y);
|
||||
// connection->SendEmoteMessage(to,0,0,"%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v);
|
||||
if (output)
|
||||
}
|
||||
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i zones are static zones, %i zones are booted zones, %i zones available.", z, w, v);
|
||||
|
||||
if (output){
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
}
|
||||
|
||||
safe_delete(output);
|
||||
}
|
||||
|
||||
@@ -564,7 +598,7 @@ void ZSList::RebootZone(const char* ip1,uint16 port,const char* ip2, uint32 skip
|
||||
iterator.Advance();
|
||||
}
|
||||
if (y == 0) {
|
||||
safe_delete(tmp);
|
||||
safe_delete_array(tmp);
|
||||
return;
|
||||
}
|
||||
uint32 z = emu_random.Int(0, y-1);
|
||||
|
||||
+100
-53
@@ -51,19 +51,24 @@ extern WebInterfaceConnection WILink;
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
ZoneServer::ZoneServer(EmuTCPConnection* itcpc)
|
||||
: WorldTCPConnection(), tcpc(itcpc), ls_zboot(5000) {
|
||||
ID = zoneserver_list.GetNextID();
|
||||
: WorldTCPConnection(), tcpc(itcpc), zone_boot_timer(5000) {
|
||||
|
||||
/* Set Process tracking variable defaults */
|
||||
|
||||
memset(zone_name, 0, sizeof(zone_name));
|
||||
memset(compiled, 0, sizeof(compiled));
|
||||
zoneID = 0;
|
||||
instanceID = 0;
|
||||
memset(client_address, 0, sizeof(client_address));
|
||||
memset(client_local_address, 0, sizeof(client_local_address));
|
||||
|
||||
memset(clientaddress, 0, sizeof(clientaddress));
|
||||
clientport = 0;
|
||||
BootingUp = false;
|
||||
authenticated = false;
|
||||
staticzone = false;
|
||||
pNumPlayers = 0;
|
||||
zone_server_id = zoneserver_list.GetNextID();
|
||||
zone_server_zone_id = 0;
|
||||
instance_id = 0;
|
||||
zone_os_process_id = 0;
|
||||
client_port = 0;
|
||||
is_booting_up = false;
|
||||
is_authenticated = false;
|
||||
is_static_zone = false;
|
||||
zone_player_count = 0;
|
||||
}
|
||||
|
||||
ZoneServer::~ZoneServer() {
|
||||
@@ -73,7 +78,7 @@ ZoneServer::~ZoneServer() {
|
||||
}
|
||||
|
||||
bool ZoneServer::SetZone(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
BootingUp = false;
|
||||
is_booting_up = false;
|
||||
|
||||
const char* zn = MakeLowerString(database.GetZoneName(iZoneID));
|
||||
char* longname;
|
||||
@@ -82,17 +87,17 @@ bool ZoneServer::SetZone(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Setting to '%s' (%d:%d)%s",(zn) ? zn : "",iZoneID, iInstanceID,
|
||||
iStaticZone ? " (Static)" : "");
|
||||
|
||||
zoneID = iZoneID;
|
||||
instanceID = iInstanceID;
|
||||
zone_server_zone_id = iZoneID;
|
||||
instance_id = iInstanceID;
|
||||
if(iZoneID!=0)
|
||||
oldZoneID = iZoneID;
|
||||
if (zoneID == 0) {
|
||||
zone_server_previous_zone_id = iZoneID;
|
||||
if (zone_server_zone_id == 0) {
|
||||
client_list.CLERemoveZSRef(this);
|
||||
pNumPlayers = 0;
|
||||
zone_player_count = 0;
|
||||
LSSleepUpdate(GetPrevZoneID());
|
||||
}
|
||||
|
||||
staticzone = iStaticZone;
|
||||
is_static_zone = iStaticZone;
|
||||
|
||||
if (zn)
|
||||
{
|
||||
@@ -112,7 +117,7 @@ bool ZoneServer::SetZone(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
}
|
||||
|
||||
client_list.ZoneBootup(this);
|
||||
ls_zboot.Start();
|
||||
zone_boot_timer.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -173,26 +178,28 @@ void ZoneServer::LSSleepUpdate(uint32 zoneid){
|
||||
bool ZoneServer::Process() {
|
||||
if (!tcpc->Connected())
|
||||
return false;
|
||||
if(ls_zboot.Check()){
|
||||
if(zone_boot_timer.Check()){
|
||||
LSBootUpdate(GetZoneID(), true);
|
||||
ls_zboot.Disable();
|
||||
zone_boot_timer.Disable();
|
||||
}
|
||||
ServerPacket *pack = 0;
|
||||
while((pack = tcpc->PopPacket())) {
|
||||
if (!authenticated) {
|
||||
if (!is_authenticated) {
|
||||
if (WorldConfig::get()->SharedKey.length() > 0) {
|
||||
if (pack->opcode == ServerOP_ZAAuth && pack->size == 16) {
|
||||
uint8 tmppass[16];
|
||||
MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass);
|
||||
if (memcmp(pack->pBuffer, tmppass, 16) == 0)
|
||||
authenticated = true;
|
||||
if (memcmp(pack->pBuffer, tmppass, 16) == 0) {
|
||||
is_authenticated = true;
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone process connected.");
|
||||
}
|
||||
else {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone authorization failed.");
|
||||
Log.Out(Logs::General, Logs::Error, "Zone authorization failed.");
|
||||
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
safe_delete(pack);
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
@@ -200,18 +207,18 @@ bool ZoneServer::Process() {
|
||||
else {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone authorization failed.");
|
||||
Log.Out(Logs::General, Logs::Error, "Zone authorization failed.");
|
||||
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
safe_delete(pack);
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"**WARNING** You have not configured a world shared key in your config file. You should add a <key>STRING</key> element to your <world> element to prevent unauthroized zone access.");
|
||||
authenticated = true;
|
||||
Log.Out(Logs::General, Logs::Error, "**WARNING** You have not configured a world shared key in your config file. You should add a <key>STRING</key> element to your <world> element to prevent unauthroized zone access.");
|
||||
is_authenticated = true;
|
||||
}
|
||||
}
|
||||
switch(pack->opcode) {
|
||||
@@ -583,17 +590,31 @@ bool ZoneServer::Process() {
|
||||
ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer;
|
||||
|
||||
if (!sci->port) {
|
||||
clientport=zoneserver_list.GetAvailableZonePort();
|
||||
client_port = zoneserver_list.GetAvailableZonePort();
|
||||
|
||||
ServerPacket p(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo));
|
||||
memset(p.pBuffer,0,sizeof(ServerConnectInfo));
|
||||
ServerConnectInfo* sci = (ServerConnectInfo*) p.pBuffer;
|
||||
sci->port = clientport;
|
||||
sci->port = client_port;
|
||||
SendPacket(&p);
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Auto zone port configuration. Telling zone to use port %d",clientport);
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Auto zone port configuration. Telling zone to use port %d",client_port);
|
||||
} else {
|
||||
clientport=sci->port;
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d, must be a previously allocated zone reconnecting.",clientport);
|
||||
client_port = sci->port;
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d.",client_port);
|
||||
}
|
||||
|
||||
if(sci->address[0]) {
|
||||
strn0cpy(client_address, sci->address, 250);
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone specified address %s.", sci->address);
|
||||
}
|
||||
|
||||
if(sci->local_address[0]) {
|
||||
strn0cpy(client_local_address, sci->local_address, 250);
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone specified local address %s.", sci->address);
|
||||
}
|
||||
|
||||
if (sci->process_id){
|
||||
zone_os_process_id = sci->process_id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -781,7 +802,7 @@ bool ZoneServer::Process() {
|
||||
whom->wrace = whoall->wrace;
|
||||
strcpy(whom->whom,whoall->whom);
|
||||
client_list.SendWhoAll(whoall->fromid,whoall->from, whoall->admin, whom, this);
|
||||
delete whom;
|
||||
safe_delete(whom);
|
||||
break;
|
||||
}
|
||||
case ServerOP_RequestOnlineGuildMembers: {
|
||||
@@ -809,6 +830,11 @@ bool ZoneServer::Process() {
|
||||
RuleManager::Instance()->LoadRules(&database, "default");
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadPerlExportSettings:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_CameraShake:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack);
|
||||
@@ -960,15 +986,15 @@ bool ZoneServer::Process() {
|
||||
tod->start_eqtime=zoneserver_list.worldclock.getStartEQTime();
|
||||
tod->start_realtime=zoneserver_list.worldclock.getStartRealTime();
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
safe_delete(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_SetWorldTime: {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Received SetWorldTime");
|
||||
eqTimeOfDay* newtime = (eqTimeOfDay*) pack->pBuffer;
|
||||
zoneserver_list.worldclock.setEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime);
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime);
|
||||
zoneserver_list.worldclock.saveFile(WorldConfig::get()->EQTimeFile.c_str());
|
||||
zoneserver_list.worldclock.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime);
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime);
|
||||
database.SaveTime((int)newtime->start_eqtime.minute, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.day, newtime->start_eqtime.month, newtime->start_eqtime.year);
|
||||
zoneserver_list.SendTimeSync();
|
||||
break;
|
||||
}
|
||||
@@ -1061,8 +1087,7 @@ bool ZoneServer::Process() {
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pack;
|
||||
pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
||||
strcpy(scs->grantname, s->grantname);
|
||||
strcpy(scs->ownername, s->ownername);
|
||||
@@ -1078,6 +1103,7 @@ bool ZoneServer::Process() {
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent_Response operation.", s->instance_id);
|
||||
}
|
||||
safe_delete(pack);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1093,8 +1119,7 @@ bool ZoneServer::Process() {
|
||||
}
|
||||
else {
|
||||
// send target not found back to requester
|
||||
delete pack;
|
||||
pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
||||
strcpy(scs->grantname, s->grantname);
|
||||
strcpy(scs->ownername, s->ownername);
|
||||
@@ -1109,13 +1134,13 @@ bool ZoneServer::Process() {
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id);
|
||||
}
|
||||
safe_delete(pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// send target not found back to requester
|
||||
delete pack;
|
||||
pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
||||
strcpy(scs->grantname, s->grantname);
|
||||
strcpy(scs->ownername, s->ownername);
|
||||
@@ -1130,6 +1155,7 @@ bool ZoneServer::Process() {
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id);
|
||||
}
|
||||
safe_delete(pack);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1307,6 +1333,23 @@ bool ZoneServer::Process() {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ChangeSharedMem: {
|
||||
std::string hotfix_name = std::string((char*)pack->pBuffer);
|
||||
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading items...");
|
||||
if(!database.LoadItems(hotfix_name)) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Error: Could not load item data. But ignoring");
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::World_Server, "Loading skill caps...");
|
||||
if(!database.LoadSkillCaps(hotfix_name)) {
|
||||
Log.Out(Logs::General, Logs::World_Server, "Error: Could not load skill cap data. But ignoring");
|
||||
}
|
||||
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerOP_RequestTellQueue:
|
||||
{
|
||||
ServerRequestTellQueue_Struct* rtq = (ServerRequestTellQueue_Struct*) pack->pBuffer;
|
||||
@@ -1319,13 +1362,17 @@ bool ZoneServer::Process() {
|
||||
}
|
||||
default:
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Unknown ServerOPcode from zone 0x%04x, size %d",pack->opcode,pack->size);
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Unknown ServerOPcode from zone 0x%04x, size %d", pack->opcode, pack->size);
|
||||
DumpPacket(pack->pBuffer, pack->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete pack;
|
||||
if (pack) {
|
||||
safe_delete(pack);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zoneserver process attempted to delete pack when pack does not exist.");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1389,13 +1436,13 @@ void ZoneServer::ChangeWID(uint32 iCharID, uint32 iWID) {
|
||||
|
||||
|
||||
void ZoneServer::TriggerBootup(uint32 iZoneID, uint32 iInstanceID, const char* adminname, bool iMakeStatic) {
|
||||
BootingUp = true;
|
||||
zoneID = iZoneID;
|
||||
instanceID = iInstanceID;
|
||||
is_booting_up = true;
|
||||
zone_server_zone_id = iZoneID;
|
||||
instance_id = iInstanceID;
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_ZoneBootup, sizeof(ServerZoneStateChange_struct));
|
||||
ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer;
|
||||
s->ZoneServerID = ID;
|
||||
s->ZoneServerID = zone_server_id;
|
||||
if (adminname != 0)
|
||||
strcpy(s->adminname, adminname);
|
||||
|
||||
@@ -1412,7 +1459,7 @@ void ZoneServer::TriggerBootup(uint32 iZoneID, uint32 iInstanceID, const char* a
|
||||
}
|
||||
|
||||
void ZoneServer::IncomingClient(Client* client) {
|
||||
BootingUp = true;
|
||||
is_booting_up = true;
|
||||
auto pack = new ServerPacket(ServerOP_ZoneIncClient, sizeof(ServerZoneIncomingClient_Struct));
|
||||
ServerZoneIncomingClient_Struct* s = (ServerZoneIncomingClient_Struct*) pack->pBuffer;
|
||||
s->zoneid = GetZoneID();
|
||||
|
||||
+29
-23
@@ -44,7 +44,7 @@ public:
|
||||
void LSBootUpdate(uint32 zoneid, uint32 iInstanceID = 0, bool startup = false);
|
||||
void LSSleepUpdate(uint32 zoneid);
|
||||
void LSShutDownUpdate(uint32 zoneid);
|
||||
uint32 GetPrevZoneID() { return oldZoneID; }
|
||||
uint32 GetPrevZoneID() { return zone_server_previous_zone_id; }
|
||||
void ChangeWID(uint32 iCharID, uint32 iWID);
|
||||
void SendGroupIDs();
|
||||
|
||||
@@ -52,39 +52,45 @@ public:
|
||||
inline const char* GetZoneLongName() const { return long_name; }
|
||||
const char* GetCompileTime() const{ return compiled; }
|
||||
void SetCompile(char* in_compile){ strcpy(compiled,in_compile); }
|
||||
inline uint32 GetZoneID() const { return zoneID; }
|
||||
inline uint32 GetZoneID() const { return zone_server_zone_id; }
|
||||
inline uint32 GetIP() const { return tcpc->GetrIP(); }
|
||||
inline uint16 GetPort() const { return tcpc->GetrPort(); }
|
||||
inline const char* GetCAddress() const { return clientaddress; }
|
||||
inline uint16 GetCPort() const { return clientport; }
|
||||
inline uint32 GetID() const { return ID; }
|
||||
inline bool IsBootingUp() const { return BootingUp; }
|
||||
inline bool IsStaticZone() const{ return staticzone; }
|
||||
inline uint32 NumPlayers() const { return pNumPlayers; }
|
||||
inline void AddPlayer() { pNumPlayers++; }
|
||||
inline void RemovePlayer() { pNumPlayers--; }
|
||||
inline const char* GetCAddress() const { return client_address; }
|
||||
inline const char* GetCLocalAddress() const { return client_local_address; }
|
||||
inline uint16 GetCPort() const { return client_port; }
|
||||
inline uint32 GetID() const { return zone_server_id; }
|
||||
inline bool IsBootingUp() const { return is_booting_up; }
|
||||
inline bool IsStaticZone() const{ return is_static_zone; }
|
||||
inline uint32 NumPlayers() const { return zone_player_count; }
|
||||
inline void AddPlayer() { zone_player_count++; }
|
||||
inline void RemovePlayer() { zone_player_count--; }
|
||||
inline const char * GetLaunchName() const { return(launcher_name.c_str()); }
|
||||
inline const char * GetLaunchedName() const { return(launched_name.c_str()); }
|
||||
|
||||
inline uint32 GetInstanceID() { return instanceID; }
|
||||
inline void SetInstanceID(uint32 i) { instanceID = i; }
|
||||
inline uint32 GetInstanceID() { return instance_id; }
|
||||
inline void SetInstanceID(uint32 i) { instance_id = i; }
|
||||
|
||||
inline uint32 GetZoneOSProcessID() { return zone_os_process_id; }
|
||||
|
||||
private:
|
||||
EmuTCPConnection* const tcpc;
|
||||
|
||||
uint32 ID;
|
||||
char clientaddress[250];
|
||||
uint16 clientport;
|
||||
bool BootingUp;
|
||||
bool staticzone;
|
||||
bool authenticated;
|
||||
uint32 pNumPlayers;
|
||||
uint32 zone_server_id;
|
||||
char client_address[250];
|
||||
char client_local_address[250];
|
||||
uint16 client_port;
|
||||
bool is_booting_up;
|
||||
bool is_static_zone;
|
||||
bool is_authenticated;
|
||||
uint32 zone_player_count;
|
||||
char compiled[25];
|
||||
char zone_name[32];
|
||||
char long_name[256];
|
||||
uint32 zoneID;
|
||||
uint32 oldZoneID;
|
||||
Timer ls_zboot;
|
||||
uint32 instanceID; //instance ids contain a zone id, and a zone version
|
||||
uint32 zone_server_zone_id;
|
||||
uint32 zone_server_previous_zone_id;
|
||||
Timer zone_boot_timer;
|
||||
uint32 instance_id; //instance ids contain a zone id, and a zone version
|
||||
uint32 zone_os_process_id;
|
||||
std::string launcher_name; //the launcher which started us
|
||||
std::string launched_name; //the name of the zone we launched.
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user