mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-01 11:36:36 +00:00
svn -> git Migration
This commit is contained in:
@@ -0,0 +1,438 @@
|
||||
#include "../common/debug.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/extprofile.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include "Adventure.h"
|
||||
#include "AdventureManager.h"
|
||||
#include "worlddb.h"
|
||||
#include "zonelist.h"
|
||||
#include "clientlist.h"
|
||||
#include "cliententry.h"
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
extern ClientList client_list;
|
||||
extern AdventureManager adventure_manager;
|
||||
|
||||
Adventure::Adventure(AdventureTemplate *t)
|
||||
{
|
||||
adventure_template = t;
|
||||
status = AS_WaitingForZoneIn;
|
||||
current_timer = new Timer(1000 * t->zone_in_time);
|
||||
count = 0;
|
||||
assassination_count = 0;
|
||||
instance_id = 0;
|
||||
}
|
||||
|
||||
Adventure::Adventure(AdventureTemplate *t, int count, int assassination_count, AdventureStatus status, uint16 instance_id, uint32 time_left)
|
||||
{
|
||||
adventure_template = t;
|
||||
this->count = count;
|
||||
this->assassination_count = assassination_count;
|
||||
this->status = status;
|
||||
this->instance_id = instance_id;
|
||||
|
||||
if(status == AS_Finished)
|
||||
{
|
||||
database.SetInstanceDuration(instance_id, time_left);
|
||||
}
|
||||
else
|
||||
{
|
||||
database.SetInstanceDuration(instance_id, time_left + 60);
|
||||
}
|
||||
|
||||
current_timer = new Timer(1000 * time_left);
|
||||
}
|
||||
|
||||
Adventure::~Adventure()
|
||||
{
|
||||
safe_delete(current_timer);
|
||||
}
|
||||
|
||||
void Adventure::AddPlayer(string character_name, bool add_client_to_instance)
|
||||
{
|
||||
if(!PlayerExists(character_name))
|
||||
{
|
||||
int client_id = database.GetCharacterID(character_name.c_str());
|
||||
if(add_client_to_instance)
|
||||
{
|
||||
database.AddClientToInstance(instance_id, client_id);
|
||||
}
|
||||
players.push_back(character_name);
|
||||
}
|
||||
}
|
||||
|
||||
void Adventure::RemovePlayer(string character_name)
|
||||
{
|
||||
list<string>::iterator iter = players.begin();
|
||||
while(iter != players.end())
|
||||
{
|
||||
if((*iter).compare(character_name) == 0)
|
||||
{
|
||||
database.RemoveClientFromInstance(instance_id, database.GetCharacterID(character_name.c_str()));
|
||||
players.erase(iter);
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
bool Adventure::PlayerExists(string character_name)
|
||||
{
|
||||
list<string>::iterator iter = players.begin();
|
||||
while(iter != players.end())
|
||||
{
|
||||
if(character_name.compare((*iter)) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Adventure::IsActive()
|
||||
{
|
||||
return (status != AS_Finished);
|
||||
}
|
||||
|
||||
bool Adventure::Process()
|
||||
{
|
||||
if(players.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(current_timer->Check())
|
||||
{
|
||||
//Timer wore out while waiting for zone in.
|
||||
if(status == AS_WaitingForZoneIn)
|
||||
{
|
||||
MoveCorpsesToGraveyard();
|
||||
database.DeleteInstance(instance_id);
|
||||
return false;
|
||||
}
|
||||
else if(status == AS_WaitingForPrimaryEndTime)
|
||||
{
|
||||
//Do partial failure: send a message to the clients that they can only get a certain amount of points.
|
||||
SendAdventureMessage(13, "You failed to complete your adventure in time. Complete your adventure goal within 30 minutes to "
|
||||
"receive a lesser reward. This adventure will end in 30 minutes and your party will be ejected from the dungeon.");
|
||||
SetStatus(AS_WaitingForSecondaryEndTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count < GetTemplate()->type_count)
|
||||
{
|
||||
Finished(AWS_Lose);
|
||||
}
|
||||
|
||||
MoveCorpsesToGraveyard();
|
||||
database.DeleteInstance(instance_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Adventure::CreateInstance()
|
||||
{
|
||||
uint32 zone_id = database.GetZoneID(adventure_template->zone);
|
||||
if(!zone_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 id = 0;
|
||||
if(!database.GetUnusedInstanceID(id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!database.CreateInstance(id, zone_id, adventure_template->zone_version, adventure_template->zone_in_time + 60))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
instance_id = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Adventure::SetStatus(AdventureStatus new_status)
|
||||
{
|
||||
if(new_status == AS_WaitingForPrimaryEndTime)
|
||||
{
|
||||
status = new_status;
|
||||
safe_delete(current_timer);
|
||||
current_timer = new Timer(adventure_template->duration * 1000);
|
||||
database.SetInstanceDuration(instance_id, adventure_template->duration + 60);
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_InstanceUpdateTime, sizeof(ServerInstanceUpdateTime_Struct));
|
||||
ServerInstanceUpdateTime_Struct *ut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer;
|
||||
ut->instance_id = instance_id;
|
||||
ut->new_duration = adventure_template->duration + 60;
|
||||
|
||||
pack->Deflate();
|
||||
zoneserver_list.SendPacket(0, instance_id, pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else if(new_status == AS_WaitingForSecondaryEndTime)
|
||||
{
|
||||
status = new_status;
|
||||
safe_delete(current_timer);
|
||||
current_timer = new Timer(1800000);
|
||||
database.SetInstanceDuration(instance_id, 1860);
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_InstanceUpdateTime, sizeof(ServerInstanceUpdateTime_Struct));
|
||||
ServerInstanceUpdateTime_Struct *ut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer;
|
||||
ut->instance_id = instance_id;
|
||||
ut->new_duration = 1860;
|
||||
|
||||
pack->Deflate();
|
||||
zoneserver_list.SendPacket(0, instance_id, pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else if(new_status == AS_Finished)
|
||||
{
|
||||
status = new_status;
|
||||
safe_delete(current_timer);
|
||||
current_timer = new Timer(1800000);
|
||||
database.SetInstanceDuration(instance_id, 1800);
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_InstanceUpdateTime, sizeof(ServerInstanceUpdateTime_Struct));
|
||||
ServerInstanceUpdateTime_Struct *ut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer;
|
||||
ut->instance_id = instance_id;
|
||||
ut->new_duration = 1860;
|
||||
|
||||
pack->Deflate();
|
||||
zoneserver_list.SendPacket(0, instance_id, pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
list<string>::iterator iter = players.begin();
|
||||
while(iter != players.end())
|
||||
{
|
||||
adventure_manager.GetAdventureData((*iter).c_str());
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void Adventure::SendAdventureMessage(uint32 type, const char *msg)
|
||||
{
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_EmoteMessage, sizeof(ServerEmoteMessage_Struct) + strlen(msg) + 1);
|
||||
ServerEmoteMessage_Struct *sms = (ServerEmoteMessage_Struct*)pack->pBuffer;
|
||||
sms->type = type;
|
||||
strcpy(sms->message, msg);
|
||||
list<string>::iterator iter = players.begin();
|
||||
while(iter != players.end())
|
||||
{
|
||||
ClientListEntry *current = client_list.FindCharacter((*iter).c_str());
|
||||
if(current)
|
||||
{
|
||||
strcpy(sms->to, (*iter).c_str());
|
||||
zoneserver_list.SendPacket(current->zone(), current->instance(), pack);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void Adventure::IncrementCount()
|
||||
{
|
||||
const AdventureTemplate *at = GetTemplate();
|
||||
if(count >= at->type_count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(status == AS_WaitingForPrimaryEndTime)
|
||||
{
|
||||
count++;
|
||||
if(count == at->type_count)
|
||||
{
|
||||
SetStatus(AS_Finished);
|
||||
Finished(AWS_Win);
|
||||
}
|
||||
}
|
||||
else if(status == AS_WaitingForSecondaryEndTime)
|
||||
{
|
||||
count++;
|
||||
if(count == at->type_count)
|
||||
{
|
||||
SetStatus(AS_Finished);
|
||||
Finished(AWS_SecondPlace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Adventure::IncrementAssassinationCount()
|
||||
{
|
||||
if(count >= RuleI(Adventure, NumberKillsForBossSpawn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assassination_count++;
|
||||
}
|
||||
|
||||
void Adventure::Finished(AdventureWinStatus ws)
|
||||
{
|
||||
list<string>::iterator iter = players.begin();
|
||||
while(iter != players.end())
|
||||
{
|
||||
ClientListEntry *current = client_list.FindCharacter((*iter).c_str());
|
||||
if(current)
|
||||
{
|
||||
if(current->Online() == CLE_Status_InZone)
|
||||
{
|
||||
//We can send our packets only.
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_AdventureFinish, sizeof(ServerAdventureFinish_Struct));
|
||||
ServerAdventureFinish_Struct *af = (ServerAdventureFinish_Struct*)pack->pBuffer;
|
||||
strcpy(af->player, (*iter).c_str());
|
||||
af->theme = GetTemplate()->theme;
|
||||
if(ws == AWS_Win)
|
||||
{
|
||||
af->win = true;
|
||||
af->points = GetTemplate()->win_points;
|
||||
}
|
||||
else if(ws == AWS_SecondPlace)
|
||||
{
|
||||
af->win = true;
|
||||
af->points = GetTemplate()->lose_points;
|
||||
}
|
||||
else
|
||||
{
|
||||
af->win = false;
|
||||
af->points = 0;
|
||||
}
|
||||
pack->Deflate();
|
||||
zoneserver_list.SendPacket(current->zone(), current->instance(), pack);
|
||||
database.UpdateAdventureStatsEntry(database.GetCharacterID((*iter).c_str()), GetTemplate()->theme, (ws != AWS_Lose) ? true : false);
|
||||
delete pack;
|
||||
}
|
||||
else
|
||||
{
|
||||
AdventureFinishEvent afe;
|
||||
afe.name = (*iter);
|
||||
if(ws == AWS_Win)
|
||||
{
|
||||
afe.theme = GetTemplate()->theme;
|
||||
afe.points = GetTemplate()->win_points;
|
||||
afe.win = true;
|
||||
}
|
||||
else if(ws == AWS_SecondPlace)
|
||||
{
|
||||
afe.theme = GetTemplate()->theme;
|
||||
afe.points = GetTemplate()->lose_points;
|
||||
afe.win = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
afe.win = false;
|
||||
afe.points = 0;
|
||||
}
|
||||
adventure_manager.AddFinishedEvent(afe);
|
||||
database.UpdateAdventureStatsEntry(database.GetCharacterID((*iter).c_str()), GetTemplate()->theme, (ws != AWS_Lose) ? true : false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AdventureFinishEvent afe;
|
||||
afe.name = (*iter);
|
||||
if(ws == AWS_Win)
|
||||
{
|
||||
afe.theme = GetTemplate()->theme;
|
||||
afe.points = GetTemplate()->win_points;
|
||||
afe.win = true;
|
||||
}
|
||||
else if(ws == AWS_SecondPlace)
|
||||
{
|
||||
afe.theme = GetTemplate()->theme;
|
||||
afe.points = GetTemplate()->lose_points;
|
||||
afe.win = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
afe.win = false;
|
||||
afe.points = 0;
|
||||
}
|
||||
adventure_manager.AddFinishedEvent(afe);
|
||||
database.UpdateAdventureStatsEntry(database.GetCharacterID((*iter).c_str()), GetTemplate()->theme, (ws != AWS_Lose) ? true : false);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
adventure_manager.GetAdventureData(this);
|
||||
}
|
||||
|
||||
void Adventure::MoveCorpsesToGraveyard()
|
||||
{
|
||||
if(GetTemplate()->graveyard_zone_id == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
list<uint32> dbid_list;
|
||||
list<uint32> charid_list;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT id, charid FROM player_corpses WHERE instanceid=%d", GetInstanceID()), errbuf, &result))
|
||||
{
|
||||
while((row = mysql_fetch_row(result)))
|
||||
{
|
||||
dbid_list.push_back(atoi(row[0]));
|
||||
charid_list.push_back(atoi(row[1]));
|
||||
}
|
||||
mysql_free_result(result);
|
||||
safe_delete_array(query);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
}
|
||||
|
||||
list<uint32>::iterator iter = dbid_list.begin();
|
||||
while(iter != dbid_list.end())
|
||||
{
|
||||
float x = GetTemplate()->graveyard_x + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
|
||||
float y = GetTemplate()->graveyard_y + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
|
||||
float z = GetTemplate()->graveyard_z;
|
||||
if(database.RunQuery(query,MakeAnyLenString(&query, "UPDATE player_corpses SET zoneid=%d, instanceid=0, x=%f, y=%f, z=%f WHERE instanceid=%d",
|
||||
GetTemplate()->graveyard_zone_id, x, y, z, GetInstanceID()), errbuf))
|
||||
{
|
||||
safe_delete_array(query);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
iter = dbid_list.begin();
|
||||
list<uint32>::iterator c_iter = charid_list.begin();
|
||||
while(iter != dbid_list.end())
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct));
|
||||
ServerDepopAllPlayersCorpses_Struct *dpc = (ServerDepopAllPlayersCorpses_Struct*)pack->pBuffer;
|
||||
dpc->CharacterID = (*c_iter);
|
||||
dpc->InstanceID = 0;
|
||||
dpc->ZoneID = GetTemplate()->graveyard_zone_id;
|
||||
zoneserver_list.SendPacket(0, GetInstanceID(), pack);
|
||||
delete pack;
|
||||
|
||||
pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
|
||||
SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
|
||||
spc->player_corpse_id = (*iter);
|
||||
spc->zone_id = GetTemplate()->graveyard_zone_id;
|
||||
|
||||
zoneserver_list.SendPacket(spc->zone_id, 0, pack);
|
||||
delete pack;
|
||||
iter++;
|
||||
c_iter++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
#ifndef ADVENTURE_H
|
||||
#define ADVENTURE_H
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/types.h"
|
||||
#include "../common/timer.h"
|
||||
#include "AdventureTemplate.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum AdventureStatus
|
||||
{
|
||||
AS_WaitingForZoneIn,
|
||||
AS_WaitingForPrimaryEndTime,
|
||||
AS_WaitingForSecondaryEndTime,
|
||||
AS_Finished,
|
||||
};
|
||||
|
||||
enum AdventureWinStatus
|
||||
{
|
||||
AWS_Win,
|
||||
AWS_SecondPlace,
|
||||
AWS_Lose
|
||||
};
|
||||
|
||||
struct AdventureZones
|
||||
{
|
||||
string zone;
|
||||
int version;
|
||||
};
|
||||
|
||||
struct AdventureZoneIn
|
||||
{
|
||||
int zone_id;
|
||||
int door_id;
|
||||
};
|
||||
|
||||
struct AdventureFinishEvent
|
||||
{
|
||||
string name;
|
||||
bool win;
|
||||
int points;
|
||||
int theme;
|
||||
};
|
||||
|
||||
struct LeaderboardInfo
|
||||
{
|
||||
string name;
|
||||
uint32 wins;
|
||||
uint32 guk_wins;
|
||||
uint32 mir_wins;
|
||||
uint32 mmc_wins;
|
||||
uint32 ruj_wins;
|
||||
uint32 tak_wins;
|
||||
uint32 losses;
|
||||
uint32 guk_losses;
|
||||
uint32 mir_losses;
|
||||
uint32 mmc_losses;
|
||||
uint32 ruj_losses;
|
||||
uint32 tak_losses;
|
||||
};
|
||||
|
||||
class Adventure
|
||||
{
|
||||
public:
|
||||
Adventure(AdventureTemplate *t);
|
||||
Adventure(AdventureTemplate *t, int count, int assassination_count, AdventureStatus status, uint16 instance_id, uint32 time_left);
|
||||
~Adventure();
|
||||
bool Process();
|
||||
bool IsActive();
|
||||
void AddPlayer(string character_name, bool add_client_to_instance = true);
|
||||
void RemovePlayer(string character_name);
|
||||
bool PlayerExists(string character_name);
|
||||
bool CreateInstance();
|
||||
void IncrementCount();
|
||||
void IncrementAssassinationCount();
|
||||
void Finished(AdventureWinStatus ws);
|
||||
void SetStatus(AdventureStatus new_status);
|
||||
void SendAdventureMessage(uint32 type, const char *msg);
|
||||
void MoveCorpsesToGraveyard();
|
||||
|
||||
uint16 GetInstanceID() const { return instance_id; }
|
||||
const AdventureTemplate *GetTemplate() const { return adventure_template; }
|
||||
AdventureStatus GetStatus() const { return status; }
|
||||
list<string> GetPlayers() { return players; }
|
||||
int GetCount() const { return count; }
|
||||
int GetAssassinationCount() const { return assassination_count; }
|
||||
uint32 GetRemainingTime() const { if(current_timer) { return (current_timer->GetRemainingTime() / 1000); } else { return 0; } }
|
||||
protected:
|
||||
int id;
|
||||
int count;
|
||||
int assassination_count;
|
||||
AdventureTemplate *adventure_template;
|
||||
AdventureStatus status;
|
||||
list<string> players;
|
||||
Timer *current_timer;
|
||||
int instance_id;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,95 @@
|
||||
#ifndef ADVENTURE_MANAGER_H
|
||||
#define ADVENTURE_MANAGER_H
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/types.h"
|
||||
#include "../common/timer.h"
|
||||
#include "Adventure.h"
|
||||
#include "AdventureTemplate.h"
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class AdventureManager
|
||||
{
|
||||
public:
|
||||
AdventureManager();
|
||||
~AdventureManager();
|
||||
|
||||
void Process();
|
||||
|
||||
bool LoadAdventureTemplates();
|
||||
bool LoadAdventureEntries();
|
||||
void LoadLeaderboardInfo();
|
||||
|
||||
void CalculateAdventureRequestReply(const char *data);
|
||||
void PlayerClickedDoor(const char *player, int zone_id, int door_id);
|
||||
void TryAdventureCreate(const char *data);
|
||||
void GetAdventureData(Adventure *adv);
|
||||
void GetAdventureData(const char *name);
|
||||
void LeaveAdventure(const char *name);
|
||||
void IncrementCount(uint16 instance_id);
|
||||
void IncrementAssassinationCount(uint16 instance_id);
|
||||
void DoLeaderboardRequest(const char* player, uint8 type);
|
||||
void SendAdventureFinish(AdventureFinishEvent fe);
|
||||
void AddFinishedEvent(AdventureFinishEvent fe) { finished_list.push_back(fe); Save(); }
|
||||
bool PopFinishedEvent(const char *name, AdventureFinishEvent &fe);
|
||||
void Save();
|
||||
void Load();
|
||||
|
||||
Adventure **GetFinishedAdventures(const char *player, int &count);
|
||||
Adventure *GetActiveAdventure(const char *player);
|
||||
AdventureTemplate *GetAdventureTemplate(int theme, int id);
|
||||
AdventureTemplate *GetAdventureTemplate(int id);
|
||||
void GetZoneData(uint16 instance_id);
|
||||
protected:
|
||||
bool IsInExcludedZoneList(list<AdventureZones> excluded_zones, string zone_name, int version);
|
||||
bool IsInExcludedZoneInList(list<AdventureZoneIn> excluded_zone_ins, int zone_id, int door_object);
|
||||
void DoLeaderboardRequestWins(const char* player);
|
||||
void DoLeaderboardRequestPercentage(const char* player);
|
||||
void DoLeaderboardRequestWinsGuk(const char* player);
|
||||
void DoLeaderboardRequestPercentageGuk(const char* player);
|
||||
void DoLeaderboardRequestWinsMir(const char* player);
|
||||
void DoLeaderboardRequestPercentageMir(const char* player);
|
||||
void DoLeaderboardRequestWinsMmc(const char* player);
|
||||
void DoLeaderboardRequestPercentageMmc(const char* player);
|
||||
void DoLeaderboardRequestWinsRuj(const char* player);
|
||||
void DoLeaderboardRequestPercentageRuj(const char* player);
|
||||
void DoLeaderboardRequestWinsTak(const char* player);
|
||||
void DoLeaderboardRequestPercentageTak(const char* player);
|
||||
|
||||
map<uint32, AdventureTemplate*> adventure_templates;
|
||||
map<uint32, list<AdventureTemplate*> > adventure_entries;
|
||||
list<Adventure*> adventure_list;
|
||||
list<AdventureFinishEvent> finished_list;
|
||||
list<LeaderboardInfo> leaderboard_info_wins;
|
||||
list<LeaderboardInfo> leaderboard_info_percentage;
|
||||
list<LeaderboardInfo> leaderboard_info_wins_guk;
|
||||
list<LeaderboardInfo> leaderboard_info_percentage_guk;
|
||||
list<LeaderboardInfo> leaderboard_info_wins_mir;
|
||||
list<LeaderboardInfo> leaderboard_info_percentage_mir;
|
||||
list<LeaderboardInfo> leaderboard_info_wins_mmc;
|
||||
list<LeaderboardInfo> leaderboard_info_percentage_mmc;
|
||||
list<LeaderboardInfo> leaderboard_info_wins_ruj;
|
||||
list<LeaderboardInfo> leaderboard_info_percentage_ruj;
|
||||
list<LeaderboardInfo> leaderboard_info_wins_tak;
|
||||
list<LeaderboardInfo> leaderboard_info_percentage_tak;
|
||||
bool leaderboard_sorted_wins;
|
||||
bool leaderboard_sorted_percentage;
|
||||
bool leaderboard_sorted_wins_guk;
|
||||
bool leaderboard_sorted_percentage_guk;
|
||||
bool leaderboard_sorted_wins_mir;
|
||||
bool leaderboard_sorted_percentage_mir;
|
||||
bool leaderboard_sorted_wins_mmc;
|
||||
bool leaderboard_sorted_percentage_mmc;
|
||||
bool leaderboard_sorted_wins_ruj;
|
||||
bool leaderboard_sorted_percentage_ruj;
|
||||
bool leaderboard_sorted_wins_tak;
|
||||
bool leaderboard_sorted_percentage_tak;
|
||||
Timer *process_timer;
|
||||
Timer *save_timer;
|
||||
Timer *leaderboard_info_timer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef ADVENTURE_TEMPLATE_H
|
||||
#define ADVENTURE_TEMPLATE_H
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/types.h"
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct AdventureTemplate
|
||||
{
|
||||
uint32 id;
|
||||
char zone[64];
|
||||
uint32 zone_version;
|
||||
bool is_hard;
|
||||
int32 min_level;
|
||||
int32 max_level;
|
||||
uint8 type;
|
||||
uint32 type_data;
|
||||
uint16 type_count;
|
||||
float assa_x;
|
||||
float assa_y;
|
||||
float assa_z;
|
||||
float assa_h;
|
||||
char text[1024];
|
||||
uint32 duration;
|
||||
uint32 zone_in_time;
|
||||
int32 win_points;
|
||||
int32 lose_points;
|
||||
uint8 theme;
|
||||
uint16 zone_in_zone_id;
|
||||
float zone_in_x;
|
||||
float zone_in_y;
|
||||
uint16 zone_in_object_id;
|
||||
float dest_x;
|
||||
float dest_y;
|
||||
float dest_z;
|
||||
float dest_h;
|
||||
int graveyard_zone_id;
|
||||
float graveyard_x;
|
||||
float graveyard_y;
|
||||
float graveyard_z;
|
||||
float graveyard_radius;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(world_sources
|
||||
Adventure.cpp
|
||||
AdventureManager.cpp
|
||||
client.cpp
|
||||
cliententry.cpp
|
||||
clientlist.cpp
|
||||
CMakeLists.txt
|
||||
console.cpp
|
||||
EQLConfig.cpp
|
||||
EQW.cpp
|
||||
EQWHTTPHandler.cpp
|
||||
EQWParser.cpp
|
||||
HTTPRequest.cpp
|
||||
LauncherLink.cpp
|
||||
LauncherList.cpp
|
||||
lfplist.cpp
|
||||
LoginServer.cpp
|
||||
LoginServerList.cpp
|
||||
net.cpp
|
||||
perl_EQLConfig.cpp
|
||||
perl_EQW.cpp
|
||||
perl_HTTPRequest.cpp
|
||||
queryserv.cpp
|
||||
ucs.cpp
|
||||
wguild_mgr.cpp
|
||||
world_logsys.cpp
|
||||
WorldConfig.cpp
|
||||
worlddb.cpp
|
||||
zonelist.cpp
|
||||
zoneserver.cpp
|
||||
)
|
||||
|
||||
SET(world_headers
|
||||
Adventure.h
|
||||
AdventureManager.h
|
||||
AdventureTemplate.h
|
||||
client.h
|
||||
cliententry.h
|
||||
clientlist.h
|
||||
CMakeLists.txt
|
||||
console.h
|
||||
EQLConfig.h
|
||||
EQW.h
|
||||
EQWHTTPHandler.h
|
||||
EQWParser.h
|
||||
HTTPRequest.h
|
||||
LauncherLink.h
|
||||
LauncherList.h
|
||||
lfplist.h
|
||||
LoginServer.h
|
||||
LoginServerList.h
|
||||
net.h
|
||||
queryserv.h
|
||||
SoFCharCreateData.h
|
||||
ucs.h
|
||||
wguild_mgr.h
|
||||
WorldConfig.h
|
||||
worlddb.h
|
||||
WorldTCPConnection.h
|
||||
zonelist.h
|
||||
zoneserver.h
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(world ${world_sources} ${world_headers})
|
||||
|
||||
ADD_DEFINITIONS(-DWORLD)
|
||||
|
||||
TARGET_LINK_LIBRARIES(world Common ${PERL_LIBRARY} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE})
|
||||
|
||||
IF(MSVC)
|
||||
|
||||
SET_TARGET_PROPERTIES(world PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
|
||||
TARGET_LINK_LIBRARIES(world "Ws2_32.lib")
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF(MINGW)
|
||||
TARGET_LINK_LIBRARIES(world "WS2_32")
|
||||
ENDIF(MINGW)
|
||||
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(world "dl")
|
||||
TARGET_LINK_LIBRARIES(world "z")
|
||||
TARGET_LINK_LIBRARIES(world "m")
|
||||
TARGET_LINK_LIBRARIES(world "rt")
|
||||
TARGET_LINK_LIBRARIES(world "pthread")
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
ENDIF(UNIX)
|
||||
|
||||
SET(EXECUTABLE_OUTPUT_PATH ../Bin)
|
||||
@@ -0,0 +1,384 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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/debug.h"
|
||||
#include "EQLConfig.h"
|
||||
#include "worlddb.h"
|
||||
#include "LauncherLink.h"
|
||||
#include "LauncherList.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
extern LauncherList launcher_list;
|
||||
|
||||
EQLConfig::EQLConfig(const char *launcher_name)
|
||||
: m_name(launcher_name)
|
||||
{
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
void EQLConfig::LoadSettings() {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
LauncherZone tmp;
|
||||
|
||||
char namebuf[128];
|
||||
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
|
||||
namebuf[127] = '\0';
|
||||
|
||||
if (database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"SELECT dynamics FROM launcher WHERE name='%s'",
|
||||
namebuf)
|
||||
, errbuf, &result))
|
||||
{
|
||||
while ((row = mysql_fetch_row(result))) {
|
||||
m_dynamics = atoi(row[0]);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
} else {
|
||||
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", errbuf);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
if (database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"SELECT zone,port FROM launcher_zones WHERE launcher='%s'",
|
||||
namebuf)
|
||||
, errbuf, &result))
|
||||
{
|
||||
LauncherZone zs;
|
||||
while ((row = mysql_fetch_row(result))) {
|
||||
zs.name = row[0];
|
||||
zs.port = atoi(row[1]);
|
||||
m_zones[zs.name] = zs;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
} else {
|
||||
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", errbuf);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
}
|
||||
|
||||
EQLConfig *EQLConfig::CreateLauncher(const char *name, uint8 dynamic_count) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char namebuf[128];
|
||||
database.DoEscapeString(namebuf, name, strlen(name)&0x3F); //limit len to 64
|
||||
namebuf[127] = '\0';
|
||||
|
||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"INSERT INTO launcher (name,dynamics) VALUES('%s', %d)",
|
||||
namebuf, dynamic_count), errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in CreateLauncher query: %s", errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
return(new EQLConfig(name));
|
||||
}
|
||||
|
||||
void EQLConfig::GetZones(std::vector<LauncherZone> &result) {
|
||||
map<string, LauncherZone>::iterator cur, end;
|
||||
cur = m_zones.begin();
|
||||
end = m_zones.end();
|
||||
for(; cur != end; cur++) {
|
||||
result.push_back(cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> EQLConfig::ListZones() {
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
vector<string> res;
|
||||
if(ll == NULL) {
|
||||
//if the launcher isnt connected, use the list from the database.
|
||||
map<string, LauncherZone>::iterator cur, end;
|
||||
cur = m_zones.begin();
|
||||
end = m_zones.end();
|
||||
for(; cur != end; cur++) {
|
||||
res.push_back(cur->first);
|
||||
}
|
||||
} else {
|
||||
//otherwise, use the zone list from the launcher link.
|
||||
ll->GetZoneList(res);
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
void EQLConfig::DeleteLauncher() {
|
||||
|
||||
launcher_list.Remove(m_name.c_str());
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char namebuf[128];
|
||||
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
|
||||
namebuf[127] = '\0';
|
||||
|
||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"DELETE FROM launcher WHERE name='%s'",
|
||||
namebuf), errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 1 query: %s", errbuf);
|
||||
safe_delete_array(query);
|
||||
return;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"DELETE FROM launcher_zones WHERE launcher='%s'",
|
||||
namebuf), errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 2 query: %s", errbuf);
|
||||
safe_delete_array(query);
|
||||
return;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
}
|
||||
|
||||
bool EQLConfig::IsConnected() const {
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
return(ll != NULL);
|
||||
}
|
||||
|
||||
void EQLConfig::RestartZone(Const_char *zone_ref) {
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll == NULL)
|
||||
return;
|
||||
ll->RestartZone(zone_ref);
|
||||
}
|
||||
|
||||
void EQLConfig::StopZone(Const_char *zone_ref) {
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll == NULL)
|
||||
return;
|
||||
ll->StopZone(zone_ref);
|
||||
}
|
||||
|
||||
void EQLConfig::StartZone(Const_char *zone_ref) {
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll == NULL)
|
||||
return;
|
||||
ll->StartZone(zone_ref);
|
||||
}
|
||||
|
||||
bool EQLConfig::BootStaticZone(Const_char *short_name, uint16 port) {
|
||||
//make sure the short name is valid.
|
||||
if(database.GetZoneID(short_name) == 0)
|
||||
return(false);
|
||||
|
||||
//database update
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char namebuf[128];
|
||||
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
|
||||
namebuf[127] = '\0';
|
||||
char zonebuf[32];
|
||||
database.DoEscapeString(zonebuf, short_name, strlen(short_name)&0xF); //limit len to 16
|
||||
zonebuf[31] = '\0';
|
||||
|
||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"INSERT INTO launcher_zones (launcher,zone,port) VALUES('%s', '%s', %d)",
|
||||
namebuf, zonebuf, port), errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in BootStaticZone query: %s", errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
//update our internal state.
|
||||
LauncherZone lz;
|
||||
lz.name = short_name;
|
||||
lz.port = port;
|
||||
m_zones[lz.name] = lz;
|
||||
|
||||
//if the launcher is connected, update it.
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll != NULL) {
|
||||
ll->BootZone(short_name, port);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool EQLConfig::ChangeStaticZone(Const_char *short_name, uint16 port) {
|
||||
//make sure the short name is valid.
|
||||
if(database.GetZoneID(short_name) == 0)
|
||||
return(false);
|
||||
|
||||
//check internal state
|
||||
map<string, LauncherZone>::iterator res;
|
||||
res = m_zones.find(short_name);
|
||||
if(res == m_zones.end()) {
|
||||
//not found.
|
||||
LogFile->write(EQEMuLog::Error, "Update for unknown zone %s", short_name);
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
//database update
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char namebuf[128];
|
||||
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
|
||||
namebuf[127] = '\0';
|
||||
char zonebuf[32];
|
||||
database.DoEscapeString(zonebuf, short_name, strlen(short_name)&0xF); //limit len to 16
|
||||
zonebuf[31] = '\0';
|
||||
|
||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"UPDATE launcher_zones SET port=%d WHERE launcher='%s' AND zone='%s'",
|
||||
port, namebuf, zonebuf), errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ChangeStaticZone query: %s", errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
|
||||
//update internal state
|
||||
res->second.port = port;
|
||||
|
||||
//if the launcher is connected, update it.
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll != NULL) {
|
||||
ll->RestartZone(short_name);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool EQLConfig::DeleteStaticZone(Const_char *short_name) {
|
||||
//check internal state
|
||||
map<string, LauncherZone>::iterator res;
|
||||
res = m_zones.find(short_name);
|
||||
if(res == m_zones.end()) {
|
||||
//not found.
|
||||
LogFile->write(EQEMuLog::Error, "Update for unknown zone %s", short_name);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//database update
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char namebuf[128];
|
||||
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
|
||||
namebuf[127] = '\0';
|
||||
char zonebuf[32];
|
||||
database.DoEscapeString(zonebuf, short_name, strlen(short_name)&0xF); //limit len to 16
|
||||
zonebuf[31] = '\0';
|
||||
|
||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"DELETE FROM launcher_zones WHERE launcher='%s' AND zone='%s'",
|
||||
namebuf, zonebuf), errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteStaticZone query: %s", errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
//internal update.
|
||||
m_zones.erase(res);
|
||||
|
||||
//if the launcher is connected, update it.
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll != NULL) {
|
||||
ll->StopZone(short_name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQLConfig::SetDynamicCount(int count) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char namebuf[128];
|
||||
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
|
||||
namebuf[127] = '\0';
|
||||
|
||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||
"UPDATE launcher SET dynamics=%d WHERE name='%s'",
|
||||
count, namebuf), errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetDynamicCount query: %s", errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
//update in-memory version.
|
||||
m_dynamics = count;
|
||||
|
||||
//if the launcher is connected, update it.
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll != NULL) {
|
||||
ll->BootDynamics(count);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
int EQLConfig::GetDynamicCount() const {
|
||||
return(m_dynamics);
|
||||
}
|
||||
|
||||
map<string,string> EQLConfig::GetZoneDetails(Const_char *zone_ref) {
|
||||
map<string,string> res;
|
||||
|
||||
LauncherLink *ll = launcher_list.Get(m_name.c_str());
|
||||
if(ll == NULL) {
|
||||
res["name"] = zone_ref;
|
||||
res["up"] = "0";
|
||||
res["starts"] = "0";
|
||||
res["port"] = "0";
|
||||
} else {
|
||||
ll->GetZoneDetails(zone_ref, res);
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef EQLCONFIG_H_
|
||||
#define EQLCONFIG_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "worlddb.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class LauncherLink;
|
||||
|
||||
typedef struct {
|
||||
std::string name;
|
||||
uint16 port;
|
||||
} LauncherZone;
|
||||
|
||||
//a class exported to perl representing a launcher's in-DB config
|
||||
class EQLConfig {
|
||||
public:
|
||||
EQLConfig(const char *launcher_name);
|
||||
|
||||
void LoadSettings();
|
||||
static EQLConfig *CreateLauncher(const char *name, uint8 dynamic_count);
|
||||
|
||||
void GetZones(std::vector<LauncherZone> &result);
|
||||
|
||||
//BEGIN PERL EXPORT
|
||||
Const_char * GetName() const { return(m_name.c_str()); }
|
||||
int GetStaticCount() const { return(m_zones.size()); }
|
||||
bool IsConnected() const; //is this launcher connected to world
|
||||
|
||||
void DeleteLauncher(); //kill this launcher and all its zones.
|
||||
|
||||
void RestartZone(Const_char *zone_ref);
|
||||
void StopZone(Const_char *zone_ref);
|
||||
void StartZone(Const_char *zone_ref);
|
||||
|
||||
bool BootStaticZone(Const_char *short_name, uint16 port);
|
||||
bool ChangeStaticZone(Const_char *short_name, uint16 port);
|
||||
bool DeleteStaticZone(Const_char *short_name);
|
||||
|
||||
bool SetDynamicCount(int count);
|
||||
int GetDynamicCount() const;
|
||||
|
||||
vector<string> ListZones(); //returns an array of zone refs
|
||||
map<string,string> GetZoneDetails(Const_char *zone_ref);
|
||||
//END PERL EXPORT
|
||||
|
||||
protected:
|
||||
const string m_name;
|
||||
|
||||
uint8 m_dynamics;
|
||||
|
||||
map<string, LauncherZone> m_zones; //static zones.
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*EQLCONFIG_H_*/
|
||||
|
||||
|
||||
+474
@@ -0,0 +1,474 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "EQW.h"
|
||||
#include "EQWParser.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "../common/races.h"
|
||||
#include "../common/classes.h"
|
||||
#include "../common/misc.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include "zoneserver.h"
|
||||
#include "zonelist.h"
|
||||
#include "clientlist.h"
|
||||
#include "cliententry.h"
|
||||
#include "LoginServer.h"
|
||||
#include "LoginServerList.h"
|
||||
#include "worlddb.h"
|
||||
#include "client.h"
|
||||
#include "LauncherList.h"
|
||||
#include "LauncherLink.h"
|
||||
#include "wguild_mgr.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
extern ClientList client_list;
|
||||
extern uint32 numzones;
|
||||
extern LoginServerList loginserverlist;
|
||||
extern LauncherList launcher_list;
|
||||
extern volatile bool RunLoops;
|
||||
|
||||
|
||||
|
||||
|
||||
EQW EQW::s_EQW;
|
||||
|
||||
//IO Capture routine
|
||||
XS(XS_EQWIO_PRINT); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQWIO_PRINT)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 2)
|
||||
return;
|
||||
|
||||
int r;
|
||||
for(r = 1; r < items; r++) {
|
||||
char *str = SvPV_nolen(ST(r));
|
||||
EQW::Singleton()->AppendOutput(str);
|
||||
}
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
EQW::EQW() {
|
||||
}
|
||||
|
||||
void EQW::AppendOutput(const char *str) {
|
||||
m_outputBuffer += str;
|
||||
// _log(WORLD__EQW, "Append %d chars, yeilding result of length %d", strlen(str), m_outputBuffer.length());
|
||||
}
|
||||
|
||||
const std::string &EQW::GetOutput() const {
|
||||
// _log(WORLD__EQW, "Getting, length %d", m_outputBuffer.length());
|
||||
return(m_outputBuffer);
|
||||
}
|
||||
|
||||
void EQW::LockWorld() {
|
||||
WorldConfig::LockWorld();
|
||||
if (loginserverlist.Connected()) {
|
||||
loginserverlist.SendStatus();
|
||||
}
|
||||
}
|
||||
|
||||
void EQW::UnlockWorld() {
|
||||
WorldConfig::UnlockWorld();
|
||||
if (loginserverlist.Connected()) {
|
||||
loginserverlist.SendStatus();
|
||||
}
|
||||
}
|
||||
|
||||
Const_char *EQW::GetConfig(Const_char *var_name) {
|
||||
m_returnBuffer = WorldConfig::get()->GetByName(var_name);
|
||||
return(m_returnBuffer.c_str());
|
||||
}
|
||||
|
||||
bool EQW::LSConnected() {
|
||||
return(loginserverlist.Connected());
|
||||
}
|
||||
|
||||
int EQW::CountZones() {
|
||||
return(zoneserver_list.GetZoneCount());
|
||||
}
|
||||
|
||||
//returns an array of zone_refs (opaque)
|
||||
vector<string> EQW::ListBootedZones() {
|
||||
vector<string> res;
|
||||
|
||||
vector<uint32> zones;
|
||||
zoneserver_list.GetZoneIDList(zones);
|
||||
|
||||
vector<uint32>::iterator cur, end;
|
||||
cur = zones.begin();
|
||||
end = zones.end();
|
||||
for(; cur != end; cur++) {
|
||||
res.push_back(itoa(*cur));
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
map<string,string> EQW::GetZoneDetails(Const_char *zone_ref) {
|
||||
map<string,string> res;
|
||||
|
||||
ZoneServer *zs = zoneserver_list.FindByID(atoi(zone_ref));
|
||||
if(zs == NULL) {
|
||||
res["error"] = "Invalid zone.";
|
||||
return(res);
|
||||
}
|
||||
|
||||
res["type"] = zs->IsStaticZone()?"static":"dynamic";
|
||||
res["zone_id"] = itoa(zs->GetZoneID());
|
||||
res["launch_name"] = zs->GetLaunchName();
|
||||
res["launched_name"] = zs->GetLaunchedName();
|
||||
res["short_name"] = zs->GetZoneName();
|
||||
res["long_name"] = zs->GetZoneLongName();
|
||||
res["port"] = itoa(zs->GetCPort());
|
||||
res["player_count"] = itoa(zs->NumPlayers());
|
||||
|
||||
//this isnt gunna work for dynamic zones...
|
||||
res["launcher"] = "";
|
||||
if(zs->GetZoneID() != 0) {
|
||||
LauncherLink *ll = launcher_list.FindByZone(zs->GetLaunchName());
|
||||
if(ll != NULL)
|
||||
res["launcher"] = ll->GetName();
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
int EQW::CountPlayers() {
|
||||
return(client_list.GetClientCount());
|
||||
}
|
||||
|
||||
//returns an array of character names in the zone (empty=all zones)
|
||||
vector<string> EQW::ListPlayers(Const_char *zone_name) {
|
||||
vector<string> res;
|
||||
|
||||
vector<ClientListEntry *> list;
|
||||
client_list.GetClients(zone_name, list);
|
||||
|
||||
vector<ClientListEntry *>::iterator cur, end;
|
||||
cur = list.begin();
|
||||
end = list.end();
|
||||
for(; cur != end; cur++) {
|
||||
res.push_back((*cur)->name());
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
map<string,string> EQW::GetPlayerDetails(Const_char *char_name) {
|
||||
map<string,string> res;
|
||||
|
||||
ClientListEntry *cle = client_list.FindCharacter(char_name);
|
||||
if(cle == NULL) {
|
||||
res["error"] = "1";
|
||||
return(res);
|
||||
}
|
||||
|
||||
res["character"] = cle->name();
|
||||
res["account"] = cle->AccountName();
|
||||
res["account_id"] = itoa(cle->AccountID());
|
||||
res["location_short"] = cle->zone()?database.GetZoneName(cle->zone()):"No Zone";
|
||||
res["location_long"] = res["location_short"];
|
||||
res["location_id"] = itoa(cle->zone());
|
||||
res["ip"] = long2ip(cle->GetIP());
|
||||
res["level"] = itoa(cle->level());
|
||||
res["race"] = GetRaceName(cle->race());
|
||||
res["race_id"] = itoa(cle->race());
|
||||
res["class"] = GetEQClassName(cle->class_());
|
||||
res["class_id"] = itoa(cle->class_());
|
||||
res["guild_id"] = itoa(cle->GuildID());
|
||||
res["guild"] = guild_mgr.GetGuildName(cle->GuildID());
|
||||
res["status"] = itoa(cle->Admin());
|
||||
// res["patch"] = cle->DescribePatch();
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
int EQW::CountLaunchers(bool active_only) {
|
||||
if(active_only)
|
||||
return(launcher_list.GetLauncherCount());
|
||||
|
||||
vector<string> it(EQW::ListLaunchers());
|
||||
return(it.size());
|
||||
}
|
||||
/*
|
||||
vector<string> EQW::ListActiveLaunchers() {
|
||||
vector<string> launchers;
|
||||
launcher_list.GetLauncherNameList(launchers);
|
||||
return(launchers);
|
||||
}*/
|
||||
|
||||
vector<string> EQW::ListLaunchers() {
|
||||
// vector<string> list;
|
||||
// database.GetLauncherList(list);
|
||||
vector<string> launchers;
|
||||
launcher_list.GetLauncherNameList(launchers);
|
||||
return(launchers);
|
||||
|
||||
/* if(list.empty()) {
|
||||
return(launchers);
|
||||
} else if(launchers.empty()) {
|
||||
return(list);
|
||||
}
|
||||
|
||||
//union the two lists.
|
||||
vector<string>::iterator curo, endo, curi, endi;
|
||||
curo = list.begin();
|
||||
endo = list.end();
|
||||
for(; curo != endo; curo++) {
|
||||
bool found = false;
|
||||
curi = launchers.begin();
|
||||
endi = launchers.end();
|
||||
for(; curi != endi; curi++) {
|
||||
if(*curo == *curi) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
break;
|
||||
launchers.push_back(*curo);
|
||||
}
|
||||
return(launchers);*/
|
||||
}
|
||||
|
||||
EQLConfig * EQW::GetLauncher(Const_char *launcher_name) {
|
||||
return(launcher_list.GetConfig(launcher_name));
|
||||
}
|
||||
|
||||
void EQW::CreateLauncher(Const_char *launcher_name, int dynamic_count) {
|
||||
launcher_list.CreateLauncher(launcher_name, dynamic_count);
|
||||
}
|
||||
|
||||
void EQW::LSReconnect() {
|
||||
#ifdef _WINDOWS
|
||||
_beginthread(AutoInitLoginServer, 0, NULL);
|
||||
#else
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, &AutoInitLoginServer, NULL);
|
||||
#endif
|
||||
RunLoops = true;
|
||||
_log(WORLD__CONSOLE,"Login Server Reconnect manually restarted by Web Tool");
|
||||
}
|
||||
|
||||
/*EQLConfig * EQW::FindLauncher(Const_char *zone_ref) {
|
||||
return(NULL);
|
||||
}*/
|
||||
|
||||
/*
|
||||
map<string,string> EQW::GetLaunchersDetails(Const_char *launcher_name) {
|
||||
map<string,string> res;
|
||||
|
||||
LauncherLink *ll = launcher_list.Get(launcher_name);
|
||||
if(ll == NULL) {
|
||||
res["name"] = launcher_name;
|
||||
res["ip"] = "Not Connected";
|
||||
res["id"] = "0";
|
||||
res["zone_count"] = "0";
|
||||
res["connected"] = "no";
|
||||
return(res);
|
||||
} else {
|
||||
res["name"] = ll->GetName();
|
||||
res["ip"] = long2ip(ll->GetIP());
|
||||
res["id"] = itoa(ll->GetID());
|
||||
res["zone_count"] = itoa(ll->CountZones());
|
||||
res["connected"] = "yes";
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
vector<string> EQW::ListLauncherZones(Const_char *launcher_name) {
|
||||
vector<string> list;
|
||||
LauncherLink *ll = launcher_list.Get(launcher_name);
|
||||
if(ll != NULL) {
|
||||
ll->GetZoneList(list);
|
||||
}
|
||||
return(list);
|
||||
}
|
||||
|
||||
map<string,string> EQW::GetLauncherZoneDetails(Const_char *launcher_name, Const_char *zone_ref) {
|
||||
map<string,string> res;
|
||||
LauncherLink *ll = launcher_list.Get(launcher_name);
|
||||
if(ll != NULL) {
|
||||
ll->GetZoneDetails(zone_ref, res);
|
||||
} else {
|
||||
res["error"] = "Launcher Not Found";
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
void EQW::CreateLauncher(Const_char *launcher_name, int dynamic_count) {
|
||||
}
|
||||
|
||||
bool EQW::BootStaticZone(Const_char *launcher_name, Const_char *short_name) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool EQW::DeleteStaticZone(Const_char *launcher_name, Const_char *short_name) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool EQW::SetDynamicCount(Const_char *launcher_name, int count) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
int EQW::GetDynamicCount(Const_char *launcher_name) {
|
||||
return(0);
|
||||
}
|
||||
*/
|
||||
|
||||
uint32 EQW::CreateGuild(const char* name, uint32 leader_char_id) {
|
||||
uint32 id = guild_mgr.CreateGuild(name, leader_char_id);
|
||||
if(id != GUILD_NONE)
|
||||
client_list.UpdateClientGuild(leader_char_id, id);
|
||||
return(id);
|
||||
}
|
||||
|
||||
bool EQW::DeleteGuild(uint32 guild_id) {
|
||||
return(guild_mgr.DeleteGuild(guild_id));
|
||||
}
|
||||
|
||||
bool EQW::RenameGuild(uint32 guild_id, const char* name) {
|
||||
return(guild_mgr.RenameGuild(guild_id, name));
|
||||
}
|
||||
|
||||
bool EQW::SetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
|
||||
return(guild_mgr.SetGuildMOTD(guild_id, motd, setter));
|
||||
}
|
||||
|
||||
bool EQW::SetGuildLeader(uint32 guild_id, uint32 leader_char_id) {
|
||||
return(guild_mgr.SetGuildLeader(guild_id, leader_char_id));
|
||||
}
|
||||
|
||||
bool EQW::SetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
||||
client_list.UpdateClientGuild(charid, guild_id);
|
||||
return(guild_mgr.SetGuild(charid, guild_id, rank));
|
||||
}
|
||||
|
||||
bool EQW::SetGuildRank(uint32 charid, uint8 rank) {
|
||||
return(guild_mgr.SetGuildRank(charid, rank));
|
||||
}
|
||||
|
||||
bool EQW::SetBankerFlag(uint32 charid, bool is_banker) {
|
||||
return(guild_mgr.SetBankerFlag(charid, is_banker));
|
||||
}
|
||||
|
||||
bool EQW::SetTributeFlag(uint32 charid, bool enabled) {
|
||||
return(guild_mgr.SetTributeFlag(charid, enabled));
|
||||
}
|
||||
|
||||
bool EQW::SetPublicNote(uint32 charid, const char *note) {
|
||||
return(guild_mgr.SetPublicNote(charid, note));
|
||||
}
|
||||
|
||||
int EQW::CountBugs() {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
if(database.RunQuery(query, MakeAnyLenString(&query, "SELECT count(*) FROM bugs where status = 0"), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
if((row = mysql_fetch_row(result))) {
|
||||
int count = atoi(row[0]);
|
||||
mysql_free_result(result);
|
||||
return count;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
return 0;
|
||||
}
|
||||
|
||||
vector<string> EQW::ListBugs(uint32 offset) {
|
||||
vector<string> res;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
if(database.RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM bugs WHERE status = 0 limit %d, 30", offset), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while((row = mysql_fetch_row(result))) {
|
||||
res.push_back(row[0]);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
map<string,string> EQW::GetBugDetails(Const_char *id) {
|
||||
map<string,string> res;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
if(database.RunQuery(query, MakeAnyLenString(&query, "select name, zone, x, y, z, target, bug from bugs where id = %s", id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while((row = mysql_fetch_row(result))) {
|
||||
res["name"] = row[0];
|
||||
res["zone"] = row[1];
|
||||
res["x"] = row[2];
|
||||
res["y"] = row[3];
|
||||
res["z"] = row[4];
|
||||
res["target"] = row[5];
|
||||
res["bug"] = row[6];
|
||||
res["id"] = id;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
void EQW::ResolveBug(const char *id) {
|
||||
vector<string> res;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_ROW row;
|
||||
if(database.RunQuery(query, MakeAnyLenString(&query, "UPDATE bugs SET status=1 WHERE id=%s", id), errbuf)) {
|
||||
safe_delete_array(query);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
}
|
||||
|
||||
|
||||
#endif //EMBPERL
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef EQW_H_
|
||||
#define EQW_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "../common/types.h"
|
||||
using namespace std;
|
||||
|
||||
class EQLConfig;
|
||||
|
||||
//this is the main object exported to perl.
|
||||
class EQW {
|
||||
EQW();
|
||||
public:
|
||||
static EQW *Singleton() { return(&s_EQW); }
|
||||
|
||||
void AppendOutput(const char *str);
|
||||
const std::string &GetOutput() const;
|
||||
void ClearOutput() { m_outputBuffer = ""; }
|
||||
|
||||
//BEGIN PERL EXPORT
|
||||
//NOTE: you must have a space after the * of a return value
|
||||
Const_char * GetConfig(Const_char *var_name);
|
||||
void LockWorld();
|
||||
void UnlockWorld();
|
||||
|
||||
bool LSConnected();
|
||||
void LSReconnect();
|
||||
|
||||
int CountZones();
|
||||
vector<string> ListBootedZones(); //returns an array of zone_refs (opaque)
|
||||
map<string,string> GetZoneDetails(Const_char *zone_ref); //returns a hash ref of details
|
||||
|
||||
int CountPlayers();
|
||||
vector<string> ListPlayers(Const_char *zone_name = ""); //returns an array of player refs (opaque)
|
||||
map<string,string> GetPlayerDetails(Const_char *player_ref); //returns a hash ref of details
|
||||
|
||||
int CountLaunchers(bool active_only);
|
||||
// vector<string> ListActiveLaunchers(); //returns an array of launcher names
|
||||
vector<string> ListLaunchers(); //returns an array of launcher names
|
||||
EQLConfig * GetLauncher(Const_char *launcher_name); //returns the EQLConfig object for the specified launcher.
|
||||
void CreateLauncher(Const_char *launcher_name, int dynamic_count);
|
||||
// EQLConfig * FindLauncher(Const_char *zone_ref);
|
||||
|
||||
//Guild routines, mostly wrappers around guild_mgr
|
||||
uint32 CreateGuild(const char* name, uint32 leader_char_id);
|
||||
bool DeleteGuild(uint32 guild_id);
|
||||
bool RenameGuild(uint32 guild_id, const char* name);
|
||||
bool SetGuildMOTD(uint32 guild_id, const char* motd, const char *setter);
|
||||
bool SetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||
bool SetGuild(uint32 charid, uint32 guild_id, uint8 rank);
|
||||
bool SetGuildRank(uint32 charid, uint8 rank);
|
||||
bool SetBankerFlag(uint32 charid, bool is_banker);
|
||||
bool SetTributeFlag(uint32 charid, bool enabled);
|
||||
bool SetPublicNote(uint32 charid, const char *note);
|
||||
|
||||
//bugs
|
||||
int CountBugs();
|
||||
vector<string> ListBugs(uint32 offset); //returns an array of zone_refs (opaque)
|
||||
map<string,string> GetBugDetails(const char *id);
|
||||
void ResolveBug(const char *id);
|
||||
|
||||
//END PERL EXPORT
|
||||
|
||||
protected:
|
||||
std::string m_outputBuffer;
|
||||
std::string m_returnBuffer;
|
||||
|
||||
bool m_worldLocked;
|
||||
|
||||
private:
|
||||
static EQW s_EQW;
|
||||
};
|
||||
|
||||
#endif /*EQW_H_*/
|
||||
@@ -0,0 +1,340 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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/debug.h"
|
||||
#include "EQWHTTPHandler.h"
|
||||
#include "../common/SocketLib/Base64.h"
|
||||
#include "EQWParser.h"
|
||||
#include "EQW.h"
|
||||
#include "HTTPRequest.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "worlddb.h"
|
||||
#include "console.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Mime EQWHTTPHandler::s_mime;
|
||||
#ifdef EMBPERL
|
||||
EQWParser *EQWHTTPHandler::s_parser = NULL;
|
||||
#endif
|
||||
const int EQWHTTPHandler::READ_BUFFER_LEN = 1024; //for page IO, was a static const member, but VC6 got mad.
|
||||
|
||||
EQWHTTPHandler::EQWHTTPHandler(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort)
|
||||
: HttpdSocket(ID,in_socket,irIP,irPort),
|
||||
m_closeOnFinish(false)
|
||||
{
|
||||
}
|
||||
|
||||
EQWHTTPHandler::~EQWHTTPHandler() {
|
||||
|
||||
}
|
||||
|
||||
#ifdef EMBPERL
|
||||
EQWParser *EQWHTTPHandler::GetParser() {
|
||||
if(s_parser == NULL) {
|
||||
EQW::Singleton()->ClearOutput();
|
||||
s_parser = new EQWParser();
|
||||
const string &res = EQW::Singleton()->GetOutput();
|
||||
if(!res.empty()) {
|
||||
printf("EQWParser Init output:\n%s\n\n", res.c_str());
|
||||
EQW::Singleton()->ClearOutput();
|
||||
}
|
||||
}
|
||||
return(s_parser);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*void EQWHTTPHandler::OnWrite() {
|
||||
HttpdSocket::OnWrite();
|
||||
if(m_closeOnFinish && GetOutputLength() == 0) {
|
||||
// printf("CLOSING\n");
|
||||
Close();
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
void EQWHTTPHandler::Exec() {
|
||||
m_sentHeaders = false;
|
||||
m_responseCode = "200";
|
||||
// printf("Request: %s, %s, %s, %s.\n", GetMethod().c_str(), GetUrl().c_str(), GetUri().c_str(), GetQueryString().c_str());
|
||||
|
||||
SetHttpVersion("HTTP/1.0");
|
||||
AddResponseHeader("Connection", "close");
|
||||
|
||||
if(GetUri().find("..") != string::npos) {
|
||||
SendResponse("403", "Forbidden");
|
||||
printf("%s is forbidden.\n", GetUri().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!CheckAuth()) {
|
||||
AddResponseHeader("Content-type", "text/plain");
|
||||
AddResponseHeader("WWW-Authenticate", "Basic realm=\"EQEmulator\"");
|
||||
SendResponse("401", "Authorization Required");
|
||||
SendString("Gotta Authenticate.");
|
||||
} else {
|
||||
string::size_type start = GetUri().find_first_not_of('/');
|
||||
string page;
|
||||
if(start != string::npos)
|
||||
page = GetUri().substr(start);
|
||||
else
|
||||
page = "index.html";
|
||||
SendPage(page);
|
||||
}
|
||||
/* if (!Detach()) {
|
||||
printf("Unable to detach...\n");
|
||||
}
|
||||
if(GetOutputLength() > 0) {
|
||||
//we cannot close yet
|
||||
m_closeOnFinish = true;
|
||||
} else {
|
||||
Close();
|
||||
}*/
|
||||
Free(); //the "app" side (us) is done with this connection too...
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
void EQWHTTPHandler::OnHeader(const std::string& key,const std::string& value) {
|
||||
HttpdSocket::OnHeader(key, value);
|
||||
|
||||
if (!strcasecmp(key.c_str(),"Authorization")) {
|
||||
if(strncasecmp(value.c_str(), "Basic ", 6)) {
|
||||
printf("Invalid auth type. Expected Basic: %s\n", value.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string dec;
|
||||
Base64::decode(value.c_str() + 6, dec);
|
||||
|
||||
std::string::size_type cpos;
|
||||
cpos = dec.find_first_of(':');
|
||||
if(cpos == string::npos) {
|
||||
printf("Invalid auth string: %s\n", dec.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_username = dec.substr(0, cpos);
|
||||
m_password = dec.substr(cpos+1);
|
||||
}
|
||||
}
|
||||
|
||||
//we should prolly cache login info here... if we load a fresh page, we could be checking
|
||||
//their auth dozens of times rather quickly...
|
||||
bool EQWHTTPHandler::CheckAuth() const {
|
||||
if(m_username.length() < 1)
|
||||
return(false);
|
||||
|
||||
int16 status = 0;
|
||||
uint32 acctid = database.CheckLogin(m_username.c_str(), m_password.c_str(), &status);
|
||||
if(acctid == 0) {
|
||||
_log(WORLD__HTTP_ERR, "Login autentication failed for %s with '%s'", m_username.c_str(), m_password.c_str());
|
||||
return(false);
|
||||
}
|
||||
if(status < httpLoginStatus) {
|
||||
_log(WORLD__HTTP_ERR, "Login of %s failed: status too low.", m_username.c_str());
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void EQWHTTPHandler::SendPage(const std::string &file) {
|
||||
|
||||
string path = "templates/";
|
||||
path += file;
|
||||
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if(f == NULL) {
|
||||
SendResponse("404", "Not Found");
|
||||
SendString("Not found.");
|
||||
printf("%s not found.\n", file.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
string type = s_mime.GetMimeFromFilename(file);
|
||||
AddResponseHeader("Content-type", type);
|
||||
|
||||
bool process = false;
|
||||
#ifdef EMBPERL
|
||||
if(type == "text/html")
|
||||
process = true;
|
||||
else {
|
||||
//not processing, send headers right away
|
||||
#endif
|
||||
SendResponse("200", "OK");
|
||||
#ifdef EMBPERL
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
char *buffer = new char[READ_BUFFER_LEN+1];
|
||||
size_t len;
|
||||
string to_process;
|
||||
while((len = fread(buffer, 1, READ_BUFFER_LEN, f)) > 0) {
|
||||
buffer[len] = '\0';
|
||||
if(process)
|
||||
to_process += buffer;
|
||||
else
|
||||
SendBuf(buffer, len);
|
||||
}
|
||||
delete[] buffer;
|
||||
fclose(f);
|
||||
#ifdef EMBPERL
|
||||
if(process) {
|
||||
//convert the base form into a useful perl exportable form
|
||||
HTTPRequest req(this, GetHttpForm());
|
||||
GetParser()->SetHTTPRequest("testing", &req);
|
||||
|
||||
//parse out the page and potentially pass some stuff on to perl.
|
||||
ProcessAndSend(to_process);
|
||||
|
||||
//clear out the form, just in case (since it gets destroyed next)
|
||||
GetParser()->SetHTTPRequest("testing", NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool EQWHTTPHandler::LoadMimeTypes(const char *filename) {
|
||||
return(s_mime.LoadMimeFile(filename));
|
||||
}
|
||||
|
||||
#ifdef EMBPERL
|
||||
void EQWHTTPHandler::ProcessAndSend(const string &str) {
|
||||
string::size_type len = str.length();
|
||||
string::size_type start = 0;
|
||||
string::size_type pos, end;
|
||||
|
||||
while((pos = str.find("<?", start)) != string::npos) {
|
||||
//send all the crap leading up to the script block
|
||||
if(pos != start) {
|
||||
ProcessText(str.c_str() + start, pos-start);
|
||||
}
|
||||
|
||||
//look for the end of this script block...
|
||||
end = str.find("?>", pos+2);
|
||||
if(end == string::npos) {
|
||||
//terminal ?> not found... should issue a warning or something...
|
||||
string scriptBody = str.substr(pos+2);
|
||||
ProcessScript(scriptBody);
|
||||
start = len;
|
||||
break;
|
||||
} else {
|
||||
//script only consumes some of this buffer...
|
||||
string scriptBody = str.substr(pos+2, end-pos-2);
|
||||
ProcessScript(scriptBody);
|
||||
start = end + 2;
|
||||
}
|
||||
}
|
||||
|
||||
//send whatever is left over
|
||||
if(start != len)
|
||||
ProcessText(str.c_str() + start, len-start);
|
||||
}
|
||||
|
||||
void EQWHTTPHandler::ProcessScript(const std::string &script_body) {
|
||||
const char *script = script_body.c_str();
|
||||
if(strcmp("perl", script) == 0)
|
||||
script += 4; //allow <?perl
|
||||
|
||||
// printf("Script: ''''%s''''\n\n", script_body.c_str());
|
||||
|
||||
GetParser()->EQW_eval("testing", script_body.c_str());
|
||||
const string &res = EQW::Singleton()->GetOutput();
|
||||
if(!res.empty()) {
|
||||
ProcessText(res.c_str(), res.length());
|
||||
EQW::Singleton()->ClearOutput();
|
||||
}
|
||||
}
|
||||
|
||||
void EQWHTTPHandler::ProcessText(const char *txt, int len) {
|
||||
if(!m_sentHeaders) {
|
||||
SendResponse(m_responseCode, "OK");
|
||||
m_sentHeaders = true;
|
||||
}
|
||||
SendBuf(txt, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
EQWHTTPServer::EQWHTTPServer()
|
||||
: m_port(0)
|
||||
{
|
||||
}
|
||||
|
||||
void EQWHTTPServer::CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort) {
|
||||
EQWHTTPHandler *conn = new EQWHTTPHandler(ID, in_socket, irIP, irPort);
|
||||
AddConnection(conn);
|
||||
}
|
||||
|
||||
void EQWHTTPServer::Stop() {
|
||||
_log(WORLD__HTTP, "Requesting that HTTP Service stop.");
|
||||
m_running = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
bool EQWHTTPServer::Start(uint16 port, const char *mime_file) {
|
||||
if(m_running) {
|
||||
_log(WORLD__HTTP_ERR, "HTTP Service is already running on port %d", m_port);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//load up our nice mime types
|
||||
if(!EQWHTTPHandler::LoadMimeTypes(mime_file)) {
|
||||
_log(WORLD__HTTP_ERR, "Failed to load mime types from '%s'", mime_file);
|
||||
return(false);
|
||||
} else {
|
||||
_log(WORLD__HTTP, "Loaded mime types from %s", mime_file);
|
||||
}
|
||||
|
||||
//fire up the server thread
|
||||
char errbuf[TCPServer_ErrorBufferSize];
|
||||
if(!Open(port, errbuf)) {
|
||||
_log(WORLD__HTTP_ERR, "Unable to bind to port %d for HTTP service: %s", port, errbuf);
|
||||
return(false);
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
m_port = port;
|
||||
|
||||
/*
|
||||
|
||||
#ifdef _WINDOWS
|
||||
_beginthread(ThreadProc, 0, this);
|
||||
#else
|
||||
pthread_create(&m_thread, NULL, ThreadProc, this);
|
||||
#endif*/
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/*
|
||||
void EQWHTTPServer::Run() {
|
||||
_log(WORLD__HTTP, "HTTP Processing thread started on port %d", m_port);
|
||||
do {
|
||||
#warning DELETE THIS IF YOU DONT USE IT
|
||||
Sleep(10);
|
||||
} while(m_running);
|
||||
_log(WORLD__HTTP, "HTTP Processing thread terminating on port %d", m_port);
|
||||
}
|
||||
|
||||
ThreadReturnType EQWHTTPServer::ThreadProc(void *data) {
|
||||
((EQWHTTPServer *) data)->Run();
|
||||
THREAD_RETURN(NULL);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef EQWHTTPHandler_H
|
||||
#define EQWHTTPHandler_H
|
||||
|
||||
#include "../common/TCPServer.h"
|
||||
#include "../common/TCPConnection.h"
|
||||
#include "../common/SocketLib/HttpdSocket.h"
|
||||
#include "../common/SocketLib/Mime.h"
|
||||
#include "../common/types.h"
|
||||
|
||||
class EQWParser;
|
||||
|
||||
class EQWHTTPHandler : public HttpdSocket {
|
||||
static const int READ_BUFFER_LEN;
|
||||
public:
|
||||
EQWHTTPHandler(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort);
|
||||
virtual ~EQWHTTPHandler();
|
||||
|
||||
void SetResponseCode(const char *code) { m_responseCode = code; }
|
||||
|
||||
//HttpdSocket interface:
|
||||
virtual void Exec();
|
||||
virtual void OnHeader(const std::string& key,const std::string& value);
|
||||
|
||||
static bool LoadMimeTypes(const char *filename);
|
||||
protected:
|
||||
bool CheckAuth() const;
|
||||
void SendPage(const std::string &file);
|
||||
|
||||
//credentials
|
||||
std::string m_username;
|
||||
std::string m_password;
|
||||
|
||||
bool m_closeOnFinish;
|
||||
std::string m_responseCode;
|
||||
bool m_sentHeaders;
|
||||
|
||||
|
||||
//our mime type manager
|
||||
static Mime s_mime;
|
||||
|
||||
|
||||
#ifdef EMBPERL
|
||||
void ProcessAndSend(const std::string &entire_html_page);
|
||||
void ProcessScript(const std::string &script_body);
|
||||
void ProcessText(const char *txt, int len);
|
||||
|
||||
static EQWParser *GetParser();
|
||||
|
||||
private:
|
||||
static EQWParser *s_parser;
|
||||
#endif
|
||||
};
|
||||
|
||||
class EQWHTTPServer : protected TCPServer<EQWHTTPHandler> {
|
||||
public:
|
||||
EQWHTTPServer();
|
||||
|
||||
bool Start(uint16 port, const char *mime_file);
|
||||
void Stop();
|
||||
|
||||
|
||||
protected:
|
||||
volatile bool m_running;
|
||||
uint16 m_port;
|
||||
|
||||
virtual void CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort);
|
||||
|
||||
/* //I decided to put this into its own thread so that the HTTP pages
|
||||
//cannot block the main world server's operation.
|
||||
static ThreadReturnType ThreadProc(void* tmp);
|
||||
void Run();
|
||||
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
pthread_t m_thread;
|
||||
#endif*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
|
||||
//a lot of this is copied from embperl.cpp, but I didnt feel like factoring the common stuff out
|
||||
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "EQWParser.h"
|
||||
#include "EQW.h"
|
||||
#include "../common/EQDB.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "worlddb.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef GvCV_set
|
||||
#define GvCV_set(gv,cv) (GvCV(gv) = (cv))
|
||||
#endif
|
||||
|
||||
|
||||
XS(XS_EQWIO_PRINT);
|
||||
|
||||
//so embedded scripts can use xs extensions (ala 'use socket;')
|
||||
EXTERN_C void boot_DynaLoader(pTHX_ CV* cv);
|
||||
EXTERN_C XS(boot_EQW);
|
||||
EXTERN_C XS(boot_EQDB);
|
||||
EXTERN_C XS(boot_EQDBRes);
|
||||
EXTERN_C XS(boot_HTTPRequest);
|
||||
EXTERN_C XS(boot_EQLConfig);
|
||||
|
||||
EXTERN_C void xs_init(pTHX)
|
||||
{
|
||||
char file[256];
|
||||
strncpy(file, __FILE__, 256);
|
||||
file[255] = '\0';
|
||||
|
||||
char buf[128]; //shouldent have any function names longer than this.
|
||||
|
||||
//add the strcpy stuff to get rid of const warnings....
|
||||
|
||||
newXS(strcpy(buf, "DynaLoader::boot_DynaLoader"), boot_DynaLoader, file);
|
||||
newXS(strcpy(buf, "EQW::boot_EQW"), boot_EQW, file);
|
||||
newXS(strcpy(buf, "EQDB::boot_EQDB"), boot_EQDB, file);
|
||||
newXS(strcpy(buf, "EQDBRes::boot_EQDBRes"), boot_EQDBRes, file);
|
||||
newXS(strcpy(buf, "HTTPRequest::boot_HTTPRequest"), boot_HTTPRequest, file);
|
||||
newXS(strcpy(buf, "EQLConfig::boot_EQLConfig"), boot_EQLConfig, file);
|
||||
newXS(strcpy(buf, "EQWIO::PRINT"), XS_EQWIO_PRINT, file);
|
||||
}
|
||||
|
||||
EQWParser::EQWParser() {
|
||||
//setup perl...
|
||||
my_perl = perl_alloc();
|
||||
_empty_sv = newSV(0);
|
||||
if(!my_perl)
|
||||
_log(WORLD__PERL_ERR, "Error: perl_alloc failed!");
|
||||
else
|
||||
DoInit();
|
||||
}
|
||||
|
||||
void EQWParser::DoInit() {
|
||||
const char *argv_eqemu[] = { "",
|
||||
"-w", "-W",
|
||||
"-e", "0;", NULL };
|
||||
|
||||
int argc = 5;
|
||||
|
||||
char **argv = (char **)argv_eqemu;
|
||||
char **env = { NULL };
|
||||
|
||||
PL_perl_destruct_level = 1;
|
||||
|
||||
perl_construct(my_perl);
|
||||
|
||||
PERL_SYS_INIT3(&argc, &argv, &env);
|
||||
|
||||
perl_parse(my_perl, xs_init, argc, argv, env);
|
||||
|
||||
perl_run(my_perl);
|
||||
|
||||
//a little routine we use a lot.
|
||||
eval_pv("sub my_eval {eval $_[0];}", TRUE); //dies on error
|
||||
|
||||
//ruin the perl exit and command:
|
||||
eval_pv("sub my_exit {}",TRUE);
|
||||
eval_pv("sub my_sleep {}",TRUE);
|
||||
if(gv_stashpv("CORE::GLOBAL", FALSE)) {
|
||||
GV *exitgp = gv_fetchpv("CORE::GLOBAL::exit", TRUE, SVt_PVCV);
|
||||
GvCV_set(exitgp, perl_get_cv("my_exit", TRUE)); //dies on error
|
||||
GvIMPORTED_CV_on(exitgp);
|
||||
GV *sleepgp = gv_fetchpv("CORE::GLOBAL::sleep", TRUE, SVt_PVCV);
|
||||
GvCV_set(sleepgp, perl_get_cv("my_sleep", TRUE)); //dies on error
|
||||
GvIMPORTED_CV_on(sleepgp);
|
||||
}
|
||||
|
||||
//setup eval_file
|
||||
eval_pv(
|
||||
"our %Cache;"
|
||||
"use Symbol qw(delete_package);"
|
||||
"sub eval_file {"
|
||||
"my($package, $filename) = @_;"
|
||||
"$filename=~s/\'//g;"
|
||||
"if(! -r $filename) { print \"Unable to read perl file '$filename'\\n\"; return; }"
|
||||
"my $mtime = -M $filename;"
|
||||
"if(defined $Cache{$package}{mtime}&&$Cache{$package}{mtime} <= $mtime && !($package eq 'plugin')){"
|
||||
" return;"
|
||||
"} else {"
|
||||
//we 'my' $filename,$mtime,$package,$sub to prevent them from changing our state up here.
|
||||
" eval(\"package $package; my(\\$filename,\\$mtime,\\$package,\\$sub); \\$isloaded = 1; require '$filename'; \");"
|
||||
"}"
|
||||
"}"
|
||||
,FALSE);
|
||||
|
||||
//make a tie-able class to capture IO and get it where it needs to go
|
||||
eval_pv(
|
||||
"package EQWIO; "
|
||||
// "&boot_EQEmuIO;"
|
||||
"sub TIEHANDLE { my $me = bless {}, $_[0]; $me->PRINT('Creating '.$me); return($me); } "
|
||||
"sub WRITE { } "
|
||||
"sub PRINTF { my $me = shift; my $fmt = shift; $me->PRINT(sprintf($fmt, @_)); } "
|
||||
"sub CLOSE { my $me = shift; $me->PRINT('Closing '.$me); } "
|
||||
"sub DESTROY { my $me = shift; $me->PRINT('Destroying '.$me); } "
|
||||
//this ties us for all packages
|
||||
"package MAIN;"
|
||||
" if(tied *STDOUT) { untie(*STDOUT); }"
|
||||
" if(tied *STDERR) { untie(*STDERR); }"
|
||||
" tie *STDOUT, 'EQWIO';"
|
||||
" tie *STDERR, 'EQWIO';"
|
||||
,FALSE);
|
||||
|
||||
eval_pv(
|
||||
"package world; "
|
||||
,FALSE
|
||||
);
|
||||
|
||||
//make sure the EQW pointer is set up in this package
|
||||
EQW *curc = EQW::Singleton();
|
||||
SV *l = get_sv("world::EQW", true);
|
||||
if(curc != NULL) {
|
||||
sv_setref_pv(l, "EQW", curc);
|
||||
} else {
|
||||
//clear out the value, mainly to get rid of blessedness
|
||||
sv_setsv(l, _empty_sv);
|
||||
}
|
||||
|
||||
//make sure the EQDB pointer is set up in this package
|
||||
EQDB::SetMySQL(database.getMySQL());
|
||||
EQDB *curc_db = EQDB::Singleton();
|
||||
SV *l_db = get_sv("world::EQDB", true);
|
||||
if(curc_db != NULL) {
|
||||
sv_setref_pv(l_db, "EQDB", curc_db);
|
||||
} else {
|
||||
//clear out the value, mainly to get rid of blessedness
|
||||
sv_setsv(l_db, _empty_sv);
|
||||
}
|
||||
|
||||
//load up EQW
|
||||
eval_pv(
|
||||
"package EQW;"
|
||||
"&boot_EQW;" //load our EQW XS
|
||||
"package EQDB;"
|
||||
"&boot_EQDB;" //load our EQW XS
|
||||
"package EQDBRes;"
|
||||
"&boot_EQDBRes;" //load our EQW XS
|
||||
"package HTTPRequest;"
|
||||
"&boot_HTTPRequest;" //load our HTTPRequest XS
|
||||
"package EQLConfig;"
|
||||
"&boot_EQLConfig;" //load our EQLConfig XS
|
||||
, FALSE );
|
||||
|
||||
|
||||
#ifdef EMBPERL_PLUGIN
|
||||
_log(WORLD__PERL, "Loading worldui perl plugins.");
|
||||
string err;
|
||||
if(!eval_file("world", "worldui.pl", err)) {
|
||||
_log(WORLD__PERL_ERR, "Warning - world.pl: %s", err.c_str());
|
||||
}
|
||||
|
||||
eval_pv(
|
||||
"package world; "
|
||||
"if(opendir(D,'worldui')) { "
|
||||
" my @d = readdir(D);"
|
||||
" closedir(D);"
|
||||
" foreach(@d){ "
|
||||
" next unless(/\\.pl$); "
|
||||
" require 'templates/'.$_;"
|
||||
" }"
|
||||
"}"
|
||||
,FALSE);
|
||||
#endif //EMBPERL_PLUGIN
|
||||
}
|
||||
|
||||
EQWParser::~EQWParser() {
|
||||
//removed to try to stop perl from exploding on reload, we'll see
|
||||
/* eval_pv(
|
||||
"package quest;"
|
||||
" untie *STDOUT;"
|
||||
" untie *STDERR;"
|
||||
,FALSE);
|
||||
*/
|
||||
perl_free(my_perl);
|
||||
}
|
||||
|
||||
bool EQWParser::eval_file(const char * packagename, const char * filename, std::string &error)
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
args.push_back(packagename);
|
||||
args.push_back(filename);
|
||||
return(dosub("eval_file", args, error));
|
||||
}
|
||||
|
||||
bool EQWParser::dosub(const char * subname, const std::vector<std::string> &args, string &error, int mode) {
|
||||
bool err = false;
|
||||
dSP; /* initialize stack pointer */
|
||||
ENTER; /* everything created after here */
|
||||
SAVETMPS; /* ...is a temporary variable. */
|
||||
PUSHMARK(SP); /* remember the stack pointer */
|
||||
if(args.size() > 0)
|
||||
{
|
||||
for(std::vector<std::string>::const_iterator i = args.begin(); i != args.end(); ++i)
|
||||
{/* push the arguments onto the perl stack */
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), i->length())));
|
||||
}
|
||||
}
|
||||
PUTBACK; /* make local stack pointer global */
|
||||
call_pv(subname, mode); /*eval our code*/
|
||||
SPAGAIN; /* refresh stack pointer */
|
||||
if(SvTRUE(ERRSV)) {
|
||||
err = true;
|
||||
}
|
||||
FREETMPS; /* free temp values */
|
||||
LEAVE; /* ...and the XPUSHed "mortal" args.*/
|
||||
|
||||
if(err) {
|
||||
error = "Perl runtime error: ";
|
||||
error += SvPVX(ERRSV);
|
||||
return(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool EQWParser::eval(const char * code, string &error) {
|
||||
std::vector<std::string> arg;
|
||||
arg.push_back(code);
|
||||
return(dosub("my_eval", arg, error, G_SCALAR|G_DISCARD|G_EVAL|G_KEEPERR));
|
||||
}
|
||||
|
||||
|
||||
void EQWParser::EQW_eval(const char *pkg, const char *code) {
|
||||
char namebuf[64];
|
||||
|
||||
snprintf(namebuf, 64, "package %s;", pkg);
|
||||
eval_pv(namebuf, FALSE);
|
||||
|
||||
//make sure the EQW pointer is set up
|
||||
EQW *curc = EQW::Singleton();
|
||||
snprintf(namebuf, 64, "EQW");
|
||||
// snprintf(namebuf, 64, "%s::EQW", pkg);
|
||||
SV *l = get_sv(namebuf, true);
|
||||
if(curc != NULL) {
|
||||
sv_setref_pv(l, "EQW", curc);
|
||||
} else {
|
||||
//clear out the value, mainly to get rid of blessedness
|
||||
sv_setsv(l, _empty_sv);
|
||||
}
|
||||
//make sure the EQDB pointer is set up
|
||||
EQDB *curc_db = EQDB::Singleton();
|
||||
snprintf(namebuf, 64, "EQDB");
|
||||
// snprintf(namebuf, 64, "%s::EQW", pkg);
|
||||
SV *l_db = get_sv(namebuf, true);
|
||||
if(curc_db != NULL) {
|
||||
sv_setref_pv(l_db, "EQDB", curc_db);
|
||||
} else {
|
||||
//clear out the value, mainly to get rid of blessedness
|
||||
sv_setsv(l_db, _empty_sv);
|
||||
}
|
||||
|
||||
string err;
|
||||
if(!eval(code, err)) {
|
||||
EQW::Singleton()->AppendOutput(err.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void EQWParser::SetHTTPRequest(const char *pkg, HTTPRequest *it) {
|
||||
char namebuf[64];
|
||||
|
||||
snprintf(namebuf, 64, "package %s;", pkg);
|
||||
eval_pv(namebuf, FALSE);
|
||||
|
||||
snprintf(namebuf, 64, "request");
|
||||
// snprintf(namebuf, 64, "%s::EQW", pkg);
|
||||
SV *l = get_sv(namebuf, true);
|
||||
if(it != NULL) {
|
||||
sv_setref_pv(l, "HTTPRequest", it);
|
||||
} else {
|
||||
//clear out the value, mainly to get rid of blessedness
|
||||
sv_setsv(l, _empty_sv);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
$editors = array();
|
||||
$editors["merchant"] = new MerchantEditor();
|
||||
#... for other editors
|
||||
|
||||
if(defined($editors[$editor])) {
|
||||
$edit = $editors[$editor];
|
||||
$edit->dispatch($action);
|
||||
}
|
||||
|
||||
class MerchantEditor extends BaseEditor {
|
||||
MerchantEditor() {
|
||||
$this->RegisterAction(0, "get_merchantlist", "merchant/merchant.tmpl.php", "no");
|
||||
$this->RegisterAction(1, "get_merchantlist", "merchant/merchant.edit.tmpl.php", "no");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function dispatch() {
|
||||
my $dispatcher = $this->_dispatchers[$action];
|
||||
$body = new Template($dispatcher["template"]);
|
||||
my $proc = $dispatcher["proc"];
|
||||
$vars = $this->$proc();
|
||||
if($dispatcher["guestmode"] == "no") {
|
||||
check_authorization();
|
||||
}
|
||||
if ($vars) {
|
||||
foreach ($vars as $key=>$value) {
|
||||
$body->set($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#endif //EMBPERL
|
||||
@@ -0,0 +1,79 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef EQWPARSER_H_
|
||||
#define EQWPARSER_H_
|
||||
|
||||
|
||||
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "../common/useperl.h"
|
||||
|
||||
class HTTPRequest;
|
||||
|
||||
class EQWParser {
|
||||
public:
|
||||
EQWParser();
|
||||
~EQWParser();
|
||||
|
||||
void EQW_eval(const char *pkg, const char *code);
|
||||
void SetHTTPRequest(const char *pkg, HTTPRequest *it);
|
||||
|
||||
//put an integer into a perl varable
|
||||
void seti(const char *varname, int val) const {
|
||||
SV *t = get_sv(varname, true);
|
||||
sv_setiv(t, val);
|
||||
}
|
||||
//put a real into a perl varable
|
||||
void setd(const char *varname, float val) const {
|
||||
SV *t = get_sv(varname, true);
|
||||
sv_setnv(t, val);
|
||||
}
|
||||
//put a string into a perl varable
|
||||
void setstr(const char *varname, const char *val) const {
|
||||
SV *t = get_sv(varname, true);
|
||||
sv_setpv(t, val);
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoInit();
|
||||
bool eval(const char * code, std::string &error);
|
||||
bool dosub(const char * subname, const std::vector<std::string> &args, std::string &error, int mode = G_SCALAR|G_DISCARD|G_EVAL);
|
||||
bool eval_file(const char * packagename, const char * filename, std::string &error);
|
||||
|
||||
//the embedded interpreter
|
||||
PerlInterpreter * my_perl;
|
||||
SV *_empty_sv;
|
||||
};
|
||||
#endif //EMBPERL
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*EQWPARSER_H_*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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/debug.h"
|
||||
#include "HTTPRequest.h"
|
||||
#include "EQWHTTPHandler.h"
|
||||
#include "../common/EQDB.h"
|
||||
#include "../common/SocketLib/HttpdForm.h"
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
HTTPRequest::HTTPRequest(EQWHTTPHandler *h, HttpdForm *form)
|
||||
: m_handler(h)
|
||||
{
|
||||
string name, value;
|
||||
if(form->getfirst(name, value)) {
|
||||
m_values[name] = value;
|
||||
while(form->getnext(name, value))
|
||||
m_values[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
const char *HTTPRequest::getEscaped(const char *name, const char *default_value) const {
|
||||
return(EQDB::Singleton()->escape_string(get(name, default_value)));
|
||||
}
|
||||
|
||||
const char *HTTPRequest::get(const char *name, const char *default_value) const {
|
||||
std::map<std::string, std::string>::const_iterator res;
|
||||
res = m_values.find(name);
|
||||
if(res == m_values.end())
|
||||
return(default_value);
|
||||
return(res->second.c_str());
|
||||
}
|
||||
|
||||
map<string,string> HTTPRequest::get_all() const {
|
||||
return m_values;
|
||||
}
|
||||
|
||||
int HTTPRequest::getInt(const char *name, int default_value) const {
|
||||
std::map<std::string, std::string>::const_iterator res;
|
||||
res = m_values.find(name);
|
||||
if(res == m_values.end())
|
||||
return(default_value);
|
||||
return(atoi(res->second.c_str()));
|
||||
}
|
||||
|
||||
float HTTPRequest::getFloat(const char *name, float default_value) const {
|
||||
std::map<std::string, std::string>::const_iterator res;
|
||||
res = m_values.find(name);
|
||||
if(res == m_values.end())
|
||||
return(default_value);
|
||||
return(atof(res->second.c_str()));
|
||||
}
|
||||
|
||||
void HTTPRequest::header(Const_char *name, Const_char *value) {
|
||||
m_handler->AddResponseHeader(name, value);
|
||||
}
|
||||
|
||||
void HTTPRequest::SetResponseCode(Const_char *code) {
|
||||
m_handler->SetResponseCode(code);
|
||||
}
|
||||
|
||||
void HTTPRequest::redirect(Const_char *URL) {
|
||||
header("Location", URL);
|
||||
SetResponseCode("302");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef HTTPREQUEST_H_
|
||||
#define HTTPREQUEST_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
//this object acts as a friendlier interface to the HttpdForm object (perl exportable)
|
||||
//which does more effecient lookups
|
||||
|
||||
|
||||
class HttpdForm;
|
||||
class EQWHTTPHandler;
|
||||
|
||||
using namespace std;
|
||||
|
||||
class HTTPRequest {
|
||||
public:
|
||||
HTTPRequest(EQWHTTPHandler *h, HttpdForm *form);
|
||||
|
||||
//BEGIN PERL EXPORT
|
||||
|
||||
|
||||
Const_char * get(Const_char *name, Const_char *default_value = "") const;
|
||||
int getInt(Const_char *name, int default_value = 0) const;
|
||||
float getFloat(Const_char *name, float default_value = 0.0) const;
|
||||
|
||||
//returns a database-safe string
|
||||
Const_char * getEscaped(Const_char *name, Const_char *default_value = "") const;
|
||||
|
||||
map<string,string> get_all() const;
|
||||
|
||||
void redirect(Const_char *URL);
|
||||
void SetResponseCode(Const_char *code);
|
||||
void header(Const_char *name, Const_char *value);
|
||||
//END PERL EXPORT
|
||||
|
||||
protected:
|
||||
EQWHTTPHandler *const m_handler;
|
||||
std::map<std::string, std::string> m_values;
|
||||
};
|
||||
|
||||
|
||||
#endif /*HTTPREQUEST_H_*/
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,368 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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/debug.h"
|
||||
#include "LauncherLink.h"
|
||||
#include "LauncherList.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "worlddb.h"
|
||||
#include "EQLConfig.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
extern LauncherList launcher_list;
|
||||
|
||||
|
||||
LauncherLink::LauncherLink(int id, EmuTCPConnection *c)
|
||||
: ID(id),
|
||||
tcpc(c),
|
||||
authenticated(false),
|
||||
m_name(""),
|
||||
m_bootTimer(2000)
|
||||
{
|
||||
m_dynamicCount = 0;
|
||||
m_bootTimer.Disable();
|
||||
}
|
||||
|
||||
LauncherLink::~LauncherLink() {
|
||||
tcpc->Free();
|
||||
}
|
||||
|
||||
bool LauncherLink::Process() {
|
||||
if (!tcpc->Connected())
|
||||
return false;
|
||||
|
||||
if(m_bootTimer.Check(false)) {
|
||||
//force a boot on any zone which isnt running.
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(!cur->second.up) {
|
||||
StartZone(cur->first.c_str());
|
||||
}
|
||||
}
|
||||
m_bootTimer.Disable();
|
||||
}
|
||||
|
||||
ServerPacket *pack = 0;
|
||||
while((pack = tcpc->PopPacket())) {
|
||||
_hex(WORLD__ZONE_TRACE,pack->pBuffer,pack->size);
|
||||
if (!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;
|
||||
else {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(WORLD__LAUNCH_ERR, "Launcher authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(WORLD__LAUNCH_ERR, "Launcher authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(WORLD__LAUNCH,"**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;
|
||||
}
|
||||
delete pack;
|
||||
continue;
|
||||
}
|
||||
switch(pack->opcode) {
|
||||
case 0:
|
||||
break;
|
||||
case ServerOP_KeepAlive: {
|
||||
// ignore this
|
||||
break;
|
||||
}
|
||||
case ServerOP_ZAAuth: {
|
||||
_log(WORLD__LAUNCH, "Got authentication from %s when they are already authenticated.", m_name.c_str());
|
||||
break;
|
||||
}
|
||||
case ServerOP_LauncherConnectInfo: {
|
||||
const LauncherConnectInfo *it = (const LauncherConnectInfo *) pack->pBuffer;
|
||||
if(HasName()) {
|
||||
_log(WORLD__LAUNCH_ERR, "Launcher '%s' received an additional connect packet with name '%s'. Ignoring.", m_name.c_str(), it->name);
|
||||
break;
|
||||
}
|
||||
m_name = it->name;
|
||||
|
||||
EQLConfig *config = launcher_list.GetConfig(m_name.c_str());
|
||||
if(config == NULL) {
|
||||
_log(WORLD__LAUNCH, "Unknown launcher '%s' connected. Disconnecting.", it->name);
|
||||
Disconnect();
|
||||
break;
|
||||
}
|
||||
|
||||
_log(WORLD__LAUNCH, "Launcher Identified itself as '%s'. Loading zone list.", it->name);
|
||||
|
||||
std::vector<LauncherZone> result;
|
||||
//database.GetLauncherZones(it->name, result);
|
||||
config->GetZones(result);
|
||||
|
||||
std::vector<LauncherZone>::iterator cur, end;
|
||||
cur = result.begin();
|
||||
end = result.end();
|
||||
ZoneState zs;
|
||||
for(; cur != end; cur++) {
|
||||
zs.port = cur->port;
|
||||
zs.up = false;
|
||||
zs.starts = 0;
|
||||
_log(WORLD__LAUNCH_TRACE, "%s: Loaded zone '%s' on port %d", m_name.c_str(), cur->name.c_str(), zs.port);
|
||||
m_states[cur->name] = zs;
|
||||
}
|
||||
|
||||
//now we add all the dynamics.
|
||||
BootDynamics(config->GetDynamicCount());
|
||||
|
||||
m_bootTimer.Start();
|
||||
|
||||
break;
|
||||
}
|
||||
case ServerOP_LauncherZoneStatus: {
|
||||
const LauncherZoneStatus *it = (const LauncherZoneStatus *) pack->pBuffer;
|
||||
std::map<std::string, ZoneState>::iterator res;
|
||||
res = m_states.find(it->short_name);
|
||||
if(res == m_states.end()) {
|
||||
_log(WORLD__LAUNCH_ERR, "%s: reported state for zone %s which it does not have.", m_name.c_str(), it->short_name);
|
||||
break;
|
||||
}
|
||||
_log(WORLD__LAUNCH, "%s: %s reported state %s (%d starts)", m_name.c_str(), it->short_name, it->running?"STARTED":"STOPPED", it->start_count);
|
||||
res->second.up = it->running;
|
||||
res->second.starts = it->start_count;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log(WORLD__LAUNCH_ERR, "Unknown ServerOPcode from launcher 0x%04x, size %d",pack->opcode,pack->size);
|
||||
DumpPacket(pack->pBuffer, pack->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete pack;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
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) {
|
||||
ZoneState zs;
|
||||
zs.port = port;
|
||||
zs.up = false;
|
||||
zs.starts = 0;
|
||||
_log(WORLD__LAUNCH_TRACE, "%s: Loaded zone '%s' on port %d", m_name.c_str(), short_name, zs.port);
|
||||
m_states[short_name] = zs;
|
||||
|
||||
StartZone(short_name);
|
||||
}
|
||||
|
||||
void LauncherLink::StartZone(const char *short_name) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Start;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LauncherLink::RestartZone(const char *short_name) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Restart;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LauncherLink::StopZone(const char *short_name) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Stop;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LauncherLink::BootDynamics(uint8 new_count) {
|
||||
if(m_dynamicCount == new_count)
|
||||
return;
|
||||
|
||||
ZoneState zs;
|
||||
if(m_dynamicCount < new_count) {
|
||||
//we are booting more dynamics.
|
||||
|
||||
zs.port = 0;
|
||||
zs.up = false;
|
||||
zs.starts = 0;
|
||||
|
||||
int r;
|
||||
char nbuf[20];
|
||||
uint8 index;
|
||||
//"for each zone we need to boot"
|
||||
for(r = m_dynamicCount; r < new_count; r++) {
|
||||
//find an idle ID
|
||||
for(index = m_dynamicCount+1; index < 255; index++) {
|
||||
sprintf(nbuf, "dynamic_%02d", index);
|
||||
if(m_states.find(nbuf) != m_states.end())
|
||||
continue;
|
||||
m_states[nbuf] = zs;
|
||||
StartZone(nbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_dynamicCount = new_count;
|
||||
} else if(new_count == 0) {
|
||||
//kill all zones...
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
StopZone(cur->first.c_str());
|
||||
}
|
||||
} else {
|
||||
//need to get rid of some zones...
|
||||
|
||||
//quick and dirty way to do this.. should do better (like looking for idle zones)
|
||||
int found = 0;
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(cur->first.find("dynamic_") == 0) {
|
||||
if(found >= new_count) {
|
||||
//this zone exceeds the number of allowed booted zones.
|
||||
StopZone(cur->first.c_str());
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_dynamicCount = new_count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LauncherLink::GetZoneList(std::vector<std::string> &l) {
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
l.push_back(cur->first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherLink::GetZoneDetails(const char *short_name, std::map<std::string,std::string> &res) {
|
||||
res.clear();
|
||||
|
||||
std::map<std::string, ZoneState>::iterator r;
|
||||
r = m_states.find(short_name);
|
||||
if(r == m_states.end()) {
|
||||
res["error"] = "Zone Not Found";
|
||||
res["name"] = short_name;
|
||||
res["up"] = "0";
|
||||
res["starts"] = "0";
|
||||
res["port"] = "0";
|
||||
} else {
|
||||
res["name"] = r->first;
|
||||
res["up"] = r->second.up?"1":"0";
|
||||
res["starts"] = itoa(r->second.starts);
|
||||
res["port"] = itoa(r->second.port);
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherLink::Shutdown() {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ShutdownAll);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef LAUNCHERLINK_H_
|
||||
#define LAUNCHERLINK_H_
|
||||
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/timer.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class ServerPacket;
|
||||
|
||||
class LauncherLink {
|
||||
public:
|
||||
LauncherLink(int id, EmuTCPConnection *tcpc);
|
||||
~LauncherLink();
|
||||
|
||||
bool Process();
|
||||
bool SendPacket(ServerPacket* pack) { return tcpc->SendPacket(pack); }
|
||||
// bool SendPacket(TCPConnection::TCPNetPacket_Struct* tnps) { return tcpc->SendPacket(tnps); }
|
||||
|
||||
int GetID() const { return(ID); }
|
||||
void Disconnect() { tcpc->Disconnect(); }
|
||||
|
||||
inline bool HasName() const { return(m_name.length() > 0); }
|
||||
inline uint32 GetIP() const { return tcpc->GetrIP(); }
|
||||
inline uint16 GetPort() const { return tcpc->GetrPort(); }
|
||||
inline const char * GetName() const { return(m_name.c_str()); }
|
||||
inline int CountZones() const { return(m_states.size()); }
|
||||
|
||||
bool ContainsZone(const char *short_name) const;
|
||||
|
||||
//commands
|
||||
void Shutdown();
|
||||
void BootZone(const char *short_name, uint16 port);
|
||||
void StartZone(const char *short_name);
|
||||
void RestartZone(const char *short_name);
|
||||
void StopZone(const char *short_name);
|
||||
void BootDynamics(uint8 new_total);
|
||||
|
||||
void GetZoneList(std::vector<std::string> &list);
|
||||
void GetZoneDetails(const char *short_name, std::map<std::string,std::string> &result);
|
||||
|
||||
protected:
|
||||
const int ID;
|
||||
EmuTCPConnection*const tcpc;
|
||||
bool authenticated;
|
||||
std::string m_name;
|
||||
Timer m_bootTimer;
|
||||
|
||||
uint8 m_dynamicCount;
|
||||
|
||||
typedef struct {
|
||||
bool up;
|
||||
uint32 starts; //number of times this zone has started
|
||||
uint16 port; //the port this zone wants to use (0=pick one)
|
||||
} ZoneState;
|
||||
std::map<std::string, ZoneState> m_states;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*LAUNCHERLINK_H_*/
|
||||
@@ -0,0 +1,222 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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/debug.h"
|
||||
#include "LauncherList.h"
|
||||
#include "LauncherLink.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "EQLConfig.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
LauncherList::LauncherList()
|
||||
: nextID(1)
|
||||
{
|
||||
}
|
||||
|
||||
LauncherList::~LauncherList() {
|
||||
vector<LauncherLink *>::iterator cur, end;
|
||||
cur = m_pendingLaunchers.begin();
|
||||
end = m_pendingLaunchers.end();
|
||||
for(; cur != end; cur++) {
|
||||
delete *cur;
|
||||
}
|
||||
|
||||
map<string, EQLConfig *>::iterator curc, endc;
|
||||
curc = m_configs.begin();
|
||||
endc = m_configs.end();
|
||||
for(; curc != endc; curc++) {
|
||||
delete curc->second;
|
||||
}
|
||||
|
||||
map<string, LauncherLink *>::iterator curl, endl;
|
||||
curl = m_launchers.begin();
|
||||
endl = m_launchers.end();
|
||||
for(; curl != endl; curl++) {
|
||||
delete curl->second;
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherList::Process() {
|
||||
//process pending launchers..
|
||||
vector<LauncherLink *>::iterator cur, end;
|
||||
cur = m_pendingLaunchers.begin();
|
||||
while(cur != m_pendingLaunchers.end()) {
|
||||
LauncherLink *l = *cur;
|
||||
//printf("ProcP %d: %p\n", l->GetID(), l);
|
||||
if(!l->Process()) {
|
||||
//launcher has died before it identified itself.
|
||||
_log(WORLD__LAUNCH, "Removing pending launcher %d", l->GetID());
|
||||
cur = m_pendingLaunchers.erase(cur);
|
||||
delete l;
|
||||
} else if(l->HasName()) {
|
||||
//launcher has identified itself now.
|
||||
//remove ourself from the pending list
|
||||
cur = m_pendingLaunchers.erase(cur);
|
||||
string name = l->GetName();
|
||||
//kill off anybody else using our name.
|
||||
map<string, LauncherLink *>::iterator res;
|
||||
res = m_launchers.find(name);
|
||||
if(res != m_launchers.end()) {
|
||||
_log(WORLD__LAUNCH, "Ghosting launcher %s", name.c_str());
|
||||
delete res->second;
|
||||
}
|
||||
_log(WORLD__LAUNCH, "Removing pending launcher %d. Adding %s to active list.", l->GetID(), name.c_str());
|
||||
//put the launcher in the list.
|
||||
m_launchers[name] = l;
|
||||
} else {
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
|
||||
//process active launchers.
|
||||
map<string, LauncherLink *>::iterator curl, tmp;
|
||||
curl = m_launchers.begin();
|
||||
while(curl != m_launchers.end()) {
|
||||
LauncherLink *l = curl->second;
|
||||
//printf("Proc %s(%d): %p\n", l->GetName(), l->GetID(), l);
|
||||
if(!l->Process()) {
|
||||
//launcher has died before it identified itself.
|
||||
_log(WORLD__LAUNCH, "Removing launcher %s (%d)", l->GetName(), l->GetID());
|
||||
tmp = curl;
|
||||
curl++;
|
||||
m_launchers.erase(tmp);
|
||||
delete l;
|
||||
} else {
|
||||
curl++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LauncherLink *LauncherList::Get(const char *name) {
|
||||
map<string, LauncherLink *>::iterator res;
|
||||
res = m_launchers.find(name);
|
||||
if(res == m_launchers.end())
|
||||
return(NULL);
|
||||
return(res->second);
|
||||
/* string goal(name);
|
||||
|
||||
vector<LauncherLink *>::iterator cur, end;
|
||||
cur = m_launchers.begin();
|
||||
end = m_launchers.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(goal == (*cur)->GetName())
|
||||
return(*cur);
|
||||
}
|
||||
return(NULL);*/
|
||||
}
|
||||
|
||||
LauncherLink *LauncherList::FindByZone(const char *short_name) {
|
||||
map<string, LauncherLink *>::iterator cur, end;
|
||||
cur = m_launchers.begin();
|
||||
end = m_launchers.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(cur->second->ContainsZone(short_name))
|
||||
return(cur->second);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void LauncherList::Add(EmuTCPConnection *conn) {
|
||||
LauncherLink *it = new LauncherLink(nextID++, conn);
|
||||
_log(WORLD__LAUNCH, "Adding pending launcher %d", it->GetID());
|
||||
m_pendingLaunchers.push_back(it);
|
||||
}
|
||||
|
||||
|
||||
int LauncherList::GetLauncherCount() {
|
||||
return(m_launchers.size());
|
||||
}
|
||||
|
||||
void LauncherList::GetLauncherNameList(std::vector<string> &res) {
|
||||
map<string, EQLConfig *>::iterator cur, end;
|
||||
cur = m_configs.begin();
|
||||
end = m_configs.end();
|
||||
for(; cur != end; cur++) {
|
||||
res.push_back(cur->first);
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherList::LoadList() {
|
||||
vector<string> launchers;
|
||||
|
||||
database.GetLauncherList(launchers);
|
||||
|
||||
vector<string>::iterator cur, end;
|
||||
cur = launchers.begin();
|
||||
end = launchers.end();
|
||||
for(; cur != end; cur++) {
|
||||
m_configs[*cur] = new EQLConfig(cur->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
EQLConfig *LauncherList::GetConfig(const char *name) {
|
||||
map<string, EQLConfig *>::iterator res;
|
||||
res = m_configs.find(name);
|
||||
if(res == m_configs.end()) {
|
||||
return(NULL);
|
||||
}
|
||||
return(res->second);
|
||||
}
|
||||
|
||||
void LauncherList::CreateLauncher(const char *name, uint8 dynamic_count) {
|
||||
m_configs[name] = EQLConfig::CreateLauncher(name, dynamic_count);
|
||||
}
|
||||
|
||||
void LauncherList::Remove(const char *name) {
|
||||
map<string, EQLConfig *>::iterator resc;
|
||||
resc = m_configs.find(name);
|
||||
if(resc != m_configs.end()) {
|
||||
delete resc->second;
|
||||
m_configs.erase(resc);
|
||||
}
|
||||
|
||||
map<string, LauncherLink *>::iterator resl;
|
||||
resl = m_launchers.find(name);
|
||||
if(resl != m_launchers.end()) {
|
||||
resl->second->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef LAUNCHERLIST_H_
|
||||
#define LAUNCHERLIST_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class LauncherLink;
|
||||
class EmuTCPConnection;
|
||||
class EQLConfig;
|
||||
|
||||
class LauncherList {
|
||||
public:
|
||||
LauncherList();
|
||||
~LauncherList();
|
||||
|
||||
void Process();
|
||||
|
||||
void LoadList();
|
||||
EQLConfig *GetConfig(const char *name);
|
||||
void CreateLauncher(const char *name, uint8 dynamic_count);
|
||||
void Remove(const char *name);
|
||||
|
||||
void Add(EmuTCPConnection *conn);
|
||||
LauncherLink *Get(const char *name);
|
||||
LauncherLink *FindByZone(const char *short_name);
|
||||
|
||||
int GetLauncherCount();
|
||||
void GetLauncherNameList(std::vector<std::string> &list);
|
||||
|
||||
protected:
|
||||
std::map<std::string, EQLConfig *> m_configs; //we own these objects
|
||||
std::map<std::string, LauncherLink *> m_launchers; //we own these objects
|
||||
// std::map<std::string, EQLConfig *> m_configs; //we own these objects
|
||||
std::vector<LauncherLink *> m_pendingLaunchers; //we own these objects, have not yet identified themself
|
||||
int nextID;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*LAUNCHERLIST_H_*/
|
||||
@@ -0,0 +1,339 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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/debug.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
#include <stdlib.h>
|
||||
#include "../common/version.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
|
||||
#define snprintf _snprintf
|
||||
#if (_MSC_VER < 1500)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#else // Pyro: fix for linux
|
||||
#include <sys/socket.h>
|
||||
#ifdef FREEBSD //Timothy Whitman - January 7, 2003
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../common/unix.h"
|
||||
|
||||
#define SOCKET_ERROR -1
|
||||
#define INVALID_SOCKET -1
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#define IGNORE_LS_FATAL_ERROR
|
||||
|
||||
#include "../common/servertalk.h"
|
||||
#include "LoginServer.h"
|
||||
#include "LoginServerList.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include "zoneserver.h"
|
||||
#include "worlddb.h"
|
||||
#include "zonelist.h"
|
||||
#include "clientlist.h"
|
||||
#include "WorldConfig.h"
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
extern ClientList client_list;
|
||||
extern uint32 numzones;
|
||||
extern uint32 numplayers;
|
||||
extern volatile bool RunLoops;
|
||||
|
||||
LoginServer::LoginServer(const char* iAddress, uint16 iPort, const char* Account, const char* Password)
|
||||
: statusupdate_timer(LoginServer_StatusUpdateInterval)
|
||||
{
|
||||
strn0cpy(LoginServerAddress,iAddress,256);
|
||||
LoginServerPort = iPort;
|
||||
strn0cpy(LoginAccount,Account,31);
|
||||
strn0cpy(LoginPassword,Password,31);
|
||||
CanAccountUpdate = false;
|
||||
tcpc = new EmuTCPConnection(true);
|
||||
tcpc->SetPacketMode(EmuTCPConnection::packetModeLogin);
|
||||
}
|
||||
|
||||
LoginServer::~LoginServer() {
|
||||
delete tcpc;
|
||||
}
|
||||
|
||||
bool LoginServer::Process() {
|
||||
const WorldConfig *Config=WorldConfig::get();
|
||||
|
||||
if (statusupdate_timer.Check()) {
|
||||
this->SendStatus();
|
||||
}
|
||||
|
||||
/************ Get all packets from packet manager out queue and process them ************/
|
||||
ServerPacket *pack = 0;
|
||||
while((pack = tcpc->PopPacket()))
|
||||
{
|
||||
_log(WORLD__LS_TRACE,"Recevied ServerPacket from LS OpCode 0x04x",pack->opcode);
|
||||
_hex(WORLD__LS_TRACE,pack->pBuffer,pack->size);
|
||||
|
||||
switch(pack->opcode) {
|
||||
case 0:
|
||||
break;
|
||||
case ServerOP_KeepAlive: {
|
||||
// ignore this
|
||||
break;
|
||||
}
|
||||
case ServerOP_UsertoWorldReq: {
|
||||
UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*) pack->pBuffer;
|
||||
uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid);
|
||||
int16 status = database.CheckStatus(id);
|
||||
|
||||
ServerPacket* outpack = new ServerPacket;
|
||||
outpack->opcode = ServerOP_UsertoWorldResp;
|
||||
outpack->size = sizeof(UsertoWorldResponse_Struct);
|
||||
outpack->pBuffer = new uchar[outpack->size];
|
||||
memset(outpack->pBuffer, 0, outpack->size);
|
||||
UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*) outpack->pBuffer;
|
||||
utwrs->lsaccountid = utwr->lsaccountid;
|
||||
utwrs->ToID = utwr->FromID;
|
||||
|
||||
if(Config->Locked == true)
|
||||
{
|
||||
if((status == 0 || status < 100) && (status != -2 || status != -1))
|
||||
utwrs->response = 0;
|
||||
if(status >= 100)
|
||||
utwrs->response = 1;
|
||||
}
|
||||
else {
|
||||
utwrs->response = 1;
|
||||
}
|
||||
|
||||
int32 x = Config->MaxClients;
|
||||
if( (int32)numplayers >= x && x != -1 && x != 255 && status < 80)
|
||||
utwrs->response = -3;
|
||||
|
||||
if(status == -1)
|
||||
utwrs->response = -1;
|
||||
if(status == -2)
|
||||
utwrs->response = -2;
|
||||
|
||||
utwrs->worldid = utwr->worldid;
|
||||
SendPacket(outpack);
|
||||
delete outpack;
|
||||
break;
|
||||
}
|
||||
case ServerOP_LSClientAuth: {
|
||||
ServerLSClientAuth* slsca = (ServerLSClientAuth*) pack->pBuffer;
|
||||
|
||||
if (RuleI(World, AccountSessionLimit) >= 0) {
|
||||
// Enforce the limit on the number of characters on the same account that can be
|
||||
// online at the same time.
|
||||
client_list.EnforceSessionLimit(slsca->lsaccount_id);
|
||||
}
|
||||
|
||||
client_list.CLEAdd(slsca->lsaccount_id, slsca->name, slsca->key, slsca->worldadmin, slsca->ip, slsca->local);
|
||||
break;
|
||||
}
|
||||
case ServerOP_LSFatalError: {
|
||||
#ifndef IGNORE_LS_FATAL_ERROR
|
||||
WorldConfig::DisableLoginserver();
|
||||
_log(WORLD__LS_ERR, "Login server responded with FatalError. Disabling reconnect.");
|
||||
#else
|
||||
_log(WORLD__LS_ERR, "Login server responded with FatalError.");
|
||||
#endif
|
||||
if (pack->size > 1) {
|
||||
_log(WORLD__LS_ERR, " %s",pack->pBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_SystemwideMessage: {
|
||||
ServerSystemwideMessage* swm = (ServerSystemwideMessage*) pack->pBuffer;
|
||||
zoneserver_list.SendEmoteMessageRaw(0, 0, 0, swm->type, swm->message);
|
||||
break;
|
||||
}
|
||||
case ServerOP_LSRemoteAddr: {
|
||||
if (!Config->WorldAddress.length()) {
|
||||
WorldConfig::SetWorldAddress((char *)pack->pBuffer);
|
||||
_log(WORLD__LS, "Loginserver provided %s as world address",pack->pBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_LSAccountUpdate: {
|
||||
_log(WORLD__LS, "Received ServerOP_LSAccountUpdate packet from loginserver");
|
||||
CanAccountUpdate = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log(WORLD__LS_ERR, "Unknown LSOpCode: 0x%04x size=%d",(int)pack->opcode,pack->size);
|
||||
DumpPacket(pack->pBuffer, pack->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete pack;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServer::InitLoginServer() {
|
||||
if(Connected() == false) {
|
||||
if(ConnectReady()) {
|
||||
_log(WORLD__LS, "Connecting to login server: %s:%d",LoginServerAddress,LoginServerPort);
|
||||
Connect();
|
||||
} else {
|
||||
_log(WORLD__LS_ERR, "Not connected but not ready to connect, this is bad: %s:%d",
|
||||
LoginServerAddress,LoginServerPort);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServer::Connect() {
|
||||
char tmp[25];
|
||||
if(database.GetVariable("loginType",tmp,sizeof(tmp)) && strcasecmp(tmp,"MinILogin") == 0){
|
||||
minilogin = true;
|
||||
_log(WORLD__LS, "Setting World to MiniLogin Server type");
|
||||
}
|
||||
else
|
||||
minilogin = false;
|
||||
|
||||
if (minilogin && WorldConfig::get()->WorldAddress.length()==0) {
|
||||
_log(WORLD__LS_ERR, "**** For minilogin to work, you need to set the <address> element in the <world> section.");
|
||||
return false;
|
||||
}
|
||||
|
||||
char errbuf[TCPConnection_ErrorBufferSize];
|
||||
if ((LoginServerIP = ResolveIP(LoginServerAddress, errbuf)) == 0) {
|
||||
_log(WORLD__LS_ERR, "Unable to resolve '%s' to an IP.",LoginServerAddress);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LoginServerIP == 0 || LoginServerPort == 0) {
|
||||
_log(WORLD__LS_ERR, "Connect info incomplete, cannot connect: %s:%d",LoginServerAddress,LoginServerPort);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tcpc->ConnectIP(LoginServerIP, LoginServerPort, errbuf)) {
|
||||
_log(WORLD__LS, "Connected to Loginserver: %s:%d",LoginServerAddress,LoginServerPort);
|
||||
if (minilogin)
|
||||
SendInfo();
|
||||
else
|
||||
SendNewInfo();
|
||||
SendStatus();
|
||||
zoneserver_list.SendLSZones();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
_log(WORLD__LS_ERR, "Could not connect to login server: %s:%d %s",LoginServerAddress,LoginServerPort,errbuf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void LoginServer::SendInfo() {
|
||||
const WorldConfig *Config=WorldConfig::get();
|
||||
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
pack->opcode = ServerOP_LSInfo;
|
||||
pack->size = sizeof(ServerLSInfo_Struct);
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
memset(pack->pBuffer, 0, pack->size);
|
||||
ServerLSInfo_Struct* lsi = (ServerLSInfo_Struct*) pack->pBuffer;
|
||||
strcpy(lsi->protocolversion, EQEMU_PROTOCOL_VERSION);
|
||||
strcpy(lsi->serverversion, CURRENT_VERSION);
|
||||
strcpy(lsi->name, Config->LongName.c_str());
|
||||
strcpy(lsi->account, LoginAccount);
|
||||
strcpy(lsi->password, LoginPassword);
|
||||
strcpy(lsi->address, Config->WorldAddress.c_str());
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LoginServer::SendNewInfo() {
|
||||
uint16 port;
|
||||
const WorldConfig *Config=WorldConfig::get();
|
||||
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
pack->opcode = ServerOP_NewLSInfo;
|
||||
pack->size = sizeof(ServerNewLSInfo_Struct);
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
memset(pack->pBuffer, 0, pack->size);
|
||||
ServerNewLSInfo_Struct* lsi = (ServerNewLSInfo_Struct*) pack->pBuffer;
|
||||
strcpy(lsi->protocolversion, EQEMU_PROTOCOL_VERSION);
|
||||
strcpy(lsi->serverversion, CURRENT_VERSION);
|
||||
strcpy(lsi->name, Config->LongName.c_str());
|
||||
strcpy(lsi->shortname, Config->ShortName.c_str());
|
||||
strcpy(lsi->account, LoginAccount);
|
||||
strcpy(lsi->password, LoginPassword);
|
||||
if (Config->WorldAddress.length())
|
||||
strcpy(lsi->remote_address, Config->WorldAddress.c_str());
|
||||
if (Config->LocalAddress.length())
|
||||
strcpy(lsi->local_address, Config->LocalAddress.c_str());
|
||||
else {
|
||||
tcpc->GetSockName(lsi->local_address,&port);
|
||||
WorldConfig::SetLocalAddress(lsi->local_address);
|
||||
}
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LoginServer::SendStatus() {
|
||||
statusupdate_timer.Start();
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
pack->opcode = ServerOP_LSStatus;
|
||||
pack->size = sizeof(ServerLSStatus_Struct);
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
memset(pack->pBuffer, 0, pack->size);
|
||||
ServerLSStatus_Struct* lss = (ServerLSStatus_Struct*) pack->pBuffer;
|
||||
|
||||
if (WorldConfig::get()->Locked)
|
||||
lss->status = -2;
|
||||
else if (numzones <= 0)
|
||||
lss->status = -2;
|
||||
else
|
||||
lss->status = numplayers;
|
||||
|
||||
lss->num_zones = numzones;
|
||||
lss->num_players = numplayers;
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LoginServer::SendAccountUpdate(ServerPacket* pack) {
|
||||
ServerLSAccountUpdate_Struct* s = (ServerLSAccountUpdate_Struct *) pack->pBuffer;
|
||||
if(CanUpdate()) {
|
||||
_log(WORLD__LS, "Sending ServerOP_LSAccountUpdate packet to loginserver: %s:%d",LoginServerAddress,LoginServerPort);
|
||||
strn0cpy(s->worldaccount, LoginAccount, 30);
|
||||
strn0cpy(s->worldpassword, LoginPassword, 30);
|
||||
SendPacket(pack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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
|
||||
*/
|
||||
#ifndef LOGINSERVER_H
|
||||
#define LOGINSERVER_H
|
||||
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/queue.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/Mutex.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
|
||||
class LoginServer{
|
||||
public:
|
||||
LoginServer(const char*, uint16, const char*, const char*);
|
||||
~LoginServer();
|
||||
|
||||
bool InitLoginServer();
|
||||
|
||||
bool Process();
|
||||
bool Connect();
|
||||
|
||||
void SendInfo();
|
||||
void SendNewInfo();
|
||||
void SendStatus();
|
||||
|
||||
void SendPacket(ServerPacket* pack) { tcpc->SendPacket(pack); }
|
||||
void SendAccountUpdate(ServerPacket* pack);
|
||||
bool ConnectReady() { return tcpc->ConnectReady(); }
|
||||
bool Connected() { return tcpc->Connected(); }
|
||||
bool MiniLogin() { return minilogin; }
|
||||
bool CanUpdate() { return CanAccountUpdate; }
|
||||
|
||||
private:
|
||||
bool minilogin;
|
||||
EmuTCPConnection* tcpc;
|
||||
char LoginServerAddress[256];
|
||||
uint32 LoginServerIP;
|
||||
uint16 LoginServerPort;
|
||||
char LoginAccount[32];
|
||||
char LoginPassword[32];
|
||||
bool CanAccountUpdate;
|
||||
|
||||
Timer statusupdate_timer;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,197 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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/debug.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
#include <stdlib.h>
|
||||
#include "../common/version.h"
|
||||
|
||||
#define IGNORE_LS_FATAL_ERROR
|
||||
|
||||
#include "../common/servertalk.h"
|
||||
#include "LoginServer.h"
|
||||
#include "LoginServerList.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "zoneserver.h"
|
||||
#include "worlddb.h"
|
||||
#include "zonelist.h"
|
||||
#include "clientlist.h"
|
||||
#include "WorldConfig.h"
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
extern LoginServerList loginserverlist;
|
||||
extern ClientList client_list;
|
||||
extern uint32 numzones;
|
||||
extern uint32 numplayers;
|
||||
extern volatile bool RunLoops;
|
||||
|
||||
LoginServerList::LoginServerList() {
|
||||
}
|
||||
|
||||
LoginServerList::~LoginServerList() {
|
||||
}
|
||||
|
||||
void LoginServerList::Add(const char* iAddress, uint16 iPort, const char* Account, const char* Password)
|
||||
{
|
||||
LoginServer* loginserver = new LoginServer(iAddress, iPort, Account, Password);
|
||||
list.Insert(loginserver);
|
||||
}
|
||||
|
||||
bool LoginServerList::Process() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
iterator.GetData()->Process();
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
void AutoInitLoginServer(void *tmp) {
|
||||
#else
|
||||
void *AutoInitLoginServer(void *tmp) {
|
||||
#endif
|
||||
loginserverlist.InitLoginServer();
|
||||
#ifndef WIN32
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LoginServerList::InitLoginServer() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
iterator.GetData()->InitLoginServer();
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
bool LoginServerList::SendInfo() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
iterator.GetData()->SendInfo();
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServerList::SendNewInfo() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
iterator.GetData()->SendNewInfo();
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServerList::SendStatus() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
iterator.GetData()->SendStatus();
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServerList::SendPacket(ServerPacket* pack) {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
iterator.GetData()->SendPacket(pack);
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServerList::SendAccountUpdate(ServerPacket* pack) {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
_log(WORLD__LS, "Requested to send ServerOP_LSAccountUpdate packet to all loginservers");
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
if(iterator.GetData()->CanUpdate()) {
|
||||
iterator.GetData()->SendAccountUpdate(pack);
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServerList::Connected() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
if(iterator.GetData()->Connected())
|
||||
return true;
|
||||
iterator.Advance();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoginServerList::AllConnected() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
if(iterator.GetData()->Connected() == false)
|
||||
return false;
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoginServerList::MiniLogin() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
if(iterator.GetData()->MiniLogin())
|
||||
return true;
|
||||
iterator.Advance();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoginServerList::CanUpdate() {
|
||||
LinkedListIterator<LoginServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()){
|
||||
if(iterator.GetData()->CanUpdate())
|
||||
return true;
|
||||
iterator.Advance();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef LOGINSERVERLIST_H_
|
||||
#define LOGINSERVERLIST_H_
|
||||
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/queue.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/Mutex.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
void AutoInitLoginServer(void *tmp);
|
||||
#else
|
||||
void *AutoInitLoginServer(void *tmp);
|
||||
#endif
|
||||
|
||||
class LoginServer;
|
||||
|
||||
class LoginServerList{
|
||||
public:
|
||||
LoginServerList();
|
||||
~LoginServerList();
|
||||
|
||||
void Add(const char*, uint16, const char*, const char*);
|
||||
void InitLoginServer();
|
||||
|
||||
bool Process();
|
||||
|
||||
bool SendInfo();
|
||||
bool SendNewInfo();
|
||||
bool SendStatus();
|
||||
|
||||
bool SendPacket(ServerPacket *pack);
|
||||
bool SendAccountUpdate(ServerPacket *pack);
|
||||
bool Connected();
|
||||
bool AllConnected();
|
||||
bool MiniLogin();
|
||||
bool CanUpdate();
|
||||
|
||||
protected:
|
||||
LinkedList<LoginServer*> list;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*LOGINSERVERLIST_H_*/
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef SOFCHARCREATEDATA_H
|
||||
#define SOFCHARCREATEDATA_H
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct RaceClassAllocation {
|
||||
unsigned int Index;
|
||||
unsigned int BaseStats[7];
|
||||
unsigned int DefaultPointAllocation[7];
|
||||
};
|
||||
|
||||
struct RaceClassCombos {
|
||||
unsigned int ExpansionRequired;
|
||||
unsigned int Race;
|
||||
unsigned int Class;
|
||||
unsigned int Deity;
|
||||
unsigned int AllocationIndex;
|
||||
unsigned int Zone;
|
||||
};
|
||||
|
||||
/*struct SoFCCData {
|
||||
unsigned char Unknown;
|
||||
unsigned int RaceClassStatEntryCount;
|
||||
SoFCCRaceClassData RCData[109];
|
||||
unsigned int Unknown2;
|
||||
SoFCCStartZoneData StartZoneData[641];
|
||||
};
|
||||
*/
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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/debug.h"
|
||||
#include "WorldConfig.h"
|
||||
|
||||
WorldConfig *WorldConfig::_world_config = NULL;
|
||||
|
||||
|
||||
string WorldConfig::GetByName(const string &var_name) const {
|
||||
if(var_name == "UpdateStats")
|
||||
return(UpdateStats?"true":"false");
|
||||
if(var_name == "LoginDisabled")
|
||||
return(LoginDisabled?"true":"false");
|
||||
return(EQEmuConfig::GetByName(var_name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef __WorldConfig_H
|
||||
#define __WorldConfig_H
|
||||
|
||||
#include "../common/EQEmuConfig.h"
|
||||
|
||||
class WorldConfig : public EQEmuConfig {
|
||||
public:
|
||||
virtual string GetByName(const string &var_name) const;
|
||||
|
||||
bool UpdateStats;
|
||||
bool LoginDisabled;
|
||||
|
||||
private:
|
||||
|
||||
static WorldConfig *_world_config;
|
||||
|
||||
WorldConfig() : EQEmuConfig() {
|
||||
LoginDisabled=false;
|
||||
UpdateStats=true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Produce a const singleton
|
||||
static const WorldConfig *get() {
|
||||
if (_world_config == NULL)
|
||||
LoadConfig();
|
||||
return(_world_config);
|
||||
}
|
||||
|
||||
// Load the config
|
||||
static bool LoadConfig() {
|
||||
if (_world_config != NULL)
|
||||
delete _world_config;
|
||||
_world_config=new WorldConfig;
|
||||
_config=_world_config;
|
||||
|
||||
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(),"server");
|
||||
}
|
||||
|
||||
// Accessors for the static private object
|
||||
static void LockWorld() { if (_world_config) _world_config->Locked=true; }
|
||||
static void UnlockWorld() { if (_world_config) _world_config->Locked=false; }
|
||||
|
||||
static void DisableStats() { if (_world_config) _world_config->UpdateStats=false; }
|
||||
static void EnableStats() { if (_world_config) _world_config->UpdateStats=true; }
|
||||
|
||||
static void DisableLoginserver() { if (_world_config) _world_config->LoginDisabled=true; }
|
||||
static void EnableLoginserver() { if (_world_config) _world_config->LoginDisabled=false; }
|
||||
|
||||
static void SetWorldAddress(string addr) { if (_world_config) _world_config->WorldAddress=addr; }
|
||||
static void SetLocalAddress(string addr) { if (_world_config) _world_config->LocalAddress=addr; }
|
||||
|
||||
void Dump() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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
|
||||
*/
|
||||
#ifndef WorldTCPCONNECTION_H
|
||||
#define WorldTCPCONNECTION_H
|
||||
|
||||
#include "../common/types.h"
|
||||
|
||||
class WorldTCPConnection
|
||||
{
|
||||
public:
|
||||
WorldTCPConnection() { }
|
||||
virtual ~WorldTCPConnection() { }
|
||||
virtual void SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...) { }
|
||||
virtual void SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message) { }
|
||||
|
||||
virtual inline bool IsConsole() { return false; }
|
||||
virtual inline bool IsZoneServer() { return false; }
|
||||
};
|
||||
|
||||
#endif
|
||||
+2021
File diff suppressed because it is too large
Load Diff
+108
@@ -0,0 +1,108 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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
|
||||
*/
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
//#include "../common/EQStream.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/timer.h"
|
||||
//#include "zoneserver.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "cliententry.h"
|
||||
|
||||
#define CLIENT_TIMEOUT 30000
|
||||
|
||||
class EQApplicationPacket;
|
||||
class EQStreamInterface;
|
||||
|
||||
class Client {
|
||||
public:
|
||||
Client(EQStreamInterface* ieqs);
|
||||
~Client();
|
||||
|
||||
bool Process();
|
||||
void ReceiveData(uchar* buf, int len);
|
||||
void SendCharInfo();
|
||||
void SendMaxCharCreate(int max_chars);
|
||||
void SendMembership();
|
||||
void SendMembershipSettings();
|
||||
void EnterWorld(bool TryBootup = true);
|
||||
void ZoneUnavail();
|
||||
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true);
|
||||
void Clearance(int8 response);
|
||||
void SendGuildList();
|
||||
void SendEnterWorld(std::string name);
|
||||
void SendExpansionInfo();
|
||||
void SendLogServer();
|
||||
void SendApproveWorld();
|
||||
void SendPostEnterWorld();
|
||||
bool GenPassKey(char* key);
|
||||
|
||||
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 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; }
|
||||
inline uint32 GetWID() { if (cle) { return cle->GetID(); } return 0; }
|
||||
inline uint32 GetLSID() { if (cle) { return cle->LSID(); } return 0; }
|
||||
inline const char* GetLSKey() { if (cle) { return cle->GetLSKey(); } return "NOKEY"; }
|
||||
inline uint32 GetCharID() { return charid; }
|
||||
inline const char* GetCharName() { return char_name; }
|
||||
inline ClientListEntry* GetCLE() { return cle; }
|
||||
inline void SetCLE(ClientListEntry* iCLE) { cle = iCLE; }
|
||||
private:
|
||||
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
uint32 charid;
|
||||
char char_name[64];
|
||||
uint32 zoneID;
|
||||
uint32 instanceID;
|
||||
bool pZoning;
|
||||
Timer autobootup_timeout;
|
||||
uint32 pwaitingforbootup;
|
||||
|
||||
bool StartInTutorial;
|
||||
uint32 ClientVersionBit;
|
||||
bool OPCharCreate(char *name, CharCreate_Struct *cc);
|
||||
|
||||
void SetClassStartingSkills( PlayerProfile_Struct *pp );
|
||||
void SetRaceStartingSkills( PlayerProfile_Struct *pp );
|
||||
void SetRacialLanguages( PlayerProfile_Struct *pp );
|
||||
|
||||
ClientListEntry* cle;
|
||||
Timer CLE_keepalive_timer;
|
||||
Timer connect;
|
||||
bool firstlogin;
|
||||
bool seencharsel;
|
||||
bool realfirstlogin;
|
||||
bool HandlePacket(const EQApplicationPacket *app);
|
||||
EQStreamInterface* const eqs;
|
||||
};
|
||||
|
||||
|
||||
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc);
|
||||
bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,326 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2005 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
|
||||
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/debug.h"
|
||||
#include "cliententry.h"
|
||||
#include "clientlist.h"
|
||||
#include "LoginServer.h"
|
||||
#include "LoginServerList.h"
|
||||
#include "worlddb.h"
|
||||
#include "zoneserver.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "../common/guilds.h"
|
||||
|
||||
extern uint32 numplayers;
|
||||
extern LoginServerList loginserverlist;
|
||||
extern ClientList client_list;
|
||||
extern volatile bool RunLoops;
|
||||
|
||||
ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local)
|
||||
: id(in_id)
|
||||
{
|
||||
ClearVars(true);
|
||||
|
||||
pIP = ip;
|
||||
pLSID = iLSID;
|
||||
if(iLSID > 0)
|
||||
paccountid = database.GetAccountIDFromLSID(iLSID, paccountname, &padmin);
|
||||
strn0cpy(plsname, iLoginName, sizeof(plsname));
|
||||
strn0cpy(plskey, iLoginKey, sizeof(plskey));
|
||||
pworldadmin = iWorldAdmin;
|
||||
plocal=(local==1);
|
||||
|
||||
pinstance = 0;
|
||||
}
|
||||
|
||||
ClientListEntry::ClientListEntry(uint32 in_id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin)
|
||||
: id(in_id)
|
||||
{
|
||||
ClearVars(true);
|
||||
|
||||
pIP = 0;
|
||||
pLSID = 0;
|
||||
pworldadmin = 0;
|
||||
|
||||
paccountid = iAccID;
|
||||
strn0cpy(paccountname, iAccName, sizeof(paccountname));
|
||||
pMD5Pass = iMD5Pass;
|
||||
padmin = iAdmin;
|
||||
|
||||
pinstance = 0;
|
||||
}
|
||||
|
||||
ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline)
|
||||
: id(in_id)
|
||||
{
|
||||
ClearVars(true);
|
||||
|
||||
pIP = 0;
|
||||
pLSID = scl->LSAccountID;
|
||||
strn0cpy(plsname, scl->name, sizeof(plsname));
|
||||
strn0cpy(plskey, scl->lskey, sizeof(plskey));
|
||||
pworldadmin = 0;
|
||||
|
||||
paccountid = scl->AccountID;
|
||||
strn0cpy(paccountname, scl->AccountName, sizeof(paccountname));
|
||||
padmin = scl->Admin;
|
||||
|
||||
pinstance = 0;
|
||||
|
||||
if (iOnline >= CLE_Status_Zoning)
|
||||
Update(iZS, scl, iOnline);
|
||||
else
|
||||
SetOnline(iOnline);
|
||||
}
|
||||
|
||||
ClientListEntry::~ClientListEntry() {
|
||||
if (RunLoops) {
|
||||
Camp(); // updates zoneserver's numplayers
|
||||
client_list.RemoveCLEReferances(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) {
|
||||
pcharid = iCharID;
|
||||
strn0cpy(pname, iCharName, sizeof(pname));
|
||||
}
|
||||
|
||||
void ClientListEntry::SetOnline(ZoneServer* iZS, int8 iOnline) {
|
||||
if (iZS == this->Server())
|
||||
SetOnline(iOnline);
|
||||
}
|
||||
|
||||
void ClientListEntry::SetOnline(int8 iOnline) {
|
||||
if (iOnline >= CLE_Status_Online && pOnline < CLE_Status_Online)
|
||||
numplayers++;
|
||||
else if (iOnline < CLE_Status_Online && pOnline >= CLE_Status_Online) {
|
||||
numplayers--;
|
||||
}
|
||||
if (iOnline != CLE_Status_Online || pOnline < CLE_Status_Online)
|
||||
pOnline = iOnline;
|
||||
if (iOnline < CLE_Status_Zoning)
|
||||
Camp();
|
||||
if (pOnline >= CLE_Status_Online)
|
||||
stale = 0;
|
||||
}
|
||||
void ClientListEntry::LSUpdate(ZoneServer* iZS){
|
||||
if(WorldConfig::get()->UpdateStats){
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
pack->opcode = ServerOP_LSZoneInfo;
|
||||
pack->size = sizeof(ZoneInfo_Struct);
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
ZoneInfo_Struct* zone =(ZoneInfo_Struct*)pack->pBuffer;
|
||||
zone->count=iZS->NumPlayers();
|
||||
zone->zone = iZS->GetZoneID();
|
||||
zone->zone_wid = iZS->GetID();
|
||||
loginserverlist.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
}
|
||||
void ClientListEntry::LSZoneChange(ZoneToZone_Struct* ztz){
|
||||
if(WorldConfig::get()->UpdateStats){
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
pack->opcode = ServerOP_LSPlayerZoneChange;
|
||||
pack->size = sizeof(ServerLSPlayerZoneChange_Struct);
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
ServerLSPlayerZoneChange_Struct* zonechange =(ServerLSPlayerZoneChange_Struct*)pack->pBuffer;
|
||||
zonechange->lsaccount_id = LSID();
|
||||
zonechange->from = ztz->current_zone_id;
|
||||
zonechange->to = ztz->requested_zone_id;
|
||||
loginserverlist.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
}
|
||||
void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) {
|
||||
if (pzoneserver != iZS) {
|
||||
if (pzoneserver){
|
||||
pzoneserver->RemovePlayer();
|
||||
LSUpdate(pzoneserver);
|
||||
}
|
||||
if (iZS){
|
||||
iZS->AddPlayer();
|
||||
LSUpdate(iZS);
|
||||
}
|
||||
}
|
||||
pzoneserver = iZS;
|
||||
pzone = scl->zone;
|
||||
pinstance = scl->instance_id;
|
||||
pcharid = scl->charid;
|
||||
|
||||
strcpy(pname, scl->name);
|
||||
if (paccountid == 0) {
|
||||
paccountid = scl->AccountID;
|
||||
strcpy(paccountname, scl->AccountName);
|
||||
strcpy(plsname, scl->AccountName);
|
||||
pIP = scl->IP;
|
||||
pLSID = scl->LSAccountID;
|
||||
strn0cpy(plskey, scl->lskey, sizeof(plskey));
|
||||
}
|
||||
padmin = scl->Admin;
|
||||
plevel = scl->level;
|
||||
pclass_ = scl->class_;
|
||||
prace = scl->race;
|
||||
panon = scl->anon;
|
||||
ptellsoff = scl->tellsoff;
|
||||
pguild_id = scl->guild_id;
|
||||
pLFG = scl->LFG;
|
||||
gm = scl->gm;
|
||||
pClientVersion = scl->ClientVersion;
|
||||
|
||||
// Fields from the LFG Window
|
||||
if((scl->LFGFromLevel != 0) && (scl->LFGToLevel != 0)) {
|
||||
pLFGFromLevel = scl->LFGFromLevel;
|
||||
pLFGToLevel = scl->LFGToLevel;
|
||||
pLFGMatchFilter = scl->LFGMatchFilter;
|
||||
memcpy(pLFGComments, scl->LFGComments, sizeof(pLFGComments));
|
||||
}
|
||||
|
||||
SetOnline(iOnline);
|
||||
}
|
||||
|
||||
void ClientListEntry::LeavingZone(ZoneServer* iZS, int8 iOnline) {
|
||||
if (iZS != 0 && iZS != pzoneserver)
|
||||
return;
|
||||
SetOnline(iOnline);
|
||||
|
||||
if (pzoneserver){
|
||||
pzoneserver->RemovePlayer();
|
||||
LSUpdate(pzoneserver);
|
||||
}
|
||||
pzoneserver = 0;
|
||||
pzone = 0;
|
||||
}
|
||||
|
||||
void ClientListEntry::ClearVars(bool iAll) {
|
||||
if (iAll) {
|
||||
pOnline = CLE_Status_Never;
|
||||
stale = 0;
|
||||
|
||||
pLSID = 0;
|
||||
memset(plsname, 0, sizeof(plsname));
|
||||
memset(plskey, 0, sizeof(plskey));
|
||||
pworldadmin = 0;
|
||||
|
||||
paccountid = 0;
|
||||
memset(paccountname, 0, sizeof(paccountname));
|
||||
padmin = 0;
|
||||
}
|
||||
pzoneserver = 0;
|
||||
pzone = 0;
|
||||
pcharid = 0;
|
||||
memset(pname, 0, sizeof(pname));
|
||||
plevel = 0;
|
||||
pclass_ = 0;
|
||||
prace = 0;
|
||||
panon = 0;
|
||||
ptellsoff = 0;
|
||||
pguild_id = GUILD_NONE;
|
||||
pLFG = 0;
|
||||
gm = 0;
|
||||
pClientVersion = 0;
|
||||
}
|
||||
|
||||
void ClientListEntry::Camp(ZoneServer* iZS) {
|
||||
if (iZS != 0 && iZS != pzoneserver)
|
||||
return;
|
||||
if (pzoneserver){
|
||||
pzoneserver->RemovePlayer();
|
||||
LSUpdate(pzoneserver);
|
||||
}
|
||||
|
||||
ClearVars();
|
||||
|
||||
stale = 0;
|
||||
}
|
||||
|
||||
bool ClientListEntry::CheckStale() {
|
||||
stale++;
|
||||
if (stale >= 3) {
|
||||
if (pOnline > CLE_Status_Offline)
|
||||
SetOnline(CLE_Status_Offline);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) {
|
||||
// if (LSID() == iLSID && strncmp(plskey, iKey,10) == 0) {
|
||||
if (strncmp(plskey, iKey,10) == 0) {
|
||||
if (paccountid == 0 && LSID()>0) {
|
||||
int16 tmpStatus = WorldConfig::get()->DefaultStatus;
|
||||
paccountid = database.CreateAccount(plsname, 0, tmpStatus, LSID());
|
||||
if (!paccountid) {
|
||||
_log(WORLD__CLIENTLIST_ERR,"Error adding local account for LS login: '%s', duplicate name?" ,plsname);
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientListEntry::CheckAuth(const char* iName, MD5& iMD5Password) {
|
||||
if (LSAccountID() == 0 && strcmp(paccountname, iName) == 0 && pMD5Pass == iMD5Password)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientListEntry::CheckAuth(uint32 id, const char* iKey, uint32 ip) {
|
||||
if (pIP==ip && strncmp(plskey, iKey,10) == 0){
|
||||
paccountid = id;
|
||||
database.GetAccountFromID(id,paccountname,&padmin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#ifndef CLIENTENTRY_H_
|
||||
#define CLIENTENTRY_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/md5.h"
|
||||
//#include "../common/eq_packet_structs.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
|
||||
#define CLE_Status_Never -1
|
||||
#define CLE_Status_Offline 0
|
||||
#define CLE_Status_Online 1 // Will not overwrite more specific online status
|
||||
#define CLE_Status_CharSelect 2
|
||||
#define CLE_Status_Zoning 3
|
||||
#define CLE_Status_InZone 4
|
||||
|
||||
class ZoneServer;
|
||||
struct ServerClientList_Struct;
|
||||
|
||||
class ClientListEntry {
|
||||
public:
|
||||
ClientListEntry(uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0);
|
||||
ClientListEntry(uint32 id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin = 0);
|
||||
ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline);
|
||||
~ClientListEntry();
|
||||
bool CheckStale();
|
||||
void Update(ZoneServer* zoneserver, ServerClientList_Struct* scl, int8 iOnline = CLE_Status_InZone);
|
||||
void LSUpdate(ZoneServer* zoneserver);
|
||||
void LSZoneChange(ZoneToZone_Struct* ztz);
|
||||
bool CheckAuth(uint32 iLSID, const char* key);
|
||||
bool CheckAuth(const char* iName, MD5& iMD5Password);
|
||||
bool CheckAuth(uint32 id, const char* key, uint32 ip);
|
||||
void SetOnline(ZoneServer* iZS, int8 iOnline);
|
||||
void SetOnline(int8 iOnline = CLE_Status_Online);
|
||||
void SetChar(uint32 iCharID, const char* iCharName);
|
||||
inline int8 Online() { return pOnline; }
|
||||
inline const uint32 GetID() const { return id; }
|
||||
inline const uint32 GetIP() const { return pIP; }
|
||||
inline void SetIP(const uint32& iIP) { pIP = iIP; }
|
||||
inline void KeepAlive() { stale = 0; }
|
||||
inline uint8 GetStaleCounter() const { return stale; }
|
||||
void LeavingZone(ZoneServer* iZS = 0, int8 iOnline = CLE_Status_Offline);
|
||||
void Camp(ZoneServer* iZS = 0);
|
||||
|
||||
// Login Server stuff
|
||||
inline uint32 LSID() const { return pLSID; }
|
||||
inline uint32 LSAccountID() const { return pLSID; }
|
||||
inline const char* LSName() const { return plsname; }
|
||||
inline int16 WorldAdmin() const { return pworldadmin; }
|
||||
inline const char* GetLSKey() const { return plskey; }
|
||||
|
||||
// Account stuff
|
||||
inline uint32 AccountID() const { return paccountid; }
|
||||
inline const char* AccountName() const { return paccountname; }
|
||||
inline int16 Admin() const { return padmin; }
|
||||
inline void SetAdmin(uint16 iAdmin) { padmin = iAdmin; }
|
||||
|
||||
// Character info
|
||||
inline ZoneServer* Server() const { return pzoneserver; }
|
||||
inline void ClearServer() { pzoneserver = 0; }
|
||||
inline uint32 CharID() const { return pcharid; }
|
||||
inline const char* name() const { return pname; }
|
||||
inline uint32 zone() const { return pzone; }
|
||||
inline uint16 instance() const { return pinstance; }
|
||||
inline uint8 level() const { return plevel; }
|
||||
inline uint8 class_() const { return pclass_; }
|
||||
inline uint16 race() const { return prace; }
|
||||
inline uint8 Anon() { return panon; }
|
||||
inline uint8 TellsOff() const { return ptellsoff; }
|
||||
inline uint32 GuildID() const { return pguild_id; }
|
||||
inline void SetGuild(uint32 guild_id) { pguild_id = guild_id; }
|
||||
inline bool LFG() const { return pLFG; }
|
||||
inline uint8 GetGM() const { return gm; }
|
||||
inline void SetGM(uint8 igm) { gm = igm; }
|
||||
inline void SetZone(uint32 zone) { pzone = zone; }
|
||||
inline bool IsLocalClient() const { return plocal; }
|
||||
inline uint8 GetLFGFromLevel() const { return pLFGFromLevel; }
|
||||
inline uint8 GetLFGToLevel() const { return pLFGToLevel; }
|
||||
inline bool GetLFGMatchFilter() const { return pLFGMatchFilter; }
|
||||
inline const char* GetLFGComments() const { return pLFGComments; }
|
||||
inline uint8 GetClientVersion() { return pClientVersion; }
|
||||
|
||||
private:
|
||||
void ClearVars(bool iAll = false);
|
||||
|
||||
const uint32 id;
|
||||
uint32 pIP;
|
||||
int8 pOnline;
|
||||
uint8 stale;
|
||||
|
||||
// Login Server stuff
|
||||
uint32 pLSID;
|
||||
char plsname[32];
|
||||
char plskey[16];
|
||||
int16 pworldadmin; // Login server's suggested admin status setting
|
||||
bool plocal;
|
||||
|
||||
// Account stuff
|
||||
uint32 paccountid;
|
||||
char paccountname[32];
|
||||
MD5 pMD5Pass;
|
||||
int16 padmin;
|
||||
|
||||
// Character info
|
||||
ZoneServer* pzoneserver;
|
||||
uint32 pzone;
|
||||
uint16 pinstance;
|
||||
uint32 pcharid;
|
||||
char pname[64];
|
||||
uint8 plevel;
|
||||
uint8 pclass_;
|
||||
uint16 prace;
|
||||
uint8 panon;
|
||||
uint8 ptellsoff;
|
||||
uint32 pguild_id;
|
||||
bool pLFG;
|
||||
uint8 gm;
|
||||
uint8 pClientVersion;
|
||||
uint8 pLFGFromLevel;
|
||||
uint8 pLFGToLevel;
|
||||
bool pLFGMatchFilter;
|
||||
char pLFGComments[64];
|
||||
};
|
||||
|
||||
|
||||
#endif /*CLIENTENTRY_H_*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,85 @@
|
||||
#ifndef CLIENTLIST_H_
|
||||
#define CLIENTLIST_H_
|
||||
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class Client;
|
||||
class ZoneServer;
|
||||
class WorldTCPConnection;
|
||||
class ClientListEntry;
|
||||
class ServerPacket;
|
||||
struct ServerClientList_Struct;
|
||||
|
||||
class ClientList {
|
||||
public:
|
||||
ClientList();
|
||||
~ClientList();
|
||||
|
||||
void Process();
|
||||
|
||||
//from old ClientList
|
||||
void Add(Client* client);
|
||||
Client* Get(uint32 ip, uint16 port);
|
||||
Client* FindByAccountID(uint32 account_id);
|
||||
Client* FindByName(char* charname);
|
||||
|
||||
void ZoneBootup(ZoneServer* zs);
|
||||
void RemoveCLEReferances(ClientListEntry* cle);
|
||||
|
||||
|
||||
//from ZSList
|
||||
|
||||
void SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_Struct* whom, WorldTCPConnection* connection);
|
||||
void SendFriendsWho(ServerFriendsWho_Struct *FriendsWho, WorldTCPConnection* connection);
|
||||
void SendOnlineGuildMembers(uint32 FromID, uint32 GuildID);
|
||||
void SendClientVersionSummary(const char *Name);
|
||||
void SendLFGMatches(ServerLFGMatchesRequest_Struct *LFGMatchesRequest);
|
||||
void ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct* whom, WorldTCPConnection* connection);
|
||||
void SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* iName = 0);
|
||||
|
||||
bool SendPacket(const char* to, ServerPacket* pack);
|
||||
void SendGuildPacket(uint32 guild_id, ServerPacket* pack);
|
||||
|
||||
void ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* scl);
|
||||
void CLERemoveZSRef(ZoneServer* iZS);
|
||||
ClientListEntry* CheckAuth(uint32 iLSID, const char* iKey);
|
||||
ClientListEntry* CheckAuth(const char* iName, const char* iPassword);
|
||||
ClientListEntry* CheckAuth(uint32 id, const char* iKey, uint32 ip);
|
||||
ClientListEntry* FindCharacter(const char* name);
|
||||
ClientListEntry* FindCLEByAccountID(uint32 iAccID);
|
||||
ClientListEntry* FindCLEByCharacterID(uint32 iCharID);
|
||||
ClientListEntry* GetCLE(uint32 iID);
|
||||
void GetCLEIP(uint32 iIP);
|
||||
void DisconnectByIP(uint32 iIP);
|
||||
void EnforceSessionLimit(uint32 iLSAccountID);
|
||||
void CLCheckStale();
|
||||
void CLEKeepAlive(uint32 numupdates, uint32* wid);
|
||||
void CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0);
|
||||
void UpdateClientGuild(uint32 char_id, uint32 guild_id);
|
||||
|
||||
int GetClientCount();
|
||||
void GetClients(const char *zone_name, std::vector<ClientListEntry *> &into);
|
||||
|
||||
protected:
|
||||
inline uint32 GetNextCLEID() { return NextCLEID++; }
|
||||
|
||||
//this is the list of people actively connected to zone
|
||||
LinkedList<Client*> list;
|
||||
|
||||
//this is the list of people in any zone, not nescesarily connected to world
|
||||
Timer CLStale_timer;
|
||||
uint32 NextCLEID;
|
||||
LinkedList<ClientListEntry *> clientlist;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*CLIENTLIST_H_*/
|
||||
@@ -0,0 +1,843 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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/debug.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "../common/version.h"
|
||||
#include "console.h"
|
||||
#include "zoneserver.h"
|
||||
#include "worlddb.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/seperator.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/EQPacket.h"
|
||||
#include "LoginServer.h"
|
||||
#include "LoginServerList.h"
|
||||
#include "../common/serverinfo.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/opcodemgr.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/ruletypes.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "zoneserver.h"
|
||||
#include "zonelist.h"
|
||||
#include "clientlist.h"
|
||||
#include "LauncherList.h"
|
||||
#include "ucs.h"
|
||||
#include "queryserv.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
#if (_MSC_VER < 1500)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
extern uint32 numzones;
|
||||
extern LoginServerList loginserverlist;
|
||||
extern ClientList client_list;
|
||||
extern LauncherList launcher_list;
|
||||
extern UCSConnection UCSLink;
|
||||
extern QueryServConnection QSLink;
|
||||
extern volatile bool RunLoops;
|
||||
|
||||
ConsoleList console_list;
|
||||
|
||||
Console::Console(EmuTCPConnection* itcpc)
|
||||
: WorldTCPConnection(),
|
||||
timeout_timer(RuleI(Console, SessionTimeOut)),
|
||||
prompt_timer(1000)
|
||||
{
|
||||
tcpc = itcpc;
|
||||
tcpc->SetEcho(true);
|
||||
state = 0;
|
||||
paccountid = 0;
|
||||
memset(paccountname, 0, sizeof(paccountname));
|
||||
admin = 0;
|
||||
pAcceptMessages = false;
|
||||
}
|
||||
|
||||
Console::~Console() {
|
||||
if (tcpc)
|
||||
tcpc->Free();
|
||||
}
|
||||
|
||||
void Console::Die() {
|
||||
state = CONSOLE_STATE_CLOSED;
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(WORLD__CONSOLE,"Removing console from %s:%d",inet_ntoa(in),GetPort());
|
||||
tcpc->Disconnect();
|
||||
}
|
||||
|
||||
bool Console::SendChannelMessage(const ServerChannelMessage_Struct* scm) {
|
||||
if (!pAcceptMessages)
|
||||
return false;
|
||||
switch (scm->chan_num) {
|
||||
if(RuleB(Chat, ServerWideAuction)){
|
||||
case 4: {
|
||||
SendMessage(1, "%s auctions, '%s'", scm->from, scm->message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(RuleB(Chat, ServerWideOOC)){
|
||||
case 5: {
|
||||
SendMessage(1, "%s says ooc, '%s'", scm->from, scm->message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 6: {
|
||||
SendMessage(1, "%s BROADCASTS, '%s'", scm->from, scm->message);
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
SendMessage(1, "%s tells you, '%s'", scm->from, scm->message);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
|
||||
memcpy(pack->pBuffer, scm, pack->size);
|
||||
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*) pack->pBuffer;
|
||||
strcpy(scm2->deliverto, scm2->from);
|
||||
scm2->noreply = true;
|
||||
client_list.SendPacket(scm->from, pack);
|
||||
safe_delete(pack);
|
||||
break;
|
||||
}
|
||||
case 11: {
|
||||
SendMessage(1, "%s GMSAYS, '%s'", scm->from, scm->message);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::SendEmoteMessage(uint32 type, const char* message, ...) {
|
||||
if (!message)
|
||||
return false;
|
||||
if (!pAcceptMessages)
|
||||
return false;
|
||||
va_list argptr;
|
||||
char buffer[1024];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, sizeof(buffer), message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SendMessage(1, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::SendEmoteMessageRaw(uint32 type, const char* message) {
|
||||
if (!message)
|
||||
return false;
|
||||
if (!pAcceptMessages)
|
||||
return false;
|
||||
SendMessage(1, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Console::SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...) {
|
||||
if (!message)
|
||||
return;
|
||||
if (to_guilddbid != 0 || to_minstatus > Admin())
|
||||
return;
|
||||
va_list argptr;
|
||||
char buffer[1024];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, sizeof(buffer), message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SendEmoteMessageRaw(to, to_guilddbid, to_minstatus, type, buffer);
|
||||
}
|
||||
|
||||
void Console::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message) {
|
||||
if (!message)
|
||||
return;
|
||||
if (to_guilddbid != 0 || to_minstatus > Admin())
|
||||
return;
|
||||
SendMessage(1, message);
|
||||
}
|
||||
|
||||
void Console::SendMessage(uint8 newline, const char* message, ...) {
|
||||
if (!message)
|
||||
return;
|
||||
char* buffer = 0;
|
||||
uint32 bufsize = 1500;
|
||||
if (message)
|
||||
bufsize += strlen(message);
|
||||
buffer = new char[bufsize];
|
||||
memset(buffer, 0, bufsize);
|
||||
if (message != 0) {
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, bufsize - 512, message, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
if (newline) {
|
||||
char outbuf[3];
|
||||
outbuf[0] = 13;
|
||||
outbuf[1] = 10;
|
||||
outbuf[2] = 0;
|
||||
for (int i=0; i < newline; i++)
|
||||
strcat(buffer, outbuf);
|
||||
}
|
||||
tcpc->Send((uchar*) buffer, strlen(buffer));
|
||||
safe_delete_array(buffer);
|
||||
}
|
||||
|
||||
bool Console::Process() {
|
||||
if (state == CONSOLE_STATE_CLOSED)
|
||||
return false;
|
||||
|
||||
if (!tcpc->Connected()) {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(WORLD__CONSOLE,"Removing console (!tcpc->Connected) from %s:%d",inet_ntoa(in),GetPort());
|
||||
return false;
|
||||
}
|
||||
//if we have not gotten the special markers after this timer, send login prompt
|
||||
if(prompt_timer.Check()) {
|
||||
prompt_timer.Disable();
|
||||
if(tcpc->GetMode() == EmuTCPConnection::modeConsole)
|
||||
tcpc->Send((const uchar*) "Username: ", strlen("Username: "));
|
||||
}
|
||||
|
||||
if (timeout_timer.Check()) {
|
||||
SendMessage(1, 0);
|
||||
SendMessage(1, "Timeout, disconnecting...");
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(WORLD__CONSOLE,"TCP connection timeout from %s:%d",inet_ntoa(in),GetPort());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tcpc->GetMode() == EmuTCPConnection::modePacket) {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) {
|
||||
ZoneServer* zs = new ZoneServer(tcpc);
|
||||
_log(WORLD__CONSOLE,"New zoneserver #%d from %s:%d", zs->GetID(), inet_ntoa(in), GetPort());
|
||||
zoneserver_list.Add(zs);
|
||||
numzones++;
|
||||
tcpc = 0;
|
||||
} else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) {
|
||||
_log(WORLD__CONSOLE,"New launcher from %s:%d", inet_ntoa(in), GetPort());
|
||||
launcher_list.Add(tcpc);
|
||||
tcpc = 0;
|
||||
} else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS)
|
||||
{
|
||||
_log(WORLD__CONSOLE,"New UCS Connection from %s:%d", inet_ntoa(in), GetPort());
|
||||
UCSLink.SetConnection(tcpc);
|
||||
tcpc = 0;
|
||||
}
|
||||
else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeQueryServ)
|
||||
{
|
||||
_log(WORLD__CONSOLE,"New QS Connection from %s:%d", inet_ntoa(in), GetPort());
|
||||
QSLink.SetConnection(tcpc);
|
||||
tcpc = 0;
|
||||
} else {
|
||||
_log(WORLD__CONSOLE,"Unsupported packet mode from %s:%d", inet_ntoa(in), GetPort());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
char* command = 0;
|
||||
while ((command = tcpc->PopLine())) {
|
||||
timeout_timer.Start();
|
||||
ProcessCommand(command);
|
||||
delete command;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConsoleList::Add(Console* con) {
|
||||
list.Insert(con);
|
||||
}
|
||||
|
||||
void ConsoleList::Process() {
|
||||
LinkedListIterator<Console*> iterator(list);
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
if (!iterator.GetData()->Process())
|
||||
iterator.RemoveCurrent();
|
||||
else
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleList::KillAll() {
|
||||
LinkedListIterator<Console*> iterator(list);
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
iterator.GetData()->Die();
|
||||
iterator.RemoveCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleList::SendConsoleWho(WorldTCPConnection* connection, const char* to, int16 admin, char** output, uint32* outsize, uint32* outlen) {
|
||||
LinkedListIterator<Console*> iterator(list);
|
||||
iterator.Reset();
|
||||
struct in_addr in;
|
||||
int x = 0;
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
in.s_addr = iterator.GetData()->GetIP();
|
||||
if (admin >= iterator.GetData()->Admin())
|
||||
AppendAnyLenString(output, outsize, outlen, " Console: %s:%i AccID: %i AccName: %s", inet_ntoa(in), iterator.GetData()->GetPort(), iterator.GetData()->AccountID(), iterator.GetData()->AccountName());
|
||||
else
|
||||
AppendAnyLenString(output, outsize, outlen, " Console: AccID: %i AccName: %s", iterator.GetData()->AccountID(), iterator.GetData()->AccountName());
|
||||
if (*outlen >= 3584) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, *output);
|
||||
safe_delete(*output);
|
||||
*outsize = 0;
|
||||
*outlen = 0;
|
||||
}
|
||||
else {
|
||||
if (connection->IsConsole())
|
||||
AppendAnyLenString(output, outsize, outlen, "\r\n");
|
||||
else
|
||||
AppendAnyLenString(output, outsize, outlen, "\n");
|
||||
}
|
||||
x++;
|
||||
iterator.Advance();
|
||||
}
|
||||
AppendAnyLenString(output, outsize, outlen, "%i consoles connected", x);
|
||||
}
|
||||
|
||||
void ConsoleList::SendChannelMessage(const ServerChannelMessage_Struct* scm) {
|
||||
LinkedListIterator<Console*> iterator(list);
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
iterator.GetData()->SendChannelMessage(scm);
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleList::SendEmoteMessage(uint32 type, const char* message, ...) {
|
||||
va_list argptr;
|
||||
char buffer[1024];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, sizeof(buffer), message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SendEmoteMessageRaw(type, buffer);
|
||||
}
|
||||
|
||||
void ConsoleList::SendEmoteMessageRaw(uint32 type, const char* message) {
|
||||
LinkedListIterator<Console*> iterator(list);
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
iterator.GetData()->SendEmoteMessageRaw(type, message);
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
Console* ConsoleList::FindByAccountName(const char* accname) {
|
||||
LinkedListIterator<Console*> iterator(list);
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
if (strcasecmp(iterator.GetData()->AccountName(), accname) == 0)
|
||||
return iterator.GetData();
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Console::ProcessCommand(const char* command) {
|
||||
switch(state)
|
||||
{
|
||||
case CONSOLE_STATE_USERNAME:
|
||||
{
|
||||
if (strlen(command) >= 16) {
|
||||
SendMessage(1, 0);
|
||||
SendMessage(2, "Username buffer overflow.");
|
||||
SendMessage(1, "Bye Bye.");
|
||||
state = CONSOLE_STATE_CLOSED;
|
||||
return;
|
||||
}
|
||||
strcpy(paccountname, command);
|
||||
state = CONSOLE_STATE_PASSWORD;
|
||||
SendMessage(0, "Password: ");
|
||||
tcpc->SetEcho(false);
|
||||
break;
|
||||
}
|
||||
case CONSOLE_STATE_PASSWORD:
|
||||
{
|
||||
if (strlen(command) >= 16) {
|
||||
SendMessage(1, 0);
|
||||
SendMessage(2, "Password buffer overflow.");
|
||||
SendMessage(1, "Bye Bye.");
|
||||
state = CONSOLE_STATE_CLOSED;
|
||||
return;
|
||||
}
|
||||
paccountid = database.CheckLogin(paccountname,command);
|
||||
if (paccountid == 0) {
|
||||
SendMessage(1, 0);
|
||||
SendMessage(2, "Login failed.");
|
||||
SendMessage(1, "Bye Bye.");
|
||||
state = CONSOLE_STATE_CLOSED;
|
||||
return;
|
||||
}
|
||||
database.GetAccountName(paccountid, paccountname); // fixes case and stuff
|
||||
admin = database.CheckStatus(paccountid);
|
||||
if (!(admin >= consoleLoginStatus)) {
|
||||
SendMessage(1, 0);
|
||||
SendMessage(2, "Access denied.");
|
||||
SendMessage(1, "Bye Bye.");
|
||||
state = CONSOLE_STATE_CLOSED;
|
||||
return;
|
||||
}
|
||||
_log(WORLD__CONSOLE,"TCP console authenticated: Username=%s, Admin=%d",paccountname,admin);
|
||||
SendMessage(1, 0);
|
||||
SendMessage(2, "Login accepted.");
|
||||
state = CONSOLE_STATE_CONNECTED;
|
||||
tcpc->SetEcho(true);
|
||||
SendPrompt();
|
||||
break;
|
||||
}
|
||||
case CONSOLE_STATE_CONNECTED: {
|
||||
_log(WORLD__CONSOLE,"TCP command: %s: \"%s\"",paccountname,command);
|
||||
Seperator sep(command);
|
||||
if (strcasecmp(sep.arg[0], "help") == 0 || strcmp(sep.arg[0], "?") == 0) {
|
||||
SendMessage(1, " whoami");
|
||||
SendMessage(1, " who");
|
||||
SendMessage(1, " zonestatus");
|
||||
SendMessage(1, " uptime [zoneID#]");
|
||||
SendMessage(1, " emote [zonename or charname or world] [type] [message]");
|
||||
SendMessage(1, " echo [on/off]");
|
||||
SendMessage(1, " acceptmessages [on/off]");
|
||||
SendMessage(1, " tell [name] [message]");
|
||||
SendMessage(1, " broadcast [message]");
|
||||
SendMessage(1, " gmsay [message]");
|
||||
SendMessage(1, " ooc [message]");
|
||||
SendMessage(1, " auction [message]");
|
||||
if (admin >= consoleKickStatus)
|
||||
SendMessage(1, " kick [charname]");
|
||||
if (admin >= consoleLockStatus)
|
||||
SendMessage(1, " lock/unlock");
|
||||
if (admin >= consoleZoneStatus) {
|
||||
SendMessage(1, " zoneshutdown [zonename or ZoneServerID]");
|
||||
SendMessage(1, " zonebootup [ZoneServerID] [zonename]");
|
||||
SendMessage(1, " zonelock [list|lock|unlock] [zonename]");
|
||||
}
|
||||
if (admin >= consoleFlagStatus)
|
||||
SendMessage(1, " flag [status] [accountname]");
|
||||
if (admin >= consolePassStatus)
|
||||
SendMessage(1, " setpass [accountname] [newpass]");
|
||||
if (admin >= consoleWorldStatus) {
|
||||
SendMessage(1, " version");
|
||||
SendMessage(1, " worldshutdown");
|
||||
}
|
||||
if (admin >= 201) {
|
||||
SendMessage(1, " IPLookup [name]");
|
||||
}
|
||||
if (admin >= 100) {
|
||||
SendMessage(1, " LSReconnect");
|
||||
SendMessage(1, " signalcharbyname charname ID");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "ping") == 0) {
|
||||
// do nothing
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "signalcharbyname") == 0) {
|
||||
SendMessage(1, "Signal Sent to %s with ID %i", (char*) sep.arg[1], atoi(sep.arg[2]));
|
||||
uint32 message_len = strlen((char*) sep.arg[1]) + 1;
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_CZSignalClientByName, sizeof(CZClientSignalByName_Struct) + message_len);
|
||||
CZClientSignalByName_Struct* CZSC = (CZClientSignalByName_Struct*) pack->pBuffer;
|
||||
strn0cpy(CZSC->Name, (char*) sep.arg[1], 64);
|
||||
CZSC->data = atoi(sep.arg[2]);
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "setpass") == 0 && admin >= consolePassStatus) {
|
||||
if (sep.argnum != 2)
|
||||
SendMessage(1, "Format: setpass accountname password");
|
||||
else {
|
||||
|
||||
int16 tmpstatus = 0;
|
||||
uint32 tmpid = database.GetAccountIDByName(sep.arg[1], &tmpstatus);
|
||||
if (!tmpid)
|
||||
SendMessage(1, "Error: Account not found");
|
||||
else if (tmpstatus > admin)
|
||||
SendMessage(1, "Cannot change password: Account's status is higher than yours");
|
||||
else if (database.SetLocalPassword(tmpid, sep.arg[2]))
|
||||
SendMessage(1, "Password changed.");
|
||||
else
|
||||
SendMessage(1, "Error changing password.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "uptime") == 0) {
|
||||
if (sep.IsNumber(1) && atoi(sep.arg[1]) > 0) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct));
|
||||
ServerUptime_Struct* sus = (ServerUptime_Struct*) pack->pBuffer;
|
||||
snprintf(sus->adminname, sizeof(sus->adminname), "*%s", this->GetName());
|
||||
sus->zoneserverid = atoi(sep.arg[1]);
|
||||
ZoneServer* zs = zoneserver_list.FindByID(sus->zoneserverid);
|
||||
if (zs)
|
||||
zs->SendPacket(pack);
|
||||
else
|
||||
SendMessage(1, "Zoneserver not found.");
|
||||
delete pack;
|
||||
}
|
||||
else {
|
||||
ZSList::ShowUpTime(this);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "md5") == 0) {
|
||||
uint8 md5[16];
|
||||
MD5::Generate((const uchar*) sep.argplus[1], strlen(sep.argplus[1]), md5);
|
||||
SendMessage(1, "MD5: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "whoami") == 0) {
|
||||
SendMessage(1, "You are logged in as '%s'", this->AccountName());
|
||||
SendMessage(1, "You are known as '*%s'", this->AccountName());
|
||||
SendMessage(1, "AccessLevel: %d", this->Admin());
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "echo") == 0) {
|
||||
if (strcasecmp(sep.arg[1], "on") == 0)
|
||||
tcpc->SetEcho(true);
|
||||
else if (strcasecmp(sep.arg[1], "off") == 0) {
|
||||
if (pAcceptMessages)
|
||||
SendMessage(1, "Echo can not be turned off while acceptmessages is on");
|
||||
else
|
||||
tcpc->SetEcho(false);
|
||||
}
|
||||
else
|
||||
SendMessage(1, "Usage: echo [on/off]");
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "acceptmessages") == 0) {
|
||||
if (strcasecmp(sep.arg[1], "on") == 0)
|
||||
if (tcpc->GetEcho())
|
||||
SendMessage(1, "AcceptMessages can not be turned on while echo is on");
|
||||
else
|
||||
pAcceptMessages = true;
|
||||
else if (strcasecmp(sep.arg[1], "off") == 0)
|
||||
pAcceptMessages = false;
|
||||
else
|
||||
SendMessage(1, "Usage: acceptmessages [on/off]");
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "tell") == 0) {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
zoneserver_list.SendChannelMessage(tmpname, sep.arg[1], 7, 0, sep.argplus[2]);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "broadcast") == 0) {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
zoneserver_list.SendChannelMessage(tmpname, 0, 6, 0, sep.argplus[1]);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "ooc") == 0) {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
zoneserver_list.SendChannelMessage(tmpname, 0, 5, 0, sep.argplus[1]);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "auction") == 0) {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
zoneserver_list.SendChannelMessage(tmpname, 0, 4, 0, sep.argplus[1]);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "gmsay") == 0 || strcasecmp(sep.arg[0], "pr") == 0) {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
zoneserver_list.SendChannelMessage(tmpname, 0, 11, 0, sep.argplus[1]);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "emote") == 0) {
|
||||
if (strcasecmp(sep.arg[1], "world") == 0)
|
||||
zoneserver_list.SendEmoteMessageRaw(0, 0, 0, atoi(sep.arg[2]), sep.argplus[3]);
|
||||
else {
|
||||
ZoneServer* zs = zoneserver_list.FindByName(sep.arg[1]);
|
||||
if (zs != 0)
|
||||
zs->SendEmoteMessageRaw(0, 0, 0, atoi(sep.arg[2]), sep.argplus[3]);
|
||||
else
|
||||
zoneserver_list.SendEmoteMessageRaw(sep.arg[1], 0, 0, atoi(sep.arg[2]), sep.argplus[3]);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "movechar") == 0) {
|
||||
if(sep.arg[1][0]==0 || sep.arg[2][0] == 0)
|
||||
SendMessage(1, "Usage: movechar [charactername] [zonename]");
|
||||
else {
|
||||
if (!database.GetZoneID(sep.arg[2]))
|
||||
SendMessage(1, "Error: Zone '%s' not found", sep.arg[2]);
|
||||
else if (!database.CheckUsedName((char*) sep.arg[1])) {
|
||||
if (!database.MoveCharacterToZone((char*) sep.arg[1], (char*) sep.arg[2]))
|
||||
SendMessage(1, "Character Move Failed!");
|
||||
else
|
||||
SendMessage(1, "Character has been moved.");
|
||||
}
|
||||
else
|
||||
SendMessage(1, "Character Does Not Exist");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "flag") == 0 && this->Admin() >= consoleFlagStatus) {
|
||||
// SCORPIOUS2K - reversed parameter order for flag
|
||||
if(sep.arg[2][0]==0 || !sep.IsNumber(1))
|
||||
SendMessage(1, "Usage: flag [status] [accountname]");
|
||||
else
|
||||
{
|
||||
if (atoi(sep.arg[1]) > this->Admin())
|
||||
SendMessage(1, "You cannot set people's status to higher than your own");
|
||||
else if (atoi(sep.arg[1]) < 0 && this->Admin() < consoleFlagStatus)
|
||||
SendMessage(1, "You have too low of status to change flags");
|
||||
else if (!database.SetAccountStatus(sep.arg[2], atoi(sep.arg[1])))
|
||||
SendMessage(1, "Unable to flag account!");
|
||||
else
|
||||
SendMessage(1, "Account Flaged");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "kick") == 0 && admin >= consoleKickStatus) {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
pack->opcode = ServerOP_KickPlayer;
|
||||
pack->size = sizeof(ServerKickPlayer_Struct);
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer;
|
||||
strcpy(skp->adminname, tmpname);
|
||||
strcpy(skp->name, sep.arg[1]);
|
||||
skp->adminrank = this->Admin();
|
||||
zoneserver_list.SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "who") == 0) {
|
||||
Who_All_Struct* whom = new Who_All_Struct;
|
||||
memset(whom, 0, sizeof(Who_All_Struct));
|
||||
whom->lvllow = 0xFFFF;
|
||||
whom->lvlhigh = 0xFFFF;
|
||||
whom->wclass = 0xFFFF;
|
||||
whom->wrace = 0xFFFF;
|
||||
whom->gmlookup = 0xFFFF;
|
||||
for (int i=1; i<=sep.argnum; i++) {
|
||||
if (strcasecmp(sep.arg[i], "gm") == 0)
|
||||
whom->gmlookup = 1;
|
||||
else if (sep.IsNumber(i)) {
|
||||
if (whom->lvllow == 0xFFFF) {
|
||||
whom->lvllow = atoi(sep.arg[i]);
|
||||
whom->lvlhigh = whom->lvllow;
|
||||
}
|
||||
else if (atoi(sep.arg[i]) > int(whom->lvllow))
|
||||
whom->lvlhigh = atoi(sep.arg[i]);
|
||||
else
|
||||
whom->lvllow = atoi(sep.arg[i]);
|
||||
}
|
||||
else
|
||||
strn0cpy(whom->whom, sep.arg[i], sizeof(whom->whom));
|
||||
}
|
||||
client_list.ConsoleSendWhoAll(0, admin, whom, this);
|
||||
delete whom;
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "zonestatus") == 0) {
|
||||
zoneserver_list.SendZoneStatus(0, admin, this);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "exit") == 0 || strcasecmp(sep.arg[0], "quit") == 0) {
|
||||
SendMessage(1, "Bye Bye.");
|
||||
state = CONSOLE_STATE_CLOSED;
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "zoneshutdown") == 0 && admin >= consoleZoneStatus) {
|
||||
if (sep.arg[1][0] == 0) {
|
||||
SendMessage(1, "Usage: zoneshutdown zoneshortname");
|
||||
} else {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
pack->size = sizeof(ServerZoneStateChange_struct);
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
memset(pack->pBuffer, 0, sizeof(ServerZoneStateChange_struct));
|
||||
ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer;
|
||||
pack->opcode = ServerOP_ZoneShutdown;
|
||||
strcpy(s->adminname, tmpname);
|
||||
if (sep.arg[1][0] >= '0' && sep.arg[1][0] <= '9')
|
||||
s->ZoneServerID = atoi(sep.arg[1]);
|
||||
else
|
||||
s->zoneid = database.GetZoneID(sep.arg[1]);
|
||||
|
||||
ZoneServer* zs = 0;
|
||||
if (s->ZoneServerID != 0)
|
||||
zs = zoneserver_list.FindByID(s->ZoneServerID);
|
||||
else if (s->zoneid != 0)
|
||||
zs = zoneserver_list.FindByName(database.GetZoneName(s->zoneid));
|
||||
else
|
||||
SendMessage(1, "Error: ZoneShutdown: neither ID nor name specified");
|
||||
|
||||
if (zs == 0)
|
||||
SendMessage(1, "Error: ZoneShutdown: zoneserver not found");
|
||||
else
|
||||
zs->SendPacket(pack);
|
||||
|
||||
delete pack;
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "zonebootup") == 0 && admin >= consoleZoneStatus) {
|
||||
if (sep.arg[2][0] == 0 || !sep.IsNumber(1)) {
|
||||
SendMessage(1, "Usage: zonebootup ZoneServerID# zoneshortname");
|
||||
} else {
|
||||
char tmpname[64];
|
||||
tmpname[0] = '*';
|
||||
strcpy(&tmpname[1], paccountname);
|
||||
|
||||
_log(WORLD__CONSOLE,"Console ZoneBootup: %s, %s, %s",tmpname,sep.arg[2],sep.arg[1]);
|
||||
zoneserver_list.SOPZoneBootup(tmpname, atoi(sep.arg[1]), sep.arg[2], (bool) (strcasecmp(sep.arg[3], "static") == 0));
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "worldshutdown") == 0 && admin >= consoleWorldStatus) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ShutdownAll);
|
||||
zoneserver_list.SendPacket(pack);
|
||||
delete pack;
|
||||
SendMessage(1, "Sending shutdown packet... goodbye.");
|
||||
CatchSignal(0);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "lock") == 0 && admin >= consoleLockStatus) {
|
||||
WorldConfig::LockWorld();
|
||||
if (loginserverlist.Connected()) {
|
||||
loginserverlist.SendStatus();
|
||||
SendMessage(1, "World locked.");
|
||||
}
|
||||
else {
|
||||
SendMessage(1, "World locked, but login server not connected.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "unlock") == 0 && admin >= consoleLockStatus) {
|
||||
WorldConfig::UnlockWorld();
|
||||
if (loginserverlist.Connected()) {
|
||||
loginserverlist.SendStatus();
|
||||
SendMessage(1, "World unlocked.");
|
||||
}
|
||||
else {
|
||||
SendMessage(1, "World unlocked, but login server not connected.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "version") == 0 && admin >= consoleWorldStatus) {
|
||||
SendMessage(1, "Current version information.");
|
||||
SendMessage(1, " %s", CURRENT_WORLD_VERSION);
|
||||
SendMessage(1, " Compiled on: %s at %s", COMPILE_DATE, COMPILE_TIME);
|
||||
SendMessage(1, " Last modified on: %s", LAST_MODIFIED);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "serverinfo") == 0 && admin >= 200) {
|
||||
if (strcasecmp(sep.arg[1], "os") == 0) {
|
||||
#ifdef _WINDOWS
|
||||
GetOS();
|
||||
char intbuffer [sizeof(unsigned long)];
|
||||
SendMessage(1, "Operating system information.");
|
||||
SendMessage(1, " %s", Ver_name);
|
||||
SendMessage(1, " Build number: %s", ultoa(Ver_build, intbuffer, 10));
|
||||
SendMessage(1, " Minor version: %s", ultoa(Ver_min, intbuffer, 10));
|
||||
SendMessage(1, " Major version: %s", ultoa(Ver_maj, intbuffer, 10));
|
||||
SendMessage(1, " Platform Id: %s", ultoa(Ver_pid, intbuffer, 10));
|
||||
#else
|
||||
char os_string[100];
|
||||
SendMessage(1, "Operating system information.");
|
||||
SendMessage(1, " %s", GetOS(os_string));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
SendMessage(1, "Usage: Serverinfo [type]");
|
||||
SendMessage(1, " OS - Operating system version information.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "IPLookup") == 0 && admin >= 201) {
|
||||
client_list.SendCLEList(admin, 0, this, sep.argplus[1]);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "LSReconnect") == 0 && admin >= 100) {
|
||||
#ifdef _WINDOWS
|
||||
_beginthread(AutoInitLoginServer, 0, NULL);
|
||||
#else
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, &AutoInitLoginServer, NULL);
|
||||
#endif
|
||||
RunLoops = true;
|
||||
SendMessage(1, " Login Server Reconnect manually restarted by Console");
|
||||
_log(WORLD__CONSOLE,"Login Server Reconnect manually restarted by Console");
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "zonelock") == 0 && admin >= consoleZoneStatus) {
|
||||
if (strcasecmp(sep.arg[1], "list") == 0) {
|
||||
zoneserver_list.ListLockedZones(0, this);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[1], "lock") == 0 && admin >= 101) {
|
||||
uint16 tmp = database.GetZoneID(sep.arg[2]);
|
||||
if (tmp) {
|
||||
if (zoneserver_list.SetLockedZone(tmp, true))
|
||||
zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone locked: %s", database.GetZoneName(tmp));
|
||||
else
|
||||
SendMessage(1, "Failed to change lock");
|
||||
}
|
||||
else
|
||||
SendMessage(1, "Usage: #zonelock lock [zonename]");
|
||||
}
|
||||
else if (strcasecmp(sep.arg[1], "unlock") == 0 && admin >= 101) {
|
||||
uint16 tmp = database.GetZoneID(sep.arg[2]);
|
||||
if (tmp) {
|
||||
if (zoneserver_list.SetLockedZone(tmp, false))
|
||||
zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone unlocked: %s", database.GetZoneName(tmp));
|
||||
else
|
||||
SendMessage(1, "Failed to change lock");
|
||||
}
|
||||
else
|
||||
SendMessage(1, "Usage: #zonelock unlock [zonename]");
|
||||
}
|
||||
else {
|
||||
SendMessage(1, "#zonelock sub-commands");
|
||||
SendMessage(1, " list");
|
||||
if (admin >= 101) {
|
||||
SendMessage(1, " lock [zonename]");
|
||||
SendMessage(1, " unlock [zonename]");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
SendMessage(1, "Command unknown.");
|
||||
}
|
||||
if (state == CONSOLE_STATE_CONNECTED)
|
||||
SendPrompt();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Console::SendPrompt() {
|
||||
if (tcpc->GetEcho())
|
||||
SendMessage(0, "%s> ", paccountname);
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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
|
||||
*/
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
enum {
|
||||
consoleLoginStatus = 50, //ability to log in, basic commands.
|
||||
httpLoginStatus = 100, //can log into the HTTP interface
|
||||
consoleFlagStatus = 200, //flag
|
||||
consoleKickStatus = 150, //kick
|
||||
consoleLockStatus = 150, //world lock/unlock
|
||||
consoleZoneStatus = 150, //zone up/down/lock
|
||||
consolePassStatus = 200, //change password
|
||||
consoleWorldStatus = 200, //world shutdown
|
||||
consoleOpcodesStatus = 250
|
||||
};
|
||||
|
||||
#define CONSOLE_STATE_USERNAME 0
|
||||
#define CONSOLE_STATE_PASSWORD 1
|
||||
#define CONSOLE_STATE_CONNECTED 2
|
||||
#define CONSOLE_STATE_CLOSED 3
|
||||
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/queue.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "WorldTCPConnection.h"
|
||||
#include "../common/Mutex.h"
|
||||
|
||||
struct ServerChannelMessage_Struct;
|
||||
|
||||
class Console : public WorldTCPConnection {
|
||||
public:
|
||||
Console(EmuTCPConnection* itcpc);
|
||||
virtual ~Console();
|
||||
virtual inline bool IsConsole() { return true; }
|
||||
|
||||
bool Process();
|
||||
void Send(const char* message);
|
||||
int16 Admin() { return admin; }
|
||||
uint32 GetIP() { return tcpc->GetrIP(); }
|
||||
uint16 GetPort() { return tcpc->GetrPort(); }
|
||||
void ProcessCommand(const char* command);
|
||||
void Die();
|
||||
|
||||
bool SendChannelMessage(const ServerChannelMessage_Struct* scm);
|
||||
bool SendEmoteMessage(uint32 type, const char* message, ...);
|
||||
bool SendEmoteMessageRaw(uint32 type, const char* message);
|
||||
void SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...);
|
||||
void SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message);
|
||||
void SendMessage(uint8 newline, const char* message, ...);
|
||||
|
||||
const char* GetName() { return paccountname; }
|
||||
const char* AccountName() { return paccountname; }
|
||||
uint32 AccountID() { return paccountid; }
|
||||
private:
|
||||
EmuTCPConnection* tcpc;
|
||||
|
||||
Timer timeout_timer;
|
||||
Timer prompt_timer;
|
||||
|
||||
void SendPrompt();
|
||||
|
||||
uint32 paccountid;
|
||||
char paccountname[30];
|
||||
bool pAcceptMessages;
|
||||
|
||||
uint8 state;
|
||||
|
||||
int16 admin;
|
||||
uchar textbuf[1024];
|
||||
int bufindex;
|
||||
};
|
||||
|
||||
class ConsoleList
|
||||
{
|
||||
public:
|
||||
ConsoleList() {}
|
||||
~ConsoleList() {}
|
||||
|
||||
void Add(Console* con);
|
||||
void Process();
|
||||
void KillAll();
|
||||
|
||||
void SendChannelMessage(const ServerChannelMessage_Struct* scm);
|
||||
void SendConsoleWho(WorldTCPConnection* connection, const char* to, int16 admin, char** output, uint32* outsize, uint32* outlen);
|
||||
void SendEmoteMessage(uint32 type, const char* message, ...);
|
||||
void SendEmoteMessageRaw(uint32 type, const char* message);
|
||||
Console* FindByAccountName(const char* accname);
|
||||
private:
|
||||
LinkedList<Console*> list;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,279 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2008 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
|
||||
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 "lfplist.h"
|
||||
#include "cliententry.h"
|
||||
#include "clientlist.h"
|
||||
#include "zoneserver.h"
|
||||
#include "zonelist.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
|
||||
extern ClientList client_list;
|
||||
extern ZSList zoneserver_list;
|
||||
|
||||
GroupLFP::GroupLFP(uint32 inLeaderID) {
|
||||
|
||||
LeaderID = inLeaderID;
|
||||
for(unsigned int i=0; i<MAX_GROUP_MEMBERS; i++) {
|
||||
Members[i].Name[0] = '\0';
|
||||
Members[i].Class = 0;
|
||||
Members[i].Level = 0;
|
||||
Members[i].Zone = 0;
|
||||
}
|
||||
FromLevel = 1;
|
||||
ToLevel = 100;
|
||||
Classes = 0x01FFFE;
|
||||
Comments[0] = '\0';
|
||||
}
|
||||
|
||||
void GroupLFP::SetDetails(ServerLFPUpdate_Struct *Update) {
|
||||
|
||||
ClientListEntry *CLE;
|
||||
|
||||
// Update->Action can be 1 or 255.
|
||||
// If it is 255, we update the members only, not the level/class filters.
|
||||
//
|
||||
if(Update->Action != 255) {
|
||||
MatchFilter = Update->MatchFilter;
|
||||
FromLevel = Update->FromLevel;
|
||||
ToLevel = Update->ToLevel;
|
||||
Classes = Update->Classes;
|
||||
strcpy(Comments, Update->Comments);
|
||||
}
|
||||
|
||||
for(unsigned int i=0; i<MAX_GROUP_MEMBERS; i++) {
|
||||
strcpy(Members[i].Name,Update->Members[i].Name);
|
||||
// If we were passed the class/level and zone information, use that.
|
||||
if(Update->Members[i].Class && Update->Members[i].Level && Update->Members[i].Zone) {
|
||||
Members[i].Class = Update->Members[i].Class;
|
||||
Members[i].Level = Update->Members[i].Level;
|
||||
Members[i].Zone = Update->Members[i].Zone;
|
||||
Members[i].GuildID = Update->Members[i].GuildID;
|
||||
}
|
||||
// Otherwise try and find the information ourselves.
|
||||
else {
|
||||
CLE = client_list.FindCharacter(Members[i].Name);
|
||||
if(CLE) {
|
||||
Members[i].Class = CLE->class_();
|
||||
Members[i].Level = CLE->level();
|
||||
Members[i].Zone = CLE->zone();
|
||||
Members[i].GuildID = CLE->GuildID();
|
||||
}
|
||||
else {
|
||||
Members[i].Class = 0;
|
||||
Members[i].Level = 0;
|
||||
Members[i].Zone = 0;
|
||||
Members[i].GuildID = 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GroupLFP::RemoveMember(int Index) {
|
||||
|
||||
Members[Index].Name[0] = '\0';
|
||||
}
|
||||
|
||||
GroupLFPList::GroupLFPList() : LFPStaleTimer(60000) {
|
||||
|
||||
}
|
||||
|
||||
void GroupLFPList::Process() {
|
||||
|
||||
// Once a minute, check for clients in a LFP group who are no longer connected, and remove them.
|
||||
// If the client that posted the LFP group has gone, remove the entire LFP entry.
|
||||
//
|
||||
// We also update the level, class and zone for each member of the group. Their class will usually
|
||||
// never change, but if the LFP group is posted while a member is zoning, it will initially be
|
||||
// 'Unknown Class', so we will fill it in here.
|
||||
|
||||
if(!LFPStaleTimer.Check())
|
||||
return;
|
||||
|
||||
GroupLFP* Group;
|
||||
|
||||
LinkedListIterator<GroupLFP*> Iterator(LFPGroupList);
|
||||
Iterator.Reset();
|
||||
|
||||
while(Iterator.MoreElements()) {
|
||||
Group = Iterator.GetData();
|
||||
int MemberCount = 0;
|
||||
if(Group) {
|
||||
GroupLFPMemberEntry* GroupMembers = Group->Members;
|
||||
if(!GroupMembers) {
|
||||
Iterator.Advance();
|
||||
continue;
|
||||
}
|
||||
for(unsigned int i=0; i<MAX_GROUP_MEMBERS; i++) {
|
||||
if(GroupMembers[i].Name[0] == '\0')
|
||||
continue;
|
||||
|
||||
ClientListEntry *CLE = client_list.FindCharacter(GroupMembers[i].Name);
|
||||
if(!CLE) {
|
||||
// The first member entry is always the person who posted the LFP group, either
|
||||
// a single ungrouped player, or the leader of the group. If (s)he is gone, remove
|
||||
// the group from LFP.
|
||||
if(i==0) break;
|
||||
Group->RemoveMember(i);
|
||||
}
|
||||
else {
|
||||
// If the level/class/zone information we have is valid, update
|
||||
// the player's information.
|
||||
//
|
||||
if(CLE->level() > 0)
|
||||
GroupMembers[i].Level = CLE->level();
|
||||
|
||||
if(CLE->class_() > 0)
|
||||
GroupMembers[i].Class = CLE->class_();
|
||||
|
||||
if(CLE->zone() > 0)
|
||||
GroupMembers[i].Zone = CLE->zone();
|
||||
|
||||
MemberCount++;
|
||||
}
|
||||
}
|
||||
if(MemberCount == 0) {
|
||||
// If the leader or all the members are not online, remove the entry.
|
||||
Iterator.RemoveCurrent();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
void GroupLFPList::RemoveGroup(ServerLFPUpdate_Struct *Update) {
|
||||
|
||||
GroupLFP* Group;
|
||||
|
||||
LinkedListIterator<GroupLFP*> Iterator(LFPGroupList);
|
||||
Iterator.Reset();
|
||||
|
||||
while(Iterator.MoreElements()) {
|
||||
Group = Iterator.GetData();
|
||||
if(Group && (Group->GetID() == Update->LeaderID)) {
|
||||
Iterator.RemoveCurrent();
|
||||
return;
|
||||
}
|
||||
Iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
void GroupLFPList::UpdateGroup(ServerLFPUpdate_Struct *Update) {
|
||||
|
||||
GroupLFP* Group;
|
||||
|
||||
LinkedListIterator<GroupLFP*> Iterator(LFPGroupList);
|
||||
Iterator.Reset();
|
||||
|
||||
while(Iterator.MoreElements()) {
|
||||
Group = Iterator.GetData();
|
||||
if(Group && (Group->GetID() == Update->LeaderID)) {
|
||||
Group->SetDetails(Update);
|
||||
return;
|
||||
}
|
||||
Iterator.Advance();
|
||||
}
|
||||
|
||||
Group = new GroupLFP(Update->LeaderID);
|
||||
|
||||
if(Group) {
|
||||
Group->SetDetails(Update);
|
||||
LFPGroupList.Append(Group);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GroupLFPList::SendLFPMatches(ServerLFPMatchesRequest_Struct* smrs) {
|
||||
|
||||
int Matches = 0;
|
||||
GroupLFP* Group;
|
||||
|
||||
LinkedListIterator<GroupLFP*> Iterator(LFPGroupList);
|
||||
Iterator.Reset();
|
||||
|
||||
while(Iterator.MoreElements()) {
|
||||
Group = Iterator.GetData();
|
||||
Iterator.Advance();
|
||||
|
||||
if(Group) {
|
||||
// Just check if the leader is within the requested level range.
|
||||
if((Group->Members[0].Level < smrs->FromLevel) || (Group->Members[0].Level > smrs->ToLevel))
|
||||
continue;
|
||||
|
||||
// If the Player putting up the LFP request specified MatchFilter = true, then anyone
|
||||
// searching for groups LFP must meet the specified criteria to see this group.
|
||||
if(Group->MatchFilter) {
|
||||
unsigned int BitMask = 1 << smrs->QuerierClass;
|
||||
if(!(BitMask & Group->Classes)) continue;
|
||||
if(!((smrs->QuerierLevel >= Group->FromLevel) && (smrs->QuerierLevel <= Group->ToLevel))) continue;
|
||||
}
|
||||
Matches++;
|
||||
}
|
||||
}
|
||||
|
||||
ServerPacket* Pack = new ServerPacket(ServerOP_LFPMatches, (sizeof(ServerLFPMatchesResponse_Struct) * Matches) + 4);
|
||||
|
||||
char *Buf = (char *)Pack->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, smrs->FromID);
|
||||
|
||||
ServerLFPMatchesResponse_Struct* Buffer = (ServerLFPMatchesResponse_Struct*)Buf;
|
||||
|
||||
Iterator.Reset();
|
||||
|
||||
if(Matches) {
|
||||
while(Iterator.MoreElements() && (Matches > 0)) {
|
||||
Group = Iterator.GetData();
|
||||
Iterator.Advance();
|
||||
|
||||
if(Group) {
|
||||
if((Group->Members[0].Level < smrs->FromLevel) || (Group->Members[0].Level > smrs->ToLevel))
|
||||
continue;
|
||||
|
||||
if(Group->MatchFilter) {
|
||||
unsigned int BitMask = 1 << smrs->QuerierClass;
|
||||
if(!(BitMask & Group->Classes)) continue;
|
||||
if(!((smrs->QuerierLevel >= Group->FromLevel) && (smrs->QuerierLevel <= Group->ToLevel))) continue;
|
||||
}
|
||||
Buffer->FromLevel = Group->FromLevel;
|
||||
Buffer->ToLevel = Group->ToLevel;
|
||||
Buffer->Classes = Group->Classes;
|
||||
memcpy(Buffer->Members, Group->Members, 64 * MAX_GROUP_MEMBERS);
|
||||
strcpy(Buffer->Comments, Group->Comments);
|
||||
Matches--;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
Pack->Deflate();
|
||||
}
|
||||
|
||||
ClientListEntry* CLE = client_list.FindCharacter(smrs->FromName);
|
||||
if (CLE != NULL) {
|
||||
if (CLE->Server() != NULL)
|
||||
CLE->Server()->SendPacket(Pack);
|
||||
}
|
||||
else {
|
||||
ZoneServer* zs = zoneserver_list.FindByName(smrs->FromName);
|
||||
if (zs != NULL)
|
||||
zs->SendPacket(Pack);
|
||||
}
|
||||
safe_delete(Pack);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2008 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
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef LFPENTRY_H
|
||||
#define LFPENTRY_H
|
||||
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/timer.h"
|
||||
|
||||
class GroupLFP {
|
||||
|
||||
public:
|
||||
GroupLFP(uint32 LeaderID);
|
||||
|
||||
void SetDetails(ServerLFPUpdate_Struct *Update);
|
||||
inline GroupLFPMemberEntry* GetMembers() { return Members; }
|
||||
inline uint32 GetID() { return LeaderID; }
|
||||
void RemoveMember(int Index);
|
||||
|
||||
friend class GroupLFPList;
|
||||
|
||||
private:
|
||||
uint32 LeaderID;
|
||||
uint8 MatchFilter;
|
||||
uint32 FromLevel;
|
||||
uint32 ToLevel;
|
||||
uint32 Classes;
|
||||
char Comments[64];
|
||||
GroupLFPMemberEntry Members[MAX_GROUP_MEMBERS];
|
||||
|
||||
};
|
||||
|
||||
class GroupLFPList {
|
||||
|
||||
public:
|
||||
GroupLFPList();
|
||||
void UpdateGroup(ServerLFPUpdate_Struct *Update);
|
||||
void RemoveGroup(ServerLFPUpdate_Struct *Update);
|
||||
void SendLFPMatches(ServerLFPMatchesRequest_Struct* smrs);
|
||||
void Process();
|
||||
|
||||
private:
|
||||
LinkedList<GroupLFP*> LFPGroupList;
|
||||
Timer LFPStaleTimer;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
+568
@@ -0,0 +1,568 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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/debug.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/queue.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/EQStreamFactory.h"
|
||||
#include "../common/EQPacket.h"
|
||||
#include "client.h"
|
||||
#include "worlddb.h"
|
||||
#include "../common/seperator.h"
|
||||
#include "../common/version.h"
|
||||
#include "../common/eqtime.h"
|
||||
#include "../common/timeoutmgr.h"
|
||||
#include "../common/EQEMuError.h"
|
||||
#include "../common/opcodemgr.h"
|
||||
#include "../common/guilds.h"
|
||||
#include "../common/EQStreamIdent.h"
|
||||
//#include "../common/patches/Client62.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/platform.h"
|
||||
#include "../common/crash.h"
|
||||
#ifdef _WINDOWS
|
||||
#include <process.h>
|
||||
#define snprintf _snprintf
|
||||
#if (_MSC_VER < 1500)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#include <conio.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include "../common/unix.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/shm.h>
|
||||
#ifndef FREEBSD
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
ushort *array;
|
||||
struct seminfo *__buf;
|
||||
void *__pad;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "../common/EMuShareMem.h"
|
||||
extern LoadEMuShareMemDLL EMuShareMemDLL;
|
||||
|
||||
/*
|
||||
Zone only right now.
|
||||
#ifdef EQPROFILE
|
||||
#ifdef COMMON_PROFILE
|
||||
CommonProfiler _cp;
|
||||
#endif
|
||||
#endif*/
|
||||
|
||||
#include "zoneserver.h"
|
||||
#include "console.h"
|
||||
#include "LoginServer.h"
|
||||
#include "LoginServerList.h"
|
||||
#include "EQWHTTPHandler.h"
|
||||
#include "../common/dbasync.h"
|
||||
#include "../common/EmuTCPServer.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "../common/patches/patches.h"
|
||||
#include "zoneserver.h"
|
||||
#include "zonelist.h"
|
||||
#include "clientlist.h"
|
||||
#include "LauncherList.h"
|
||||
#include "wguild_mgr.h"
|
||||
#include "lfplist.h"
|
||||
#include "AdventureManager.h"
|
||||
#include "ucs.h"
|
||||
#include "queryserv.h"
|
||||
|
||||
TimeoutManager timeout_manager;
|
||||
EQStreamFactory eqsf(WorldStream,9000);
|
||||
EmuTCPServer tcps;
|
||||
ClientList client_list;
|
||||
GroupLFPList LFPGroupList;
|
||||
ZSList zoneserver_list;
|
||||
LoginServerList loginserverlist;
|
||||
EQWHTTPServer http_server;
|
||||
UCSConnection UCSLink;
|
||||
QueryServConnection QSLink;
|
||||
LauncherList launcher_list;
|
||||
AdventureManager adventure_manager;
|
||||
DBAsync *dbasync = NULL;
|
||||
RuleManager *rules = new RuleManager();
|
||||
volatile bool RunLoops = true;
|
||||
uint32 numclients = 0;
|
||||
uint32 numzones = 0;
|
||||
bool holdzones = false;
|
||||
|
||||
|
||||
extern ConsoleList console_list;
|
||||
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
RegisterExecutablePlatform(ExePlatformWorld);
|
||||
set_exception_handler();
|
||||
|
||||
// Load server configuration
|
||||
_log(WORLD__INIT, "Loading server configuration..");
|
||||
if (!WorldConfig::LoadConfig()) {
|
||||
_log(WORLD__INIT_ERR, "Loading server configuration failed.");
|
||||
return(1);
|
||||
}
|
||||
const WorldConfig *Config=WorldConfig::get();
|
||||
|
||||
if(!load_log_settings(Config->LogSettingsFile.c_str()))
|
||||
_log(WORLD__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
|
||||
else
|
||||
_log(WORLD__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
|
||||
|
||||
|
||||
_log(WORLD__INIT, "CURRENT_WORLD_VERSION:%s", CURRENT_WORLD_VERSION);
|
||||
|
||||
#ifdef _DEBUG
|
||||
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
#endif
|
||||
|
||||
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
|
||||
_log(WORLD__INIT_ERR, "Could not set signal handler");
|
||||
return 0;
|
||||
}
|
||||
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
|
||||
_log(WORLD__INIT_ERR, "Could not set signal handler");
|
||||
return 0;
|
||||
}
|
||||
#ifndef WIN32
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
||||
_log(WORLD__INIT_ERR, "Could not set signal handler");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// add login server config to list
|
||||
if (Config->LoginCount == 0) {
|
||||
if (Config->LoginHost.length()) {
|
||||
loginserverlist.Add(Config->LoginHost.c_str(), Config->LoginPort, Config->LoginAccount.c_str(), Config->LoginPassword.c_str());
|
||||
_log(WORLD__INIT, "Added loginserver %s:%i", Config->LoginHost.c_str(), Config->LoginPort);
|
||||
}
|
||||
} else {
|
||||
LinkedList<LoginConfig*> loginlist=Config->loginlist;
|
||||
LinkedListIterator<LoginConfig*> iterator(loginlist);
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
loginserverlist.Add(iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort, iterator.GetData()->LoginAccount.c_str(), iterator.GetData()->LoginPassword.c_str());
|
||||
_log(WORLD__INIT, "Added loginserver %s:%i", iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort);
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
_log(WORLD__INIT, "Connecting to MySQL...");
|
||||
if (!database.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(),
|
||||
Config->DatabaseDB.c_str(),
|
||||
Config->DatabasePort)) {
|
||||
_log(WORLD__INIT_ERR, "Cannot continue without a database connection.");
|
||||
return(1);
|
||||
}
|
||||
dbasync = new DBAsync(&database);
|
||||
guild_mgr.SetDatabase(&database);
|
||||
|
||||
if (argc >= 2) {
|
||||
char tmp[2];
|
||||
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) {
|
||||
cout << "Worldserver command line commands:" << endl;
|
||||
cout << "adduser username password flag - adds a user account" << endl;
|
||||
cout << "flag username flag - sets GM flag on the account" << endl;
|
||||
cout << "startzone zoneshortname - sets the starting zone" << endl;
|
||||
cout << "-holdzones - reboots lost zones" << endl;
|
||||
return 0;
|
||||
}
|
||||
else if (strcasecmp(argv[1], "-holdzones") == 0) {
|
||||
cout << "Reboot Zones mode ON" << endl;
|
||||
holdzones = true;
|
||||
}
|
||||
else if (database.GetVariable("disablecommandline", tmp, 2)) {
|
||||
if (strlen(tmp) == 1) {
|
||||
if (tmp[0] == '1') {
|
||||
cout << "Command line disabled in database... exiting" << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(argv[1], "adduser") == 0) {
|
||||
if (argc == 5) {
|
||||
if (Seperator::IsNumber(argv[4])) {
|
||||
if (atoi(argv[4]) >= 0 && atoi(argv[4]) <= 255) {
|
||||
if (database.CreateAccount(argv[2], argv[3], atoi(argv[4])) == 0)
|
||||
cout << "database.CreateAccount failed." << endl;
|
||||
else
|
||||
cout << "Account created: Username='" << argv[2] << "', Password='" << argv[3] << "', status=" << argv[4] << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
cout << "Usage: world adduser username password flag" << endl;
|
||||
cout << "flag = 0, 1 or 2" << endl;
|
||||
return 0;
|
||||
}
|
||||
else if (strcasecmp(argv[1], "flag") == 0) {
|
||||
if (argc == 4) {
|
||||
if (Seperator::IsNumber(argv[3])) {
|
||||
|
||||
if (atoi(argv[3]) >= 0 && atoi(argv[3]) <= 255) {
|
||||
if (database.SetAccountStatus(argv[2], atoi(argv[3])))
|
||||
cout << "Account flagged: Username='" << argv[2] << "', status=" << argv[3] << endl;
|
||||
else
|
||||
cout << "database.SetAccountStatus failed." << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
cout << "Usage: world flag username flag" << endl;
|
||||
cout << "flag = 0-200" << endl;
|
||||
return 0;
|
||||
}
|
||||
else if (strcasecmp(argv[1], "startzone") == 0) {
|
||||
if (argc == 3) {
|
||||
if (strlen(argv[2]) < 3) {
|
||||
cout << "Error: zone name too short" << endl;
|
||||
}
|
||||
else if (strlen(argv[2]) > 15) {
|
||||
cout << "Error: zone name too long" << endl;
|
||||
}
|
||||
else {
|
||||
if (database.SetVariable("startzone", argv[2]))
|
||||
cout << "Starting zone changed: '" << argv[2] << "'" << endl;
|
||||
else
|
||||
cout << "database.SetVariable failed." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
cout << "Usage: world startzone zoneshortname" << endl;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
cout << "Error, unknown command line option" << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(Config->WorldHTTPEnabled) {
|
||||
_log(WORLD__INIT, "Starting HTTP world service...");
|
||||
http_server.Start(Config->WorldHTTPPort, Config->WorldHTTPMimeFile.c_str());
|
||||
} else {
|
||||
_log(WORLD__INIT, "HTTP world service disabled.");
|
||||
}
|
||||
|
||||
_log(WORLD__INIT, "Loading variables..");
|
||||
database.LoadVariables();
|
||||
_log(WORLD__INIT, "Loading zones..");
|
||||
database.LoadZoneNames();
|
||||
_log(WORLD__INIT, "Clearing groups..");
|
||||
database.ClearGroup();
|
||||
_log(WORLD__INIT, "Clearing raids..");
|
||||
database.ClearRaid();
|
||||
database.ClearRaidDetails();
|
||||
_log(WORLD__INIT, "Loading items..");
|
||||
if (!database.LoadItems()) {
|
||||
_log(WORLD__INIT_ERR, "Error: Could not load item data. But ignoring");
|
||||
}
|
||||
_log(WORLD__INIT, "Loading guilds..");
|
||||
guild_mgr.LoadGuilds();
|
||||
//rules:
|
||||
{
|
||||
char tmp[64];
|
||||
if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
|
||||
_log(WORLD__INIT, "Loading rule set '%s'", tmp);
|
||||
if(!rules->LoadRules(&database, tmp)) {
|
||||
_log(WORLD__INIT_ERR, "Failed to load ruleset '%s', falling back to defaults.", tmp);
|
||||
}
|
||||
} else {
|
||||
if(!rules->LoadRules(&database, "default")) {
|
||||
_log(WORLD__INIT, "No rule set configured, using default rules");
|
||||
} else {
|
||||
_log(WORLD__INIT, "Loaded default rule set 'default'", tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(RuleB(World, ClearTempMerchantlist)){
|
||||
_log(WORLD__INIT, "Clearing temporary merchant lists..");
|
||||
database.ClearMerchantTemp();
|
||||
}
|
||||
_log(WORLD__INIT, "Loading EQ time of day..");
|
||||
if (!zoneserver_list.worldclock.loadFile(Config->EQTimeFile.c_str()))
|
||||
_log(WORLD__INIT_ERR, "Unable to load %s", Config->EQTimeFile.c_str());
|
||||
_log(WORLD__INIT, "Loading launcher list..");
|
||||
launcher_list.LoadList();
|
||||
|
||||
char tmp[20];
|
||||
tmp[0] = '\0';
|
||||
database.GetVariable("holdzones",tmp, 20);
|
||||
if ((strcasecmp(tmp, "1") == 0)) {
|
||||
holdzones = true;
|
||||
}
|
||||
_log(WORLD__INIT, "Reboot zone modes %s",holdzones ? "ON" : "OFF");
|
||||
|
||||
_log(WORLD__INIT, "Deleted %i stale player corpses from database", database.DeleteStalePlayerCorpses());
|
||||
if (RuleB(World, DeleteStaleCorpeBackups) == true) {
|
||||
_log(WORLD__INIT, "Deleted %i stale player backups from database", database.DeleteStalePlayerBackups());
|
||||
}
|
||||
|
||||
_log(WORLD__INIT, "Loading adventures...");
|
||||
if(!adventure_manager.LoadAdventureTemplates())
|
||||
{
|
||||
_log(WORLD__INIT_ERR, "Unable to load adventure templates.");
|
||||
}
|
||||
|
||||
if(!adventure_manager.LoadAdventureEntries())
|
||||
{
|
||||
_log(WORLD__INIT_ERR, "Unable to load adventure templates.");
|
||||
}
|
||||
|
||||
adventure_manager.Load();
|
||||
adventure_manager.LoadLeaderboardInfo();
|
||||
|
||||
_log(WORLD__INIT, "Purging expired instances");
|
||||
database.PurgeExpiredInstances();
|
||||
Timer PurgeInstanceTimer(450000);
|
||||
PurgeInstanceTimer.Start(450000);
|
||||
|
||||
_log(WORLD__INIT, "Loading char create info...");
|
||||
database.LoadCharacterCreateAllocations();
|
||||
database.LoadCharacterCreateCombos();
|
||||
|
||||
char errbuf[TCPConnection_ErrorBufferSize];
|
||||
if (tcps.Open(Config->WorldTCPPort, errbuf)) {
|
||||
_log(WORLD__INIT,"Zone (TCP) listener started.");
|
||||
} else {
|
||||
_log(WORLD__INIT_ERR,"Failed to start zone (TCP) listener on port %d:",Config->WorldTCPPort);
|
||||
_log(WORLD__INIT_ERR," %s",errbuf);
|
||||
return 1;
|
||||
}
|
||||
if (eqsf.Open()) {
|
||||
_log(WORLD__INIT,"Client (UDP) listener started.");
|
||||
} else {
|
||||
_log(WORLD__INIT_ERR,"Failed to start client (UDP) listener (port 9000)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//register all the patches we have avaliable with the stream identifier.
|
||||
EQStreamIdentifier stream_identifier;
|
||||
RegisterAllPatches(stream_identifier);
|
||||
zoneserver_list.shutdowntimer = new Timer(60000);
|
||||
zoneserver_list.shutdowntimer->Disable();
|
||||
zoneserver_list.reminder = new Timer(20000);
|
||||
zoneserver_list.reminder->Disable();
|
||||
Timer InterserverTimer(INTERSERVER_TIMER); // does MySQL pings and auto-reconnect
|
||||
InterserverTimer.Trigger();
|
||||
uint8 ReconnectCounter = 100;
|
||||
EQStream* eqs;
|
||||
EmuTCPConnection* tcpc;
|
||||
EQStreamInterface *eqsi;
|
||||
|
||||
while(RunLoops) {
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
//check the factory for any new incoming streams.
|
||||
while ((eqs = eqsf.Pop())) {
|
||||
//pull the stream out of the factory and give it to the stream identifier
|
||||
//which will figure out what patch they are running, and set up the dynamic
|
||||
//structures and opcodes for that patch.
|
||||
struct in_addr in;
|
||||
in.s_addr = eqs->GetRemoteIP();
|
||||
_log(WORLD__CLIENT, "New connection from %s:%d", inet_ntoa(in),ntohs(eqs->GetRemotePort()));
|
||||
stream_identifier.AddStream(eqs); //takes the stream
|
||||
}
|
||||
|
||||
//give the stream identifier a chance to do its work....
|
||||
stream_identifier.Process();
|
||||
|
||||
//check the stream identifier for any now-identified streams
|
||||
while((eqsi = stream_identifier.PopIdentified())) {
|
||||
//now that we know what patch they are running, start up their client object
|
||||
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(WORLD__CLIENT, "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(WORLD__CLIENT, "Connection %s PASSED banned IPs check. Processing connection.", inet_ntoa(in));
|
||||
Client* client = new Client(eqsi);
|
||||
// @merth: client->zoneattempt=0;
|
||||
client_list.Add(client);
|
||||
} else {
|
||||
_log(WORLD__CLIENT, "Connection from %s FAILED banned IPs check. Closing connection.", inet_ntoa(in));
|
||||
eqsi->Close(); //Lieka: If the inbound IP is on the banned table, close the EQStream.
|
||||
}
|
||||
}
|
||||
if (!RuleB(World, UseBannedIPsTable)){
|
||||
_log(WORLD__CLIENT, "New connection from %s:%d, processing connection", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
|
||||
Client* client = new Client(eqsi);
|
||||
// @merth: client->zoneattempt=0;
|
||||
client_list.Add(client);
|
||||
}
|
||||
}
|
||||
|
||||
client_list.Process();
|
||||
|
||||
while ((tcpc = tcps.NewQueuePop())) {
|
||||
struct in_addr in;
|
||||
in.s_addr = tcpc->GetrIP();
|
||||
_log(WORLD__ZONE, "New TCP connection from %s:%d", inet_ntoa(in),tcpc->GetrPort());
|
||||
console_list.Add(new Console(tcpc));
|
||||
}
|
||||
|
||||
if(PurgeInstanceTimer.Check())
|
||||
{
|
||||
database.PurgeExpiredInstances();
|
||||
}
|
||||
|
||||
//check for timeouts in other threads
|
||||
timeout_manager.CheckTimeouts();
|
||||
|
||||
loginserverlist.Process();
|
||||
|
||||
console_list.Process();
|
||||
|
||||
zoneserver_list.Process();
|
||||
|
||||
launcher_list.Process();
|
||||
|
||||
UCSLink.Process();
|
||||
|
||||
QSLink.Process();
|
||||
|
||||
LFPGroupList.Process();
|
||||
|
||||
adventure_manager.Process();
|
||||
|
||||
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) {
|
||||
#ifdef _WINDOWS
|
||||
_beginthread(AutoInitLoginServer, 0, NULL);
|
||||
#else
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, &AutoInitLoginServer, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numclients == 0) {
|
||||
Sleep(50);
|
||||
continue;
|
||||
}
|
||||
Sleep(20);
|
||||
}
|
||||
_log(WORLD__SHUTDOWN,"World main loop completed.");
|
||||
_log(WORLD__SHUTDOWN,"Shutting down console connections (if any).");
|
||||
console_list.KillAll();
|
||||
_log(WORLD__SHUTDOWN,"Shutting down zone connections (if any).");
|
||||
zoneserver_list.KillAll();
|
||||
_log(WORLD__SHUTDOWN,"Zone (TCP) listener stopped.");
|
||||
tcps.Close();
|
||||
_log(WORLD__SHUTDOWN,"Client (UDP) listener stopped.");
|
||||
eqsf.Close();
|
||||
_log(WORLD__SHUTDOWN,"Signaling HTTP service to stop...");
|
||||
http_server.Stop();
|
||||
#if 0
|
||||
#if defined(SHAREMEM) && !defined(WIN32)
|
||||
for (int ipc_files = 0; ipc_files <= 4; ipc_files++) {
|
||||
key_t share_key;
|
||||
switch (ipc_files) {
|
||||
// Item
|
||||
case 0: share_key = ftok(".", 'I'); break;
|
||||
// Npctype
|
||||
case 1: share_key = ftok(".", 'N'); break;
|
||||
// Door
|
||||
case 2: share_key = ftok(".", 'D'); break;
|
||||
// Spell
|
||||
case 3: share_key = ftok(".", 'S'); break;
|
||||
// Faction
|
||||
case 4: share_key = ftok(".", 'F'); break;
|
||||
// ERROR Fatal
|
||||
default: cerr<<"Opps!"<<endl; share_key = 0xFF; break;
|
||||
}
|
||||
|
||||
int share_id = shmget(share_key, 0, IPC_NOWAIT|0400);
|
||||
if (share_id <= 0) {
|
||||
cerr<<"exiting could not check user count on shared memory ipcs mem leak!!!!!!!! id="<<share_id<<" key:"<<share_key<<endl;
|
||||
exit(1);
|
||||
}
|
||||
struct shmid_ds mem_users;
|
||||
if ((shmctl(share_id, IPC_STAT, &mem_users)) != 0) {
|
||||
cerr<<"exiting error checking user count on shared memory, marking for deletion!!!!!id="<<share_id<<" key:"<<share_key<<endl;
|
||||
shmctl(share_id, IPC_RMID, 0);
|
||||
exit(1);
|
||||
}
|
||||
if (mem_users.shm_nattch == 0) {
|
||||
//cerr<<"exiting stale share marked for deletion!id="<<share_id<<" key:"<<share_key<<endl;
|
||||
shmctl(share_id, IPC_RMID, 0);
|
||||
}
|
||||
else if (mem_users.shm_nattch == 1) {
|
||||
//cerr<<"mem_users = 1"<<endl;
|
||||
// Detatch and delete shared mem here
|
||||
EMuShareMemDLL.Unload();
|
||||
shmctl(share_id, IPC_RMID, 0);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CheckEQEMuErrorAndPause();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CatchSignal(int sig_num) {
|
||||
_log(WORLD__SHUTDOWN,"Caught signal %d",sig_num);
|
||||
if(zoneserver_list.worldclock.saveFile(WorldConfig::get()->EQTimeFile.c_str())==false)
|
||||
_log(WORLD__SHUTDOWN,"Failed to save time file.");
|
||||
RunLoops = false;
|
||||
}
|
||||
|
||||
void UpdateWindowTitle(char* iNewTitle) {
|
||||
#ifdef _WINDOWS
|
||||
char tmp[500];
|
||||
if (iNewTitle) {
|
||||
snprintf(tmp, sizeof(tmp), "World: %s", iNewTitle);
|
||||
}
|
||||
else {
|
||||
snprintf(tmp, sizeof(tmp), "World");
|
||||
}
|
||||
SetConsoleTitle(tmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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
|
||||
*/
|
||||
#ifndef WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
void CatchSignal(int sig_num);
|
||||
void UpdateWindowTitle(char* iNewTitle);
|
||||
|
||||
#define EQ_WORLD_PORT 9000 //mandated by the client
|
||||
#define LOGIN_PORT 5997
|
||||
|
||||
class NetConnection
|
||||
{
|
||||
public:
|
||||
NetConnection() {
|
||||
world_locked = false;
|
||||
for (int i=0; i<5; i++) {
|
||||
memset(loginaddress[i], 0, sizeof(loginaddress[i]));
|
||||
loginport[i] = LOGIN_PORT;
|
||||
}
|
||||
memset(worldname, 0, sizeof(worldname));
|
||||
memset(worldshortname, 0, sizeof(worldshortname));
|
||||
memset(worldaccount, 0, sizeof(worldaccount));
|
||||
memset(worldpassword, 0, sizeof(worldpassword));
|
||||
memset(worldaddress, 0, sizeof(worldaddress));
|
||||
memset(chataddress, 0, sizeof(chataddress));
|
||||
DEFAULTSTATUS=0;
|
||||
LoginServerInfo = 0;//ReadLoginINI();
|
||||
UpdateStats = false;
|
||||
}
|
||||
~NetConnection() { }
|
||||
|
||||
bool ReadLoginINI();
|
||||
bool LoginServerInfo;
|
||||
bool UpdateStats;
|
||||
char* GetLoginInfo(uint16* oPort);
|
||||
inline char* GetLoginAddress(uint8 i) { return loginaddress[i]; }
|
||||
inline uint16 GetLoginPort(uint8 i) { return loginport[i]; }
|
||||
inline char* GetWorldName() { return worldname; }
|
||||
inline char* GetWorldShortName() { return worldshortname; }
|
||||
inline char* GetWorldAccount() { return worldaccount; }
|
||||
inline char* GetWorldPassword() { return worldpassword; }
|
||||
inline char* GetWorldAddress() { return worldaddress; }
|
||||
inline uint8 GetDefaultStatus() { return DEFAULTSTATUS; }
|
||||
inline char* GetChatAddress() { return chataddress; }
|
||||
uint16 GetChatPort() { return chatport; }
|
||||
bool world_locked;
|
||||
private:
|
||||
int listening_socket;
|
||||
char loginaddress[5][255];
|
||||
uint16 loginport[5];
|
||||
uint16 chatport;
|
||||
char worldname[201];
|
||||
char worldshortname[31];
|
||||
char worldaccount[31];
|
||||
char worldpassword[31];
|
||||
char worldaddress[255];
|
||||
char chataddress[255];
|
||||
uint8 DEFAULTSTATUS;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
* This file was generated automatically by xsubpp version 1.9508 from the
|
||||
* contents of tmp. Do not edit this file, edit tmp instead.
|
||||
*
|
||||
* ANY CHANGES MADE HERE WILL BE LOST!
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2004 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
|
||||
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
|
||||
*/
|
||||
|
||||
typedef const char Const_char;
|
||||
|
||||
#ifdef EMBPERL
|
||||
#include "../common/debug.h"
|
||||
#include "EQWParser.h"
|
||||
#include "EQLConfig.h"
|
||||
|
||||
#ifdef THIS /* this macro seems to leak out on some systems */
|
||||
#undef THIS
|
||||
#endif
|
||||
|
||||
|
||||
XS(XS_EQLConfig_GetName); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_GetName)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::GetName(THIS)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
Const_char * RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetName();
|
||||
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_GetStaticCount); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_GetStaticCount)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::GetStaticCount(THIS)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
int RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetStaticCount();
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_IsConnected); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_IsConnected)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::IsConnected(THIS)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
bool RETVAL;
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->IsConnected();
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_DeleteLauncher); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_DeleteLauncher)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::DeleteLauncher(THIS)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->DeleteLauncher();
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_RestartZone); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_RestartZone)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::RestartZone(THIS, zone_ref)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->RestartZone(zone_ref);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_StopZone); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_StopZone)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::StopZone(THIS, zone_ref)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->StopZone(zone_ref);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_StartZone); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_StartZone)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::StartZone(THIS, zone_ref)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->StartZone(zone_ref);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_BootStaticZone); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_BootStaticZone)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::BootStaticZone(THIS, short_name, port)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
bool RETVAL;
|
||||
Const_char * short_name = (Const_char *)SvPV_nolen(ST(1));
|
||||
uint16 port = (uint16)SvUV(ST(2));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->BootStaticZone(short_name, port);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_ChangeStaticZone); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_ChangeStaticZone)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::ChangeStaticZone(THIS, short_name, port)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
bool RETVAL;
|
||||
Const_char * short_name = (Const_char *)SvPV_nolen(ST(1));
|
||||
uint16 port = (uint16)SvUV(ST(2));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->ChangeStaticZone(short_name, port);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_DeleteStaticZone); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_DeleteStaticZone)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::DeleteStaticZone(THIS, short_name)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
bool RETVAL;
|
||||
Const_char * short_name = (Const_char *)SvPV_nolen(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->DeleteStaticZone(short_name);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_SetDynamicCount); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_SetDynamicCount)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::SetDynamicCount(THIS, count)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
bool RETVAL;
|
||||
int count = (int)SvIV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->SetDynamicCount(count);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_GetDynamicCount); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_GetDynamicCount)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::GetDynamicCount(THIS)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
int RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetDynamicCount();
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_ListZones); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_ListZones)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::ListZones(THIS)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
vector<string> RETVAL;
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->ListZones();
|
||||
ST(0) = sv_newmortal();
|
||||
{
|
||||
U32 ix_RETVAL;
|
||||
/* pop crap off the stack we dont really want */
|
||||
POPs;
|
||||
POPs;
|
||||
/* grow the stack to the number of elements being returned */
|
||||
EXTEND(SP, RETVAL.size());
|
||||
for (ix_RETVAL = 0; ix_RETVAL < RETVAL.size(); ix_RETVAL++) {
|
||||
const string &it = RETVAL[ix_RETVAL];
|
||||
ST(ix_RETVAL) = sv_newmortal();
|
||||
sv_setpvn(ST(ix_RETVAL), it.c_str(), it.length());
|
||||
}
|
||||
/* hackish, but im over it. The normal xsubpp return will be right below this */
|
||||
XSRETURN(RETVAL.size());
|
||||
}
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_EQLConfig_GetZoneDetails); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_EQLConfig_GetZoneDetails)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: EQLConfig::GetZoneDetails(THIS, zone_ref)");
|
||||
{
|
||||
EQLConfig * THIS;
|
||||
map<string,string> RETVAL;
|
||||
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "EQLConfig")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(EQLConfig *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetZoneDetails(zone_ref);
|
||||
ST(0) = sv_newmortal();
|
||||
if (RETVAL.begin()!=RETVAL.end())
|
||||
{
|
||||
//NOTE: we are leaking the original ST(0) right now
|
||||
HV *hv = newHV();
|
||||
sv_2mortal((SV*)hv);
|
||||
ST(0) = newRV((SV*)hv);
|
||||
|
||||
map<string,string>::const_iterator cur, end;
|
||||
cur = RETVAL.begin();
|
||||
end = RETVAL.end();
|
||||
for(; cur != end; cur++) {
|
||||
/* get the element from the hash, creating if needed (will be needed) */
|
||||
SV**ele = hv_fetch(hv, cur->first.c_str(), cur->first.length(), TRUE);
|
||||
if(ele == NULL) {
|
||||
Perl_croak(aTHX_ "Unable to create a hash element for RETVAL");
|
||||
break;
|
||||
}
|
||||
/* put our string in the SV associated with this element in the hash */
|
||||
sv_setpvn(*ele, cur->second.c_str(), cur->second.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
XS(boot_EQLConfig); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(boot_EQLConfig)
|
||||
{
|
||||
dXSARGS;
|
||||
char file[256];
|
||||
strncpy(file, __FILE__, 256);
|
||||
file[255] = 0;
|
||||
|
||||
if(items != 1)
|
||||
fprintf(stderr, "boot_quest does not take any arguments.");
|
||||
char buf[128];
|
||||
|
||||
//add the strcpy stuff to get rid of const warnings....
|
||||
|
||||
|
||||
|
||||
XS_VERSION_BOOTCHECK ;
|
||||
|
||||
newXSproto(strcpy(buf, "GetName"), XS_EQLConfig_GetName, file, "$");
|
||||
newXSproto(strcpy(buf, "GetStaticCount"), XS_EQLConfig_GetStaticCount, file, "$");
|
||||
newXSproto(strcpy(buf, "IsConnected"), XS_EQLConfig_IsConnected, file, "$");
|
||||
newXSproto(strcpy(buf, "DeleteLauncher"), XS_EQLConfig_DeleteLauncher, file, "$");
|
||||
newXSproto(strcpy(buf, "RestartZone"), XS_EQLConfig_RestartZone, file, "$$");
|
||||
newXSproto(strcpy(buf, "StopZone"), XS_EQLConfig_StopZone, file, "$$");
|
||||
newXSproto(strcpy(buf, "StartZone"), XS_EQLConfig_StartZone, file, "$$");
|
||||
newXSproto(strcpy(buf, "BootStaticZone"), XS_EQLConfig_BootStaticZone, file, "$$$");
|
||||
newXSproto(strcpy(buf, "ChangeStaticZone"), XS_EQLConfig_ChangeStaticZone, file, "$$$");
|
||||
newXSproto(strcpy(buf, "DeleteStaticZone"), XS_EQLConfig_DeleteStaticZone, file, "$$");
|
||||
newXSproto(strcpy(buf, "SetDynamicCount"), XS_EQLConfig_SetDynamicCount, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetDynamicCount"), XS_EQLConfig_GetDynamicCount, file, "$");
|
||||
newXSproto(strcpy(buf, "ListZones"), XS_EQLConfig_ListZones, file, "$");
|
||||
newXSproto(strcpy(buf, "GetZoneDetails"), XS_EQLConfig_GetZoneDetails, file, "$$");
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
#endif //EMBPERL_XS_CLASSES
|
||||
|
||||
+1023
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* This file was generated automatically by xsubpp version 1.9508 from the
|
||||
* contents of tmp. Do not edit this file, edit tmp instead.
|
||||
*
|
||||
* ANY CHANGES MADE HERE WILL BE LOST!
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2004 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
|
||||
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
|
||||
*/
|
||||
|
||||
typedef const char Const_char;
|
||||
|
||||
#ifdef EMBPERL
|
||||
#include "../common/debug.h"
|
||||
#include "EQWParser.h"
|
||||
#include "HTTPRequest.h"
|
||||
|
||||
#ifdef THIS /* this macro seems to leak out on some systems */
|
||||
#undef THIS
|
||||
#endif
|
||||
|
||||
|
||||
XS(XS_HTTPRequest_get); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_get)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 3)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::get(THIS, name, default_value= \"\")");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
Const_char * RETVAL;
|
||||
dXSTARG;
|
||||
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
|
||||
Const_char * default_value;
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
if (items < 3)
|
||||
default_value = "";
|
||||
else {
|
||||
default_value = (Const_char *)SvPV_nolen(ST(2));
|
||||
}
|
||||
|
||||
RETVAL = THIS->get(name, default_value);
|
||||
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_HTTPRequest_getInt); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_getInt)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 3)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::getInt(THIS, name, default_value= 0)");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
int RETVAL;
|
||||
dXSTARG;
|
||||
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
|
||||
int default_value;
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
if (items < 3)
|
||||
default_value = 0;
|
||||
else {
|
||||
default_value = (int)SvIV(ST(2));
|
||||
}
|
||||
|
||||
RETVAL = THIS->getInt(name, default_value);
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_HTTPRequest_getFloat); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_getFloat)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 3)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::getFloat(THIS, name, default_value= 0.0)");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
float RETVAL;
|
||||
dXSTARG;
|
||||
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
|
||||
float default_value;
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
if (items < 3)
|
||||
default_value = 0.0;
|
||||
else {
|
||||
default_value = (float)SvNV(ST(2));
|
||||
}
|
||||
|
||||
RETVAL = THIS->getFloat(name, default_value);
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_HTTPRequest_getEscaped); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_getEscaped)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 3)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::getEscaped(THIS, name, default_value= \"\")");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
Const_char * RETVAL;
|
||||
dXSTARG;
|
||||
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
|
||||
Const_char * default_value;
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
if (items < 3)
|
||||
default_value = "";
|
||||
else {
|
||||
default_value = (Const_char *)SvPV_nolen(ST(2));
|
||||
}
|
||||
|
||||
RETVAL = THIS->getEscaped(name, default_value);
|
||||
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_HTTPRequest_get_all); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_get_all)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::get_all(THIS)");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
map<string,string> RETVAL;
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->get_all();
|
||||
ST(0) = sv_newmortal();
|
||||
if (RETVAL.begin()!=RETVAL.end())
|
||||
{
|
||||
//NOTE: we are leaking the original ST(0) right now
|
||||
HV *hv = newHV();
|
||||
sv_2mortal((SV*)hv);
|
||||
ST(0) = newRV((SV*)hv);
|
||||
|
||||
map<string,string>::const_iterator cur, end;
|
||||
cur = RETVAL.begin();
|
||||
end = RETVAL.end();
|
||||
for(; cur != end; cur++) {
|
||||
/* get the element from the hash, creating if needed (will be needed) */
|
||||
SV**ele = hv_fetch(hv, cur->first.c_str(), cur->first.length(), TRUE);
|
||||
if(ele == NULL) {
|
||||
Perl_croak(aTHX_ "Unable to create a hash element for RETVAL");
|
||||
break;
|
||||
}
|
||||
/* put our string in the SV associated with this element in the hash */
|
||||
sv_setpvn(*ele, cur->second.c_str(), cur->second.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_HTTPRequest_redirect); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_redirect)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::redirect(THIS, URL)");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
Const_char * URL = (Const_char *)SvPV_nolen(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->redirect(URL);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_HTTPRequest_SetResponseCode); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_SetResponseCode)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::SetResponseCode(THIS, code)");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
Const_char * code = (Const_char *)SvPV_nolen(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->SetResponseCode(code);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_HTTPRequest_header); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_HTTPRequest_header)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: HTTPRequest::header(THIS, name, value)");
|
||||
{
|
||||
HTTPRequest * THIS;
|
||||
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
|
||||
Const_char * value = (Const_char *)SvPV_nolen(ST(2));
|
||||
|
||||
if (sv_derived_from(ST(0), "HTTPRequest")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(HTTPRequest *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->header(name, value);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
XS(boot_HTTPRequest); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(boot_HTTPRequest)
|
||||
{
|
||||
dXSARGS;
|
||||
char file[256];
|
||||
strncpy(file, __FILE__, 256);
|
||||
file[255] = 0;
|
||||
|
||||
if(items != 1)
|
||||
fprintf(stderr, "boot_quest does not take any arguments.");
|
||||
char buf[128];
|
||||
|
||||
//add the strcpy stuff to get rid of const warnings....
|
||||
|
||||
|
||||
|
||||
XS_VERSION_BOOTCHECK ;
|
||||
|
||||
newXSproto(strcpy(buf, "get"), XS_HTTPRequest_get, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "getInt"), XS_HTTPRequest_getInt, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "getFloat"), XS_HTTPRequest_getFloat, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "getEscaped"), XS_HTTPRequest_getEscaped, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "get_all"), XS_HTTPRequest_get_all, file, "$");
|
||||
newXSproto(strcpy(buf, "redirect"), XS_HTTPRequest_redirect, file, "$$");
|
||||
newXSproto(strcpy(buf, "SetResponseCode"), XS_HTTPRequest_SetResponseCode, file, "$$");
|
||||
newXSproto(strcpy(buf, "header"), XS_HTTPRequest_header, file, "$$$");
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
#endif //EMBPERL_XS_CLASSES
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "../common/debug.h"
|
||||
#include "queryserv.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "clientlist.h"
|
||||
#include "zonelist.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/logtypes.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/packet_dump.h"
|
||||
|
||||
extern ClientList client_list;
|
||||
extern ZSList zoneserver_list;
|
||||
|
||||
QueryServConnection::QueryServConnection()
|
||||
{
|
||||
Stream = 0;
|
||||
authenticated = false;
|
||||
}
|
||||
|
||||
void QueryServConnection::SetConnection(EmuTCPConnection *inStream)
|
||||
{
|
||||
if(Stream)
|
||||
{
|
||||
_log(QUERYSERV__ERROR, "Incoming QueryServ Connection while we were already connected to a QueryServ.");
|
||||
Stream->Disconnect();
|
||||
}
|
||||
|
||||
Stream = inStream;
|
||||
|
||||
authenticated = false;
|
||||
}
|
||||
|
||||
bool QueryServConnection::Process()
|
||||
{
|
||||
if (!Stream || !Stream->Connected())
|
||||
return false;
|
||||
|
||||
ServerPacket *pack = 0;
|
||||
|
||||
while((pack = Stream->PopPacket()))
|
||||
{
|
||||
if (!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;
|
||||
else
|
||||
{
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(QUERYSERV__ERROR, "QueryServ authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(QUERYSERV__ERROR, "QueryServ authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(QUERYSERV__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.");
|
||||
authenticated = true;
|
||||
}
|
||||
delete pack;
|
||||
continue;
|
||||
}
|
||||
switch(pack->opcode)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case ServerOP_KeepAlive:
|
||||
{
|
||||
// ignore this
|
||||
break;
|
||||
}
|
||||
case ServerOP_ZAAuth:
|
||||
{
|
||||
_log(QUERYSERV__ERROR, "Got authentication from QueryServ when they are already authenticated.");
|
||||
break;
|
||||
}
|
||||
case ServerOP_QueryServGeneric:
|
||||
{
|
||||
uint32 ZoneID = pack->ReadUInt32();
|
||||
uint16 InstanceID = pack->ReadUInt32();
|
||||
zoneserver_list.SendPacket(ZoneID, InstanceID, pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_LFGuildUpdate:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log(QUERYSERV__ERROR, "Unknown ServerOPcode from QueryServ 0x%04x, size %d", pack->opcode, pack->size);
|
||||
DumpPacket(pack->pBuffer, pack->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete pack;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool QueryServConnection::SendPacket(ServerPacket* pack)
|
||||
{
|
||||
if(!Stream)
|
||||
return false;
|
||||
|
||||
return Stream->SendPacket(pack);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef QueryServ_H
|
||||
#define QueryServ_H
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
class QueryServConnection
|
||||
{
|
||||
public:
|
||||
QueryServConnection();
|
||||
void SetConnection(EmuTCPConnection *inStream);
|
||||
bool Process();
|
||||
bool SendPacket(ServerPacket* pack);
|
||||
void Disconnect() { if(Stream) Stream->Disconnect(); }
|
||||
void SendMessage(const char *From, const char *Message);
|
||||
private:
|
||||
inline uint32 GetIP() const { return Stream ? Stream->GetrIP() : 0; }
|
||||
EmuTCPConnection *Stream;
|
||||
bool authenticated;
|
||||
};
|
||||
|
||||
#endif /*QueryServ_H_*/
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
#include "../common/debug.h"
|
||||
#include "ucs.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/logtypes.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/packet_dump.h"
|
||||
|
||||
UCSConnection::UCSConnection()
|
||||
{
|
||||
Stream = 0;
|
||||
authenticated = false;
|
||||
}
|
||||
|
||||
void UCSConnection::SetConnection(EmuTCPConnection *inStream)
|
||||
{
|
||||
if(Stream)
|
||||
{
|
||||
_log(UCS__ERROR, "Incoming UCS Connection while we were already connected to a UCS.");
|
||||
Stream->Disconnect();
|
||||
}
|
||||
|
||||
Stream = inStream;
|
||||
|
||||
authenticated = false;
|
||||
}
|
||||
|
||||
bool UCSConnection::Process()
|
||||
{
|
||||
if (!Stream || !Stream->Connected())
|
||||
return false;
|
||||
|
||||
ServerPacket *pack = 0;
|
||||
|
||||
while((pack = Stream->PopPacket()))
|
||||
{
|
||||
if (!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;
|
||||
else
|
||||
{
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(UCS__ERROR, "UCS authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(UCS__ERROR, "UCS authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(UCS__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.");
|
||||
authenticated = true;
|
||||
}
|
||||
delete pack;
|
||||
continue;
|
||||
}
|
||||
switch(pack->opcode)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case ServerOP_KeepAlive:
|
||||
{
|
||||
// ignore this
|
||||
break;
|
||||
}
|
||||
case ServerOP_ZAAuth:
|
||||
{
|
||||
_log(UCS__ERROR, "Got authentication from UCS when they are already authenticated.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log(UCS__ERROR, "Unknown ServerOPcode from UCS 0x%04x, size %d", pack->opcode, pack->size);
|
||||
DumpPacket(pack->pBuffer, pack->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete pack;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool UCSConnection::SendPacket(ServerPacket* pack)
|
||||
{
|
||||
if(!Stream)
|
||||
return false;
|
||||
|
||||
return Stream->SendPacket(pack);
|
||||
}
|
||||
|
||||
void UCSConnection::SendMessage(const char *From, const char *Message)
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_UCSMessage, strlen(From) + strlen(Message) + 2);
|
||||
|
||||
char *Buffer = (char *)pack->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, From);
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, Message);
|
||||
|
||||
SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
#ifndef UCS_H
|
||||
#define UCS_H
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
class UCSConnection
|
||||
{
|
||||
public:
|
||||
UCSConnection();
|
||||
void SetConnection(EmuTCPConnection *inStream);
|
||||
bool Process();
|
||||
bool SendPacket(ServerPacket* pack);
|
||||
void Disconnect() { if(Stream) Stream->Disconnect(); }
|
||||
void SendMessage(const char *From, const char *Message);
|
||||
private:
|
||||
inline uint32 GetIP() const { return Stream ? Stream->GetrIP() : 0; }
|
||||
EmuTCPConnection *Stream;
|
||||
bool authenticated;
|
||||
};
|
||||
|
||||
#endif /*UCS_H_*/
|
||||
@@ -0,0 +1,172 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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/debug.h"
|
||||
#include "wguild_mgr.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "clientlist.h"
|
||||
#include "zonelist.h"
|
||||
|
||||
|
||||
extern ClientList client_list;
|
||||
extern ZSList zoneserver_list;
|
||||
|
||||
|
||||
|
||||
WorldGuildManager guild_mgr;
|
||||
|
||||
|
||||
|
||||
void WorldGuildManager::SendGuildRefresh(uint32 guild_id, bool name, bool motd, bool rank, bool relation) {
|
||||
_log(GUILDS__REFRESH, "Broadcasting guild refresh for %d, changes: name=%d, motd=%d, rank=d, relation=%d", guild_id, name, motd, rank, relation);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_RefreshGuild, sizeof(ServerGuildRefresh_Struct));
|
||||
ServerGuildRefresh_Struct *s = (ServerGuildRefresh_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
s->name_change = name;
|
||||
s->motd_change = motd;
|
||||
s->rank_change = rank;
|
||||
s->relation_change = relation;
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void WorldGuildManager::SendCharRefresh(uint32 old_guild_id, uint32 guild_id, uint32 charid) {
|
||||
_log(GUILDS__REFRESH, "Broadcasting char refresh for %d from guild %d to world", charid, guild_id);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GuildCharRefresh, sizeof(ServerGuildCharRefresh_Struct));
|
||||
ServerGuildCharRefresh_Struct *s = (ServerGuildCharRefresh_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
s->old_guild_id = old_guild_id;
|
||||
s->char_id = charid;
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void WorldGuildManager::SendGuildDelete(uint32 guild_id) {
|
||||
_log(GUILDS__REFRESH, "Broadcasting guild delete for guild %d to world", guild_id);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_DeleteGuild, sizeof(ServerGuildID_Struct));
|
||||
ServerGuildID_Struct *s = (ServerGuildID_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void WorldGuildManager::ProcessZonePacket(ServerPacket *pack) {
|
||||
switch(pack->opcode) {
|
||||
|
||||
case ServerOP_RefreshGuild: {
|
||||
if(pack->size != sizeof(ServerGuildRefresh_Struct)) {
|
||||
_log(GUILDS__ERROR, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildRefresh_Struct));
|
||||
return;
|
||||
}
|
||||
ServerGuildRefresh_Struct *s = (ServerGuildRefresh_Struct *) pack->pBuffer;
|
||||
_log(GUILDS__REFRESH, "Received and broadcasting guild refresh for %d, changes: name=%d, motd=%d, rank=d, relation=%d", s->guild_id, s->name_change, s->motd_change, s->rank_change, s->relation_change);
|
||||
|
||||
//broadcast this packet to all zones.
|
||||
zoneserver_list.SendPacket(pack);
|
||||
|
||||
//preform a local refresh.
|
||||
if(!RefreshGuild(s->guild_id)) {
|
||||
_log(GUILDS__ERROR, "Unable to preform local refresh on guild %d", s->guild_id);
|
||||
//can we do anything?
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerOP_GuildCharRefresh: {
|
||||
if(pack->size != sizeof(ServerGuildCharRefresh_Struct)) {
|
||||
_log(GUILDS__ERROR, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildCharRefresh_Struct));
|
||||
return;
|
||||
}
|
||||
ServerGuildCharRefresh_Struct *s = (ServerGuildCharRefresh_Struct *) pack->pBuffer;
|
||||
_log(GUILDS__REFRESH, "Received and broadcasting guild member refresh for char %d to all zones with members of guild %d", s->char_id, s->guild_id);
|
||||
|
||||
//preform the local update
|
||||
client_list.UpdateClientGuild(s->char_id, s->guild_id);
|
||||
|
||||
//broadcast this update to any zone with a member in this guild.
|
||||
//client_list.SendGuildPacket(s->guild_id, pack);
|
||||
//because im sick of this not working, sending it to all zones, just spends a bit more bandwidth.
|
||||
zoneserver_list.SendPacket(pack);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerOP_DeleteGuild: {
|
||||
if(pack->size != sizeof(ServerGuildID_Struct)) {
|
||||
_log(GUILDS__ERROR, "Received ServerOP_DeleteGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildID_Struct));
|
||||
return;
|
||||
}
|
||||
ServerGuildID_Struct *s = (ServerGuildID_Struct *) pack->pBuffer;
|
||||
_log(GUILDS__REFRESH, "Received and broadcasting guild delete for guild %d", s->guild_id);
|
||||
|
||||
//broadcast this packet to all zones.
|
||||
zoneserver_list.SendPacket(pack);
|
||||
|
||||
//preform a local refresh.
|
||||
if(!LocalDeleteGuild(s->guild_id)) {
|
||||
_log(GUILDS__ERROR, "Unable to preform local delete on guild %d", s->guild_id);
|
||||
//can we do anything?
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerOP_GuildMemberUpdate: {
|
||||
if(pack->size != sizeof(ServerGuildMemberUpdate_Struct))
|
||||
{
|
||||
_log(GUILDS__ERROR, "Received ServerOP_GuildMemberUpdate of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildMemberUpdate_Struct));
|
||||
return;
|
||||
}
|
||||
|
||||
zoneserver_list.SendPacket(pack);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
_log(GUILDS__ERROR, "Unknown packet 0x%x received from zone??", pack->opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef GUILD_MGR_H_
|
||||
#define GUILD_MGR_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/guild_base.h"
|
||||
|
||||
class Client;
|
||||
class ServerPacket;
|
||||
|
||||
class WorldGuildManager : public BaseGuildManager {
|
||||
public:
|
||||
|
||||
//called by zoneserver when it receives a guild message from zone.
|
||||
void ProcessZonePacket(ServerPacket *pack);
|
||||
|
||||
uint8 *MakeGuildMembers(uint32 guild_id, const char *prefix_name, uint32 &length); //make a guild member list packet, returns ownership of the buffer.
|
||||
|
||||
protected:
|
||||
virtual void SendGuildRefresh(uint32 guild_id, bool name, bool motd, bool rank, bool relation);
|
||||
virtual void SendCharRefresh(uint32 old_guild_id, uint32 guild_id, uint32 charid);
|
||||
virtual void SendRankUpdate(uint32 CharID) { return; }
|
||||
virtual void SendGuildDelete(uint32 guild_id);
|
||||
|
||||
//map<uint32, uint32> m_tribute; //map from guild ID to current tribute ammount
|
||||
};
|
||||
|
||||
extern WorldGuildManager guild_mgr;
|
||||
|
||||
|
||||
#endif /*GUILD_MGR_H_*/
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "zoneserver.h"
|
||||
#include "client.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
void log_message_clientVA(LogType type, Client *who, const char *fmt, va_list args) {
|
||||
char prefix_buffer[256];
|
||||
snprintf(prefix_buffer, 255, "[%s] %s: ", log_type_info[type].name, who->GetAccountName());
|
||||
prefix_buffer[255] = '\0';
|
||||
|
||||
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer, fmt, args);
|
||||
}
|
||||
|
||||
void log_message_client(LogType type, Client *who, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
log_message_clientVA(type, who, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void log_message_zoneVA(LogType type, ZoneServer *who, const char *fmt, va_list args) {
|
||||
|
||||
char prefix_buffer[256];
|
||||
char zone_tag[65];
|
||||
const char *zone_name=who->GetZoneName();
|
||||
if (*zone_name==0)
|
||||
snprintf(zone_tag,64,"[%d]", who->GetID());
|
||||
else
|
||||
snprintf(zone_tag,64,"[%d] [%s]",who->GetID(),zone_name);
|
||||
|
||||
snprintf(prefix_buffer, 255, "[%s] %s ", log_type_info[type].name, zone_tag);
|
||||
prefix_buffer[255] = '\0';
|
||||
|
||||
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer, fmt, args);
|
||||
}
|
||||
|
||||
void log_message_zone(LogType type, ZoneServer *who, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
log_message_zoneVA(type, who, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,650 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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 "worlddb.h"
|
||||
//#include "../common/Item.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/Item.h"
|
||||
#include "../common/dbasync.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include "SoFCharCreateData.h"
|
||||
|
||||
using namespace std;
|
||||
WorldDatabase database;
|
||||
extern std::vector<RaceClassAllocation> character_create_allocations;
|
||||
extern std::vector<RaceClassCombos> character_create_race_class_combos;
|
||||
|
||||
|
||||
// solar: the current stuff is at the bottom of this function
|
||||
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
Inventory *inv;
|
||||
|
||||
for (int i=0; i<10; i++) {
|
||||
strcpy(cs->name[i], "<none>");
|
||||
cs->zone[i] = 0;
|
||||
cs->level[i] = 0;
|
||||
cs->tutorial[i] = 0;
|
||||
cs->gohome[i] = 0;
|
||||
}
|
||||
|
||||
int char_num = 0;
|
||||
unsigned long* lengths;
|
||||
|
||||
// Populate character info
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT name,profile,zonename,class,level FROM character_ WHERE account_id=%i order by name limit 10", account_id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while ((row = mysql_fetch_row(result))) {
|
||||
lengths = mysql_fetch_lengths(result);
|
||||
////////////
|
||||
//////////// This is the current one, the other are for converting
|
||||
////////////
|
||||
if ((lengths[1] == sizeof(PlayerProfile_Struct))) {
|
||||
strcpy(cs->name[char_num], row[0]);
|
||||
PlayerProfile_Struct* pp = (PlayerProfile_Struct*)row[1];
|
||||
uint8 clas = atoi(row[3]);
|
||||
uint8 lvl = atoi(row[4]);
|
||||
|
||||
// Character information
|
||||
if(lvl == 0)
|
||||
cs->level[char_num] = pp->level; //no level in DB, trust PP
|
||||
else
|
||||
cs->level[char_num] = lvl;
|
||||
if(clas == 0)
|
||||
cs->class_[char_num] = pp->class_; //no class in DB, trust PP
|
||||
else
|
||||
cs->class_[char_num] = clas;
|
||||
cs->race[char_num] = pp->race;
|
||||
cs->gender[char_num] = pp->gender;
|
||||
cs->deity[char_num] = pp->deity;
|
||||
cs->zone[char_num] = GetZoneID(row[2]);
|
||||
cs->face[char_num] = pp->face;
|
||||
cs->haircolor[char_num] = pp->haircolor;
|
||||
cs->beardcolor[char_num] = pp->beardcolor;
|
||||
cs->eyecolor2[char_num] = pp->eyecolor2;
|
||||
cs->eyecolor1[char_num] = pp->eyecolor1;
|
||||
cs->hairstyle[char_num] = pp->hairstyle;
|
||||
cs->beard[char_num] = pp->beard;
|
||||
cs->drakkin_heritage[char_num] = pp->drakkin_heritage;
|
||||
cs->drakkin_tattoo[char_num] = pp->drakkin_tattoo;
|
||||
cs->drakkin_details[char_num] = pp->drakkin_details;
|
||||
|
||||
if(RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
|
||||
cs->tutorial[char_num] = 1;
|
||||
|
||||
if(RuleB(World, EnableReturnHomeButton)) {
|
||||
int now = time(NULL);
|
||||
if((now - pp->lastlogin) >= RuleI(World, MinOfflineTimeToReturnHome))
|
||||
cs->gohome[char_num] = 1;
|
||||
}
|
||||
|
||||
|
||||
// This part creates home city entries for characters created before the home bind point was tracked.
|
||||
// Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should
|
||||
// probably be removed at some point, when most accounts are safely converted.
|
||||
if(pp->binds[4].zoneId == 0) {
|
||||
bool altered = false;
|
||||
MYSQL_RES *result2;
|
||||
MYSQL_ROW row2;
|
||||
char startzone[50] = {0};
|
||||
|
||||
// check for start zone variable (I didn't even know any variables were still being used...)
|
||||
if(database.GetVariable("startzone", startzone, 50)) {
|
||||
uint32 zoneid = database.GetZoneID(startzone);
|
||||
if(zoneid) {
|
||||
pp->binds[4].zoneId = zoneid;
|
||||
GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RunQuery(query,
|
||||
MakeAnyLenString(&query,
|
||||
"SELECT zone_id,bind_id,x,y,z FROM start_zones "
|
||||
"WHERE player_class=%i AND player_deity=%i AND player_race=%i",
|
||||
pp->class_,
|
||||
pp->deity,
|
||||
pp->race
|
||||
),
|
||||
errbuf,
|
||||
&result2
|
||||
);
|
||||
safe_delete_array(query);
|
||||
|
||||
// if there is only one possible start city, set it
|
||||
if(mysql_num_rows(result2) == 1) {
|
||||
row2 = mysql_fetch_row(result2);
|
||||
if(atoi(row2[1]) != 0) { // if a bind_id is specified, make them start there
|
||||
pp->binds[4].zoneId = (uint32)atoi(row2[1]);
|
||||
GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
}
|
||||
else { // otherwise, use the zone and coordinates given
|
||||
pp->binds[4].zoneId = (uint32)atoi(row2[0]);
|
||||
float x = atof(row2[2]);
|
||||
float y = atof(row2[3]);
|
||||
float z = atof(row2[4]);
|
||||
if(x == 0 && y == 0 && z == 0)
|
||||
GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z);
|
||||
|
||||
pp->binds[4].x = x;
|
||||
pp->binds[4].y = y;
|
||||
pp->binds[4].z = z;
|
||||
}
|
||||
altered = true;
|
||||
}
|
||||
|
||||
mysql_free_result(result2);
|
||||
}
|
||||
|
||||
// update the player profile
|
||||
if(altered) {
|
||||
uint32 char_id = GetCharacterID(cs->name[char_num]);
|
||||
RunQuery(query,MakeAnyLenString(&query,"SELECT extprofile FROM character_ WHERE id=%i",char_id), errbuf, &result2);
|
||||
safe_delete_array(query);
|
||||
if(result2) {
|
||||
row2 = mysql_fetch_row(result2);
|
||||
ExtendedProfile_Struct* ext = (ExtendedProfile_Struct*)row2[0];
|
||||
SetPlayerProfile(account_id,char_id,pp,inv,ext, 0, 0, 5);
|
||||
}
|
||||
mysql_free_result(result2);
|
||||
}
|
||||
} // end of "set start zone" block
|
||||
|
||||
|
||||
// Character's equipped items
|
||||
// @merth: Haven't done bracer01/bracer02 yet.
|
||||
// Also: this needs a second look after items are a little more solid
|
||||
// NOTE: items don't have a color, players MAY have a tint, if the
|
||||
// use_tint part is set. otherwise use the regular color
|
||||
inv = new Inventory;
|
||||
if(GetInventory(account_id, cs->name[char_num], inv))
|
||||
{
|
||||
for (uint8 material = 0; material <= 8; material++)
|
||||
{
|
||||
uint32 color;
|
||||
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
|
||||
if(item == 0)
|
||||
continue;
|
||||
|
||||
cs->equip[char_num][material] = item->GetItem()->Material;
|
||||
|
||||
if(pp->item_tint[material].rgb.use_tint) // they have a tint (LoY dye)
|
||||
color = pp->item_tint[material].color;
|
||||
else // no tint, use regular item color
|
||||
color = item->GetItem()->Color;
|
||||
|
||||
cs->cs_colors[char_num][material].color = color;
|
||||
|
||||
// the weapons are kept elsewhere
|
||||
if ((material==MATERIAL_PRIMARY) || (material==MATERIAL_SECONDARY))
|
||||
{
|
||||
if(strlen(item->GetItem()->IDFile) > 2) {
|
||||
uint32 idfile=atoi(&item->GetItem()->IDFile[2]);
|
||||
if (material==MATERIAL_PRIMARY)
|
||||
cs->primary[char_num]=idfile;
|
||||
else
|
||||
cs->secondary[char_num]=idfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error loading inventory for %s\n", cs->name[char_num]);
|
||||
}
|
||||
safe_delete(inv);
|
||||
if (++char_num > 10)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Got a bogus character (" << row[0] << ") Ignoring!!!" << endl;
|
||||
cout << "PP length ="<<lengths[1]<<" but PP should be "<<sizeof(PlayerProfile_Struct)<<endl;
|
||||
//DeleteCharacter(row[0]);
|
||||
}
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error in GetCharSelectInfo query '" << query << "' " << errbuf << endl;
|
||||
safe_delete_array(query);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) {
|
||||
// if an invalid bind point is specified, use the primary bind
|
||||
if (bindnum > 4)
|
||||
bindnum = 0;
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
uint32 affected_rows = 0;
|
||||
PlayerProfile_Struct pp;
|
||||
|
||||
bool PPValid = false;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT profile from character_ where id='%i'", CharID), errbuf, &result)) {
|
||||
row = mysql_fetch_row(result);
|
||||
unsigned long* lengths = mysql_fetch_lengths(result);
|
||||
if (lengths[0] == sizeof(PlayerProfile_Struct)) {
|
||||
memcpy(&pp, row[0], sizeof(PlayerProfile_Struct));
|
||||
PPValid = true;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
if(!PPValid) return 0;
|
||||
|
||||
const char *BindZoneName = StaticGetZoneName(pp.binds[bindnum].zoneId);
|
||||
|
||||
if(!strcmp(BindZoneName, "UNKNWN")) return pp.zone_id;
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET zonename = '%s',zoneid=%i,x=%f, y=%f, z=%f, instanceid=0 WHERE id='%i'",
|
||||
BindZoneName, pp.binds[bindnum].zoneId, pp.binds[bindnum].x, pp.binds[bindnum].y, pp.binds[bindnum].z,
|
||||
CharID), errbuf, 0,&affected_rows)) {
|
||||
|
||||
return pp.zone_id;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
return pp.binds[bindnum].zoneId;
|
||||
}
|
||||
|
||||
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row = 0;
|
||||
int rows;
|
||||
|
||||
if(!in_pp || !in_cc)
|
||||
return false;
|
||||
|
||||
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
|
||||
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;
|
||||
|
||||
RunQuery
|
||||
(
|
||||
query,
|
||||
MakeAnyLenString
|
||||
(
|
||||
&query,
|
||||
"SELECT x,y,z,heading,zone_id,bind_id FROM start_zones "
|
||||
"WHERE player_choice=%i AND player_class=%i "
|
||||
"AND player_deity=%i AND player_race=%i",
|
||||
in_cc->start_zone,
|
||||
in_cc->class_,
|
||||
in_cc->deity,
|
||||
in_cc->race
|
||||
),
|
||||
errbuf,
|
||||
&result
|
||||
);
|
||||
LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query);
|
||||
safe_delete_array(query);
|
||||
|
||||
if((rows = mysql_num_rows(result)) > 0)
|
||||
row = mysql_fetch_row(result);
|
||||
|
||||
if(row)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
in_pp->z = atof(row[2]);
|
||||
in_pp->heading = atof(row[3]);
|
||||
in_pp->zone_id = atoi(row[4]);
|
||||
in_pp->binds[0].zoneId = atoi(row[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
switch(in_cc->start_zone)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
in_pp->zone_id = 24; // erudnext
|
||||
in_pp->binds[0].zoneId = 38; // tox
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
in_pp->zone_id =2; // qeynos2
|
||||
in_pp->binds[0].zoneId = 2; // qeynos2
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
in_pp->zone_id =29; // halas
|
||||
in_pp->binds[0].zoneId = 30; // everfrost
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
in_pp->zone_id =19; // rivervale
|
||||
in_pp->binds[0].zoneId = 20; // kithicor
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
in_pp->zone_id =9; // freportw
|
||||
in_pp->binds[0].zoneId = 9; // freportw
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
in_pp->zone_id =40; // neriaka
|
||||
in_pp->binds[0].zoneId = 25; // nektulos
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
in_pp->zone_id =52; // gukta
|
||||
in_pp->binds[0].zoneId = 46; // innothule
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
in_pp->zone_id =49; // oggok
|
||||
in_pp->binds[0].zoneId = 47; // feerrott
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
in_pp->zone_id =60; // kaladima
|
||||
in_pp->binds[0].zoneId = 68; // butcher
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
in_pp->zone_id =54; // gfaydark
|
||||
in_pp->binds[0].zoneId = 54; // gfaydark
|
||||
break;
|
||||
}
|
||||
case 10:
|
||||
{
|
||||
in_pp->zone_id =61; // felwithea
|
||||
in_pp->binds[0].zoneId = 54; // gfaydark
|
||||
break;
|
||||
}
|
||||
case 11:
|
||||
{
|
||||
in_pp->zone_id =55; // akanon
|
||||
in_pp->binds[0].zoneId = 56; // steamfont
|
||||
break;
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
in_pp->zone_id =82; // cabwest
|
||||
in_pp->binds[0].zoneId = 78; // fieldofbone
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
in_pp->zone_id =155; // sharvahl
|
||||
in_pp->binds[0].zoneId = 155; // sharvahl
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
|
||||
database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z);
|
||||
|
||||
if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
|
||||
database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
|
||||
if(result)
|
||||
mysql_free_result(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
|
||||
{
|
||||
|
||||
// SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead.
|
||||
//
|
||||
// For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity.
|
||||
//
|
||||
// For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely
|
||||
// reason for no match being found.
|
||||
//
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row = 0;
|
||||
int rows;
|
||||
|
||||
if(!in_pp || !in_cc)
|
||||
return false;
|
||||
|
||||
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
|
||||
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;
|
||||
|
||||
RunQuery
|
||||
(
|
||||
query,
|
||||
MakeAnyLenString
|
||||
(
|
||||
&query,
|
||||
"SELECT x,y,z,heading,bind_id FROM start_zones "
|
||||
"WHERE zone_id=%i AND player_class=%i "
|
||||
"AND player_deity=%i AND player_race=%i",
|
||||
in_cc->start_zone,
|
||||
in_cc->class_,
|
||||
in_cc->deity,
|
||||
in_cc->race
|
||||
),
|
||||
errbuf,
|
||||
&result
|
||||
);
|
||||
LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query);
|
||||
_log(WORLD__CLIENT_TRACE, "SoF Start zone query: %s\n", query);
|
||||
safe_delete_array(query);
|
||||
|
||||
if((rows = mysql_num_rows(result)) > 0)
|
||||
row = mysql_fetch_row(result);
|
||||
|
||||
if(row)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
in_pp->z = atof(row[2]);
|
||||
in_pp->heading = atof(row[3]);
|
||||
in_pp->zone_id = in_cc->start_zone;
|
||||
in_pp->binds[0].zoneId = atoi(row[4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
|
||||
if(in_cc->start_zone == RuleI(World, TutorialZoneID))
|
||||
in_pp->zone_id = in_cc->start_zone;
|
||||
else {
|
||||
in_pp->x = in_pp->binds[0].x = -51;
|
||||
in_pp->y = in_pp->binds[0].y = -20;
|
||||
in_pp->z = in_pp->binds[0].z = 0.79;
|
||||
in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
|
||||
database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z);
|
||||
|
||||
if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
|
||||
database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
|
||||
if(result)
|
||||
mysql_free_result(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldDatabase::GetLauncherList(std::vector<std::string> &rl) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
rl.clear();
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query,
|
||||
"SELECT name FROM launcher" )
|
||||
, errbuf, &result))
|
||||
{
|
||||
while ((row = mysql_fetch_row(result))) {
|
||||
rl.push_back(row[0]);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetLauncherList: %s", errbuf);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
}
|
||||
|
||||
void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey) {
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char MailKeyString[17];
|
||||
|
||||
if(RuleB(Chat, EnableMailKeyIPVerification) == true)
|
||||
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
|
||||
else
|
||||
sprintf(MailKeyString, "%08X", MailKey);
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET mailkey = '%s' WHERE id='%i'",
|
||||
MailKeyString, CharID), errbuf))
|
||||
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
}
|
||||
|
||||
bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if(RunQuery(query, MakeAnyLenString(&query, "SELECT level FROM character_ WHERE name='%s'", name), errbuf, &result))
|
||||
{
|
||||
if(row = mysql_fetch_row(result))
|
||||
{
|
||||
level = atoi(row[0]);
|
||||
mysql_free_result(result);
|
||||
safe_delete_array(query);
|
||||
return true;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetCharacterLevel: %s", errbuf);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorldDatabase::LoadCharacterCreateAllocations() {
|
||||
character_create_allocations.clear();
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
if(RunQuery(query, MakeAnyLenString(&query, "SELECT * FROM char_create_point_allocations order by id"), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while(row = mysql_fetch_row(result)) {
|
||||
RaceClassAllocation allocate;
|
||||
int r = 0;
|
||||
allocate.Index = atoi(row[r++]);
|
||||
allocate.BaseStats[0] = atoi(row[r++]);
|
||||
allocate.BaseStats[3] = atoi(row[r++]);
|
||||
allocate.BaseStats[1] = atoi(row[r++]);
|
||||
allocate.BaseStats[2] = atoi(row[r++]);
|
||||
allocate.BaseStats[4] = atoi(row[r++]);
|
||||
allocate.BaseStats[5] = atoi(row[r++]);
|
||||
allocate.BaseStats[6] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[0] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[3] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[1] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[2] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[4] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[5] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[6] = atoi(row[r++]);
|
||||
character_create_allocations.push_back(allocate);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
} else {
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldDatabase::LoadCharacterCreateCombos() {
|
||||
character_create_race_class_combos.clear();
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
if(RunQuery(query, MakeAnyLenString(&query, "select * from char_create_combinations order by race, class, deity, start_zone"), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while(row = mysql_fetch_row(result)) {
|
||||
RaceClassCombos combo;
|
||||
int r = 0;
|
||||
combo.AllocationIndex = atoi(row[r++]);
|
||||
combo.Race = atoi(row[r++]);
|
||||
combo.Class = atoi(row[r++]);
|
||||
combo.Deity = atoi(row[r++]);
|
||||
combo.Zone = atoi(row[r++]);
|
||||
combo.ExpansionRequired = atoi(row[r++]);
|
||||
character_create_race_class_combos.push_back(combo);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
} else {
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
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
|
||||
*/
|
||||
#ifndef WORLDDB_H_
|
||||
#define WORLDDB_H_
|
||||
|
||||
#include "../common/shareddb.h"
|
||||
#include "../common/ZoneNumbers.h"
|
||||
|
||||
struct PlayerProfile_Struct;
|
||||
struct CharCreate_Struct;
|
||||
struct CharacterSelect_Struct;
|
||||
|
||||
|
||||
class WorldDatabase : public SharedDatabase {
|
||||
public:
|
||||
bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
|
||||
bool GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
|
||||
|
||||
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*);
|
||||
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
|
||||
|
||||
void GetLauncherList(std::vector<std::string> &result);
|
||||
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
||||
bool GetCharacterLevel(const char *name, int &level);
|
||||
|
||||
bool LoadCharacterCreateAllocations();
|
||||
bool LoadCharacterCreateCombos();
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
extern WorldDatabase database;
|
||||
|
||||
|
||||
#endif /*WORLDDB_H_*/
|
||||
@@ -0,0 +1,730 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2005 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
|
||||
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/debug.h"
|
||||
#include "zonelist.h"
|
||||
#include "zoneserver.h"
|
||||
#include "WorldTCPConnection.h"
|
||||
#include "worlddb.h"
|
||||
#include "console.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
|
||||
extern uint32 numzones;
|
||||
extern bool holdzones;
|
||||
extern ConsoleList console_list;
|
||||
|
||||
|
||||
|
||||
ZSList::ZSList()
|
||||
{
|
||||
NextID = 1;
|
||||
CurGroupID = 1;
|
||||
LastAllocatedPort=0;
|
||||
memset(pLockedZones, 0, sizeof(pLockedZones));
|
||||
}
|
||||
|
||||
ZSList::~ZSList() {
|
||||
}
|
||||
|
||||
void ZSList::ShowUpTime(WorldTCPConnection* con, const char* adminname) {
|
||||
uint32 ms = Timer::GetCurrentTime();
|
||||
uint32 d = ms / 86400000;
|
||||
ms -= d * 86400000;
|
||||
uint32 h = ms / 3600000;
|
||||
ms -= h * 3600000;
|
||||
uint32 m = ms / 60000;
|
||||
ms -= m * 60000;
|
||||
uint32 s = ms / 1000;
|
||||
if (d)
|
||||
con->SendEmoteMessage(adminname, 0, 0, 0, "Worldserver Uptime: %02id %02ih %02im %02is", d, h, m, s);
|
||||
else if (h)
|
||||
con->SendEmoteMessage(adminname, 0, 0, 0, "Worldserver Uptime: %02ih %02im %02is", h, m, s);
|
||||
else
|
||||
con->SendEmoteMessage(adminname, 0, 0, 0, "Worldserver Uptime: %02im %02is", m, s);
|
||||
}
|
||||
|
||||
void ZSList::Add(ZoneServer* zoneserver) {
|
||||
list.Insert(zoneserver);
|
||||
zoneserver->SendGroupIDs(); //send its initial set of group ids
|
||||
}
|
||||
|
||||
void ZSList::KillAll() {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
iterator.GetData()->Disconnect();
|
||||
iterator.RemoveCurrent();
|
||||
numzones--;
|
||||
}
|
||||
}
|
||||
|
||||
void ZSList::Process() {
|
||||
|
||||
if(shutdowntimer && shutdowntimer->Check()){
|
||||
_log(WORLD__ZONELIST, "Shutdown timer has expired. Telling all zones to shut down and exiting. (fake sigint)");
|
||||
ServerPacket* pack2 = new ServerPacket;
|
||||
pack2->opcode = ServerOP_ShutdownAll;
|
||||
pack2->size=0;
|
||||
SendPacket(pack2);
|
||||
safe_delete(pack2);
|
||||
Process();
|
||||
CatchSignal(2);
|
||||
}
|
||||
if(reminder && reminder->Check()){
|
||||
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i seconds...",shutdowntimer->GetRemainingTime()/1000);
|
||||
}
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if (!iterator.GetData()->Process()) {
|
||||
ZoneServer* zs = iterator.GetData();
|
||||
struct in_addr in;
|
||||
in.s_addr = zs->GetIP();
|
||||
_log(WORLD__ZONELIST,"Removing zoneserver #%d at %s:%d",zs->GetID(),zs->GetCAddress(),zs->GetCPort());
|
||||
zs->LSShutDownUpdate(zs->GetZoneID());
|
||||
if (holdzones){
|
||||
_log(WORLD__ZONELIST,"Hold Zones mode is ON - rebooting lost zone");
|
||||
if(!zs->IsStaticZone())
|
||||
RebootZone(inet_ntoa(in),zs->GetCPort(),zs->GetCAddress(),zs->GetID());
|
||||
else
|
||||
RebootZone(inet_ntoa(in),zs->GetCPort(),zs->GetCAddress(),zs->GetID(),database.GetZoneID(zs->GetZoneName()));
|
||||
}
|
||||
|
||||
iterator.RemoveCurrent();
|
||||
numzones--;
|
||||
}
|
||||
else {
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ZSList::SendPacket(ServerPacket* pack) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
iterator.GetData()->SendPacket(pack);
|
||||
iterator.Advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZSList::SendPacket(uint32 ZoneID, ServerPacket* pack) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetZoneID() == ZoneID) {
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
return(tmp->SendPacket(pack));
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool ZSList::SendPacket(uint32 ZoneID, uint16 instanceID, ServerPacket* pack) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
if(instanceID != 0)
|
||||
{
|
||||
while(iterator.MoreElements()) {
|
||||
if(iterator.GetData()->GetInstanceID() == instanceID) {
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
return(tmp->SendPacket(pack));
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetZoneID() == ZoneID
|
||||
&& iterator.GetData()->GetInstanceID() == 0) {
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
return(tmp->SendPacket(pack));
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
ZoneServer* ZSList::FindByName(const char* zonename) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements())
|
||||
{
|
||||
if (strcasecmp(iterator.GetData()->GetZoneName(), zonename) == 0) {
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
return tmp;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZoneServer* ZSList::FindByID(uint32 ZoneID) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetID() == ZoneID) {
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
return tmp;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZoneServer* ZSList::FindByZoneID(uint32 ZoneID) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements())
|
||||
{
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
if (tmp->GetZoneID() == ZoneID && tmp->GetInstanceID() == 0) {
|
||||
return tmp;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZoneServer* ZSList::FindByPort(uint16 port) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements())
|
||||
{
|
||||
if (iterator.GetData()->GetCPort() == port) {
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
return tmp;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZoneServer* ZSList::FindByInstanceID(uint32 InstanceID)
|
||||
{
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements())
|
||||
{
|
||||
if (iterator.GetData()->GetInstanceID() == InstanceID) {
|
||||
ZoneServer* tmp = iterator.GetData();
|
||||
return tmp;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ZSList::SetLockedZone(uint16 iZoneID, bool iLock) {
|
||||
for (int i=0; i<MaxLockedZones; i++) {
|
||||
if (iLock) {
|
||||
if (pLockedZones[i] == 0) {
|
||||
pLockedZones[i] = iZoneID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pLockedZones[i] == iZoneID) {
|
||||
pLockedZones[i] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZSList::IsZoneLocked(uint16 iZoneID) {
|
||||
for (int i=0; i<MaxLockedZones; i++) {
|
||||
if (pLockedZones[i] == iZoneID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ZSList::ListLockedZones(const char* to, WorldTCPConnection* connection) {
|
||||
int x = 0;
|
||||
for (int i=0; i<MaxLockedZones; i++) {
|
||||
if (pLockedZones[i]) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 0, database.GetZoneName(pLockedZones[i], true));
|
||||
x++;
|
||||
}
|
||||
}
|
||||
connection->SendEmoteMessage(to, 0, 0, 0, "%i zones locked.", x);
|
||||
}
|
||||
|
||||
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)
|
||||
strcpy(locked, "Yes");
|
||||
else
|
||||
strcpy(locked, "No");
|
||||
|
||||
char* output = 0;
|
||||
uint32 outsize = 0, outlen = 0;
|
||||
if (connection->IsConsole())
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s\r\n", locked);
|
||||
else
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s^", locked);
|
||||
if (connection->IsConsole())
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:\r\n");
|
||||
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())
|
||||
z++;
|
||||
else if (zs->GetZoneID() != 0)
|
||||
w++;
|
||||
else if(zs->GetZoneID() == 0 && !zs->IsBootingUp())
|
||||
v++;
|
||||
|
||||
if (zs->IsStaticZone())
|
||||
tmpStatic[0] = 'S';
|
||||
else
|
||||
tmpStatic[0] = ' ';
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
if (outlen >= 3584) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
safe_delete(output);
|
||||
outsize = 0;
|
||||
outlen = 0;
|
||||
}
|
||||
else {
|
||||
if (connection->IsConsole())
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "\r\n");
|
||||
else
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "^");
|
||||
}
|
||||
x++;
|
||||
}
|
||||
else if (zs->GetZoneID() != 0) {
|
||||
if (zs->GetZoneID())
|
||||
strcpy(tmpZone, zs->GetZoneName());
|
||||
else
|
||||
tmpZone[0] = 0;
|
||||
AppendAnyLenString(&output, &outsize, &outlen, " #%i %s %s", zs->GetID(), tmpStatic, tmpZone);
|
||||
if (outlen >= 3584) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
safe_delete(output);
|
||||
outsize = 0;
|
||||
outlen = 0;
|
||||
}
|
||||
else {
|
||||
if (connection->IsConsole())
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "\r\n");
|
||||
else
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "^");
|
||||
}
|
||||
x++;
|
||||
}
|
||||
y++;
|
||||
iterator.Advance();
|
||||
}
|
||||
if (connection->IsConsole())
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.\r\n", x, y);
|
||||
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)
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
safe_delete(output);
|
||||
}
|
||||
|
||||
void ZSList::SendChannelMessage(const char* from, const char* to, uint8 chan_num, uint8 language, const char* message, ...) {
|
||||
if (!message)
|
||||
return;
|
||||
va_list argptr;
|
||||
char buffer[1024];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, sizeof(buffer), message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SendChannelMessageRaw(from, to, chan_num, language, buffer);
|
||||
}
|
||||
|
||||
void ZSList::SendChannelMessageRaw(const char* from, const char* to, uint8 chan_num, uint8 language, const char* message) {
|
||||
if (!message)
|
||||
return;
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
|
||||
pack->opcode = ServerOP_ChannelMessage;
|
||||
pack->size = sizeof(ServerChannelMessage_Struct)+strlen(message)+1;
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
memset(pack->pBuffer, 0, pack->size);
|
||||
ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer;
|
||||
if (from == 0) {
|
||||
strcpy(scm->from, "WServer");
|
||||
scm->noreply = true;
|
||||
}
|
||||
else if (from[0] == 0) {
|
||||
strcpy(scm->from, "WServer");
|
||||
scm->noreply = true;
|
||||
}
|
||||
else
|
||||
strcpy(scm->from, from);
|
||||
if (to != 0) {
|
||||
strcpy((char *) scm->to, to);
|
||||
strcpy((char *) scm->deliverto, to);
|
||||
}
|
||||
else {
|
||||
scm->to[0] = 0;
|
||||
scm->deliverto[0] = 0;
|
||||
}
|
||||
|
||||
scm->language = language;
|
||||
scm->chan_num = chan_num;
|
||||
strcpy(&scm->message[0], message);
|
||||
if (scm->chan_num == 5 || scm->chan_num == 6 || scm->chan_num == 11) {
|
||||
console_list.SendChannelMessage(scm);
|
||||
}
|
||||
pack->Deflate();
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
|
||||
void ZSList::SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...) {
|
||||
if (!message)
|
||||
return;
|
||||
va_list argptr;
|
||||
char buffer[1024];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, sizeof(buffer), message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SendEmoteMessageRaw(to, to_guilddbid, to_minstatus, type, buffer);
|
||||
}
|
||||
|
||||
void ZSList::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message) {
|
||||
if (!message)
|
||||
return;
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
|
||||
pack->opcode = ServerOP_EmoteMessage;
|
||||
pack->size = sizeof(ServerEmoteMessage_Struct)+strlen(message)+1;
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
memset(pack->pBuffer, 0, pack->size);
|
||||
ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer;
|
||||
|
||||
if (to) {
|
||||
if (to[0] == '*') {
|
||||
Console* con = console_list.FindByAccountName(&to[1]);
|
||||
if (con)
|
||||
con->SendEmoteMessageRaw(to, to_guilddbid, to_minstatus, type, message);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
strcpy((char *) sem->to, to);
|
||||
}
|
||||
else {
|
||||
sem->to[0] = 0;
|
||||
}
|
||||
|
||||
sem->guilddbid = to_guilddbid;
|
||||
sem->minstatus = to_minstatus;
|
||||
sem->type = type;
|
||||
strcpy(&sem->message[0], message);
|
||||
char tempto[64]={0};
|
||||
if(to)
|
||||
strn0cpy(tempto,to,64);
|
||||
pack->Deflate();
|
||||
if (tempto[0] == 0) {
|
||||
SendPacket(pack);
|
||||
if (to_guilddbid == 0)
|
||||
console_list.SendEmoteMessageRaw(type, message);
|
||||
}
|
||||
else {
|
||||
ZoneServer* zs = FindByName(to);
|
||||
|
||||
if (zs != 0)
|
||||
zs->SendPacket(pack);
|
||||
else
|
||||
SendPacket(pack);
|
||||
}
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void ZSList::SendTimeSync() {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_SyncWorldTime, sizeof(eqTimeOfDay));
|
||||
eqTimeOfDay* tod = (eqTimeOfDay*) pack->pBuffer;
|
||||
tod->start_eqtime=worldclock.getStartEQTime();
|
||||
tod->start_realtime=worldclock.getStartRealTime();
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void ZSList::NextGroupIDs(uint32 &start, uint32 &end) {
|
||||
start = CurGroupID;
|
||||
CurGroupID += 1000; //hand them out 1000 at a time...
|
||||
if(CurGroupID < start) { //handle overflow
|
||||
start = 1;
|
||||
CurGroupID = 1001;
|
||||
}
|
||||
end = CurGroupID - 1;
|
||||
}
|
||||
|
||||
void ZSList::SOPZoneBootup(const char* adminname, uint32 ZoneServerID, const char* zonename, bool iMakeStatic) {
|
||||
ZoneServer* zs = 0;
|
||||
ZoneServer* zs2 = 0;
|
||||
uint32 zoneid;
|
||||
if (!(zoneid = database.GetZoneID(zonename)))
|
||||
SendEmoteMessage(adminname, 0, 0, 0, "Error: SOP_ZoneBootup: zone '%s' not found in 'zone' table. Typo protection=ON.", zonename);
|
||||
else {
|
||||
if (ZoneServerID != 0)
|
||||
zs = FindByID(ZoneServerID);
|
||||
else
|
||||
SendEmoteMessage(adminname, 0, 0, 0, "Error: SOP_ZoneBootup: ServerID must be specified");
|
||||
|
||||
if (zs == 0)
|
||||
SendEmoteMessage(adminname, 0, 0, 0, "Error: SOP_ZoneBootup: zoneserver not found");
|
||||
else {
|
||||
zs2 = FindByName(zonename);
|
||||
if (zs2 != 0)
|
||||
SendEmoteMessage(adminname, 0, 0, 0, "Error: SOP_ZoneBootup: zone '%s' already being hosted by ZoneServer #%i", zonename, zs2->GetID());
|
||||
else {
|
||||
zs->TriggerBootup(zoneid, 0, adminname, iMakeStatic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZSList::RebootZone(const char* ip1,uint16 port,const char* ip2, uint32 skipid, uint32 zoneid){
|
||||
// get random zone
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
uint32 x = 0;
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
x++;
|
||||
iterator.Advance();
|
||||
}
|
||||
if (x == 0)
|
||||
return;
|
||||
ZoneServer** tmp = new ZoneServer*[x];
|
||||
uint32 y = 0;
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if (!strcmp(iterator.GetData()->GetCAddress(),ip2) && !iterator.GetData()->IsBootingUp() && iterator.GetData()->GetID() != skipid) {
|
||||
tmp[y++] = iterator.GetData();
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
if (y == 0) {
|
||||
safe_delete(tmp);
|
||||
return;
|
||||
}
|
||||
uint32 z = MakeRandomInt(0, y-1);
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZoneReboot, sizeof(ServerZoneReboot_Struct));
|
||||
ServerZoneReboot_Struct* s = (ServerZoneReboot_Struct*) pack->pBuffer;
|
||||
// strcpy(s->ip1,ip1);
|
||||
strcpy(s->ip2,ip2);
|
||||
s->port = port;
|
||||
s->zoneid = zoneid;
|
||||
if(zoneid != 0)
|
||||
_log(WORLD__ZONELIST,"Rebooting static zone with the ID of: %i",zoneid);
|
||||
tmp[z]->SendPacket(pack);
|
||||
delete pack;
|
||||
safe_delete_array(tmp);
|
||||
}
|
||||
|
||||
uint16 ZSList::GetAvailableZonePort()
|
||||
{
|
||||
const WorldConfig *Config=WorldConfig::get();
|
||||
int i;
|
||||
uint16 port=0;
|
||||
|
||||
if (LastAllocatedPort==0)
|
||||
i=Config->ZonePortLow;
|
||||
else
|
||||
i=LastAllocatedPort+1;
|
||||
|
||||
while(i!=LastAllocatedPort && port==0) {
|
||||
if (i>Config->ZonePortHigh)
|
||||
i=Config->ZonePortLow;
|
||||
|
||||
if (!FindByPort(i)) {
|
||||
port=i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
LastAllocatedPort=port;
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
uint32 ZSList::TriggerBootup(uint32 iZoneID, uint32 iInstanceID) {
|
||||
if(iInstanceID > 0)
|
||||
{
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if(iterator.GetData()->GetInstanceID() == iInstanceID)
|
||||
{
|
||||
return iterator.GetData()->GetID();
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetZoneID() == 0 && !iterator.GetData()->IsBootingUp()) {
|
||||
ZoneServer* zone=iterator.GetData();
|
||||
zone->TriggerBootup(iZoneID, iInstanceID);
|
||||
return zone->GetID();
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if(iterator.GetData()->GetZoneID() == iZoneID && iterator.GetData()->GetInstanceID() == 0)
|
||||
{
|
||||
return iterator.GetData()->GetID();
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetZoneID() == 0 && !iterator.GetData()->IsBootingUp()) {
|
||||
ZoneServer* zone=iterator.GetData();
|
||||
zone->TriggerBootup(iZoneID);
|
||||
return zone->GetID();
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*Old Random boot zones use this if your server is distributed across computers.
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
|
||||
srand(time(NULL));
|
||||
uint32 x = 0;
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
x++;
|
||||
iterator.Advance();
|
||||
}
|
||||
if (x == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZoneServer** tmp = new ZoneServer*[x];
|
||||
uint32 y = 0;
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetZoneID() == 0 && !iterator.GetData()->IsBootingUp()) {
|
||||
tmp[y++] = iterator.GetData();
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
if (y == 0) {
|
||||
safe_delete(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 z = rand() % y;
|
||||
|
||||
tmp[z]->TriggerBootup(iZoneID);
|
||||
uint32 ret = tmp[z]->GetID();
|
||||
safe_delete(tmp);
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
void ZSList::SendLSZones(){
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
ZoneServer* zs = iterator.GetData();
|
||||
zs->LSBootUpdate(zs->GetZoneID(),true);
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
int ZSList::GetZoneCount() {
|
||||
return(numzones);
|
||||
}
|
||||
|
||||
void ZSList::GetZoneIDList(vector<uint32> &zones) {
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
ZoneServer* zs = iterator.GetData();
|
||||
zones.push_back(zs->GetID());
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#ifndef ZONELIST_H_
|
||||
#define ZONELIST_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/eqtime.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include <vector>
|
||||
|
||||
class WorldTCPConnection;
|
||||
class ServerPacket;
|
||||
class ZoneServer;
|
||||
|
||||
class ZSList
|
||||
{
|
||||
public:
|
||||
enum { MaxLockedZones = 10 };
|
||||
|
||||
static void ShowUpTime(WorldTCPConnection* con, const char* adminname = 0);
|
||||
|
||||
ZSList();
|
||||
~ZSList();
|
||||
ZoneServer* FindByName(const char* zonename);
|
||||
ZoneServer* FindByID(uint32 ZoneID);
|
||||
ZoneServer* FindByZoneID(uint32 ZoneID);
|
||||
ZoneServer* FindByPort(uint16 port);
|
||||
ZoneServer* FindByInstanceID(uint32 InstanceID);
|
||||
|
||||
void SendChannelMessage(const char* from, const char* to, uint8 chan_num, uint8 language, const char* message, ...);
|
||||
void SendChannelMessageRaw(const char* from, const char* to, uint8 chan_num, uint8 language, const char* message);
|
||||
void SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...);
|
||||
void SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message);
|
||||
|
||||
void SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* connection);
|
||||
|
||||
void SendTimeSync();
|
||||
void Add(ZoneServer* zoneserver);
|
||||
void Process();
|
||||
void KillAll();
|
||||
bool SendPacket(ServerPacket* pack);
|
||||
bool SendPacket(uint32 zoneid, ServerPacket* pack);
|
||||
bool SendPacket(uint32 zoneid, uint16 instanceid, ServerPacket* pack);
|
||||
inline uint32 GetNextID() { return NextID++; }
|
||||
void RebootZone(const char* ip1,uint16 port, const char* ip2, uint32 skipid, uint32 zoneid = 0);
|
||||
uint32 TriggerBootup(uint32 iZoneID, uint32 iInstanceID = 0);
|
||||
void SOPZoneBootup(const char* adminname, uint32 ZoneServerID, const char* zonename, bool iMakeStatic = false);
|
||||
EQTime worldclock;
|
||||
bool SetLockedZone(uint16 iZoneID, bool iLock);
|
||||
bool IsZoneLocked(uint16 iZoneID);
|
||||
void ListLockedZones(const char* to, WorldTCPConnection* connection);
|
||||
Timer* shutdowntimer;
|
||||
Timer* reminder;
|
||||
void NextGroupIDs(uint32 &start, uint32 &end);
|
||||
void SendLSZones();
|
||||
uint16 GetAvailableZonePort();
|
||||
|
||||
int GetZoneCount();
|
||||
void GetZoneIDList(std::vector<uint32> &zones);
|
||||
|
||||
protected:
|
||||
uint32 NextID;
|
||||
LinkedList<ZoneServer*> list;
|
||||
uint16 pLockedZones[MaxLockedZones];
|
||||
uint32 CurGroupID;
|
||||
uint16 LastAllocatedPort;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*ZONELIST_H_*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,93 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.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
|
||||
*/
|
||||
#ifndef ZONESERVER_H
|
||||
#define ZONESERVER_H
|
||||
|
||||
#include "WorldTCPConnection.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
class Client;
|
||||
class ServerPacket;
|
||||
|
||||
|
||||
class ZoneServer : public WorldTCPConnection {
|
||||
public:
|
||||
ZoneServer(EmuTCPConnection* itcpc);
|
||||
~ZoneServer();
|
||||
virtual inline bool IsZoneServer() { return true; }
|
||||
|
||||
bool Process();
|
||||
bool SendPacket(ServerPacket* pack) { return tcpc->SendPacket(pack); }
|
||||
void SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...);
|
||||
void SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message);
|
||||
bool SetZone(uint32 iZoneID, uint32 iInstanceID = 0, bool iStaticZone = false);
|
||||
void TriggerBootup(uint32 iZoneID = 0, uint32 iInstanceID = 0, const char* iAdminName = 0, bool iMakeStatic = false);
|
||||
void Disconnect() { tcpc->Disconnect(); }
|
||||
void IncommingClient(Client* client);
|
||||
void LSBootUpdate(uint32 zoneid, uint32 iInstanceID = 0, bool startup = false);
|
||||
void LSSleepUpdate(uint32 zoneid);
|
||||
void LSShutDownUpdate(uint32 zoneid);
|
||||
uint32 GetPrevZoneID() { return oldZoneID; }
|
||||
void ChangeWID(uint32 iCharID, uint32 iWID);
|
||||
void SendGroupIDs();
|
||||
|
||||
inline const char* GetZoneName() const { return zone_name; }
|
||||
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 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 * 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; }
|
||||
private:
|
||||
EmuTCPConnection* const tcpc;
|
||||
|
||||
uint32 ID;
|
||||
char clientaddress[250];
|
||||
uint16 clientport;
|
||||
bool BootingUp;
|
||||
bool staticzone;
|
||||
bool authenticated;
|
||||
uint32 pNumPlayers;
|
||||
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
|
||||
std::string launcher_name; //the launcher which started us
|
||||
std::string launched_name; //the name of the zone we launched.
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user