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:
Natedog2012
2016-08-18 03:55:58 -07:00
430 changed files with 99694 additions and 39003 deletions
+210 -144
View File
@@ -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
View File
@@ -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);
+4 -4
View File
@@ -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;
+7 -6
View File
@@ -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
View File
@@ -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());
+1 -1
View File
@@ -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
View File
@@ -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;
}
+1
View File
@@ -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);
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
};