mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
svn -> git Migration
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(qserv_sources
|
||||
database.cpp
|
||||
lfguild.cpp
|
||||
queryserv.cpp
|
||||
queryservconfig.cpp
|
||||
worldserver.cpp
|
||||
)
|
||||
|
||||
SET(qserv_headers
|
||||
database.h
|
||||
lfguild.h
|
||||
queryservconfig.h
|
||||
worldserver.h
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(queryserv ${qserv_sources} ${qserv_headers})
|
||||
|
||||
ADD_DEFINITIONS(-DQSERV)
|
||||
|
||||
TARGET_LINK_LIBRARIES(queryserv Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE})
|
||||
|
||||
IF(MSVC)
|
||||
|
||||
SET_TARGET_PROPERTIES(queryserv PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
|
||||
TARGET_LINK_LIBRARIES(queryserv "Ws2_32.lib")
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF(MINGW)
|
||||
TARGET_LINK_LIBRARIES(queryserv "WS2_32")
|
||||
ENDIF(MINGW)
|
||||
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(queryserv "dl")
|
||||
TARGET_LINK_LIBRARIES(queryserv "z")
|
||||
TARGET_LINK_LIBRARIES(queryserv "m")
|
||||
TARGET_LINK_LIBRARIES(queryserv "rt")
|
||||
TARGET_LINK_LIBRARIES(queryserv "pthread")
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
ENDIF(UNIX)
|
||||
|
||||
SET(EXECUTABLE_OUTPUT_PATH ../Bin)
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
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 "../common/debug.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errmsg.h>
|
||||
#include <mysqld_error.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
|
||||
// Disgrace: for windows compile
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#include "../common/unix.h"
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "database.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
Database::Database ()
|
||||
{
|
||||
DBInitVars();
|
||||
}
|
||||
|
||||
/*
|
||||
Establish a connection to a mysql database with the supplied parameters
|
||||
*/
|
||||
|
||||
Database::Database(const char* host, const char* user, const char* passwd, const char* database, uint32 port)
|
||||
{
|
||||
DBInitVars();
|
||||
Connect(host, user, passwd, database, port);
|
||||
}
|
||||
|
||||
bool Database::Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port)
|
||||
{
|
||||
uint32 errnum= 0;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
if (!Open(host, user, passwd, database, port, &errnum, errbuf))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||
HandleMysqlError(errnum);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Using database '%s' at %s:%d",database,host,port);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Database::DBInitVars() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Database::HandleMysqlError(uint32 errnum) {
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Close the connection to the database
|
||||
*/
|
||||
Database::~Database()
|
||||
{
|
||||
}
|
||||
|
||||
bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) {
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `value` from `variables` where `varname`='%s'", varname), errbuf, &result)) {
|
||||
|
||||
_log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
if (mysql_num_rows(result) != 1) {
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
|
||||
snprintf(varvalue, varvalue_len, "%s", row[0]);
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Database::AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
|
||||
char *S1 = new char[strlen(from) * 2 + 1];
|
||||
char *S2 = new char[strlen(to) * 2 + 1];
|
||||
char *S3 = new char[strlen(message) * 2 + 1];
|
||||
DoEscapeString(S1, from, strlen(from));
|
||||
DoEscapeString(S2, to, strlen(to));
|
||||
DoEscapeString(S3, message, strlen(message));
|
||||
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_speech` SET `from`='%s', `to`='%s', `message`='%s', `minstatus`='%i', `guilddbid`='%i', `type`='%i'", S1, S2, S3, minstatus, guilddbid, type), errbuf, 0, 0)) {
|
||||
_log(NET__WORLD, "Failed Speech Entry Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
|
||||
safe_delete_array(query);
|
||||
safe_delete_array(S1);
|
||||
safe_delete_array(S2);
|
||||
safe_delete_array(S3);
|
||||
}
|
||||
|
||||
void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) {
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
uint32 lastid = 0;
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_trade_record` SET `time`=NOW(), "
|
||||
"`char1_id`='%i', `char1_pp`='%i', `char1_gp`='%i', `char1_sp`='%i', `char1_cp`='%i', `char1_items`='%i', "
|
||||
"`char2_id`='%i', `char2_pp`='%i', `char2_gp`='%i', `char2_sp`='%i', `char2_cp`='%i', `char2_items`='%i'",
|
||||
QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold, QS->char1_money.silver, QS->char1_money.copper, QS->char1_count,
|
||||
QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold, QS->char2_money.silver, QS->char2_money.copper, QS->char2_count),
|
||||
errbuf, 0, 0, &lastid)) {
|
||||
_log(NET__WORLD, "Failed Trade Log Record Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
|
||||
if(Items > 0) {
|
||||
for(int i = 0; i < Items; i++) {
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_trade_record_entries` SET `event_id`='%i', "
|
||||
"`from_id`='%i', `from_slot`='%i', `to_id`='%i', `to_slot`='%i', `item_id`='%i', "
|
||||
"`charges`='%i', `aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
||||
lastid, QS->items[i].from_id, QS->items[i].from_slot, QS->items[i].to_id, QS->items[i].to_slot, QS->items[i].item_id,
|
||||
QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||
errbuf, 0, 0))) {
|
||||
_log(NET__WORLD, "Failed Trade Log Record Entry Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) {
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
uint32 lastid = 0;
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_handin_record` SET `time`=NOW(), `quest_id`='%i', "
|
||||
"`char_id`='%i', `char_pp`='%i', `char_gp`='%i', `char_sp`='%i', `char_cp`='%i', `char_items`='%i', "
|
||||
"`npc_id`='%i', `npc_pp`='%i', `npc_gp`='%i', `npc_sp`='%i', `npc_cp`='%i', `npc_items`='%i'",
|
||||
QS->quest_id, QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count,
|
||||
QS->npc_id, QS->npc_money.platinum, QS->npc_money.gold, QS->npc_money.silver, QS->npc_money.copper, QS->npc_count),
|
||||
errbuf, 0, 0, &lastid)) {
|
||||
_log(NET__WORLD, "Failed Handin Log Record Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
|
||||
if(Items > 0) {
|
||||
for(int i = 0; i < Items; i++) {
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_handin_record_entries` SET `event_id`='%i', "
|
||||
"`action_type`='%s', `char_slot`='%i', `item_id`='%i', `charges`='%i', "
|
||||
"`aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
||||
lastid, QS->items[i].action_type, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges,
|
||||
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||
errbuf, 0, 0))) {
|
||||
_log(NET__WORLD, "Failed Handin Log Record Entry Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Database::LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members){
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
uint32 lastid = 0;
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record` SET `npc_id`='%i', `type`='%i', `zone_id`='%i', `time`=NOW()", QS->s1.NPCID, QS->s1.Type, QS->s1.ZoneID), errbuf, 0, 0, &lastid)) {
|
||||
_log(NET__WORLD, "Failed NPC Kill Log Record Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
|
||||
if(Members > 0){
|
||||
for (int i = 0; i < Members; i++) {
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record_entries` SET `event_id`='%i', `char_id`='%i'", lastid, QS->Chars[i].char_id, errbuf, 0, 0))) {
|
||||
_log(NET__WORLD, "Failed NPC Kill Log Entry Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Database::LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items) {
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
uint32 lastid = 0;
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_delete_record` SET `time`=NOW(), "
|
||||
"`char_id`='%i', `stack_size`='%i', `char_items`='%i'",
|
||||
QS->char_id, QS->stack_size, QS->char_count, QS->char_count),
|
||||
errbuf, 0, 0, &lastid)) {
|
||||
_log(NET__WORLD, "Failed Delete Log Record Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
|
||||
if(Items > 0) {
|
||||
for(int i = 0; i < Items; i++) {
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_delete_record_entries` SET `event_id`='%i', "
|
||||
"`char_slot`='%i', `item_id`='%i', `charges`='%i', `aug_1`='%i', "
|
||||
"`aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
||||
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
||||
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||
errbuf, 0, 0))) {
|
||||
_log(NET__WORLD, "Failed Delete Log Record Entry Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
uint32 lastid = 0;
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_move_record` SET `time`=NOW(), "
|
||||
"`char_id`='%i', `from_slot`='%i', `to_slot`='%i', `stack_size`='%i', `char_items`='%i', `postaction`='%i'",
|
||||
QS->char_id, QS->from_slot, QS->to_slot, QS->stack_size, QS->char_count, QS->postaction),
|
||||
errbuf, 0, 0, &lastid)) {
|
||||
_log(NET__WORLD, "Failed Move Log Record Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
|
||||
if(Items > 0) {
|
||||
for(int i = 0; i < Items; i++) {
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_move_record_entries` SET `event_id`='%i', "
|
||||
"`from_slot`='%i', `to_slot`='%i', `item_id`='%i', `charges`='%i', "
|
||||
"`aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'", lastid,
|
||||
QS->items[i].from_slot, QS->items[i].to_slot, QS->items[i].item_id, QS->items[i].charges,
|
||||
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||
errbuf, 0, 0))) {
|
||||
_log(NET__WORLD, "Failed Move Log Record Entry Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items) {
|
||||
// Merchant transactions are from the perspective of the merchant, not the player -U
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
uint32 lastid = 0;
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_merchant_transaction_record` SET `time`=NOW(), "
|
||||
"`zone_id`='%i', `merchant_id`='%i', `merchant_pp`='%i', `merchant_gp`='%i', `merchant_sp`='%i', `merchant_cp`='%i', `merchant_items`='%i', "
|
||||
"`char_id`='%i', `char_pp`='%i', `char_gp`='%i', `char_sp`='%i', `char_cp`='%i', `char_items`='%i'",
|
||||
QS->zone_id, QS->merchant_id, QS->merchant_money.platinum, QS->merchant_money.gold, QS->merchant_money.silver, QS->merchant_money.copper, QS->merchant_count,
|
||||
QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count),
|
||||
errbuf, 0, 0, &lastid)) {
|
||||
_log(NET__WORLD, "Failed Transaction Log Record Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
|
||||
if(Items > 0) {
|
||||
for(int i = 0; i < Items; i++) {
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_merchant_transaction_record_entries` SET `event_id`='%i', "
|
||||
"`char_slot`='%i', `item_id`='%i', `charges`='%i', `aug_1`='%i', "
|
||||
"`aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
||||
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
||||
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||
errbuf, 0, 0))) {
|
||||
_log(NET__WORLD, "Failed Transaction Log Record Entry Insert: %s", errbuf);
|
||||
_log(NET__WORLD, "%s", query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
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 CHATSERVER_DATABASE_H
|
||||
#define CHATSERVER_DATABASE_H
|
||||
|
||||
#define AUTHENTICATION_TIMEOUT 60
|
||||
#define INVALID_ID 0xFFFFFFFF
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/types.h"
|
||||
#include "../common/dbcore.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
//atoi is not uint32 or uint32 safe!!!!
|
||||
#define atoul(str) strtoul(str, NULL, 10)
|
||||
|
||||
class Database : public DBcore {
|
||||
public:
|
||||
Database();
|
||||
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
~Database();
|
||||
|
||||
bool GetVariable(const char* varname, char* varvalue, uint16 varvalue_len);
|
||||
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
||||
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items);
|
||||
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items);
|
||||
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
||||
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
||||
void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items);
|
||||
void LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items);
|
||||
protected:
|
||||
void HandleMysqlError(uint32 errnum);
|
||||
private:
|
||||
void DBInitVars();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,435 @@
|
||||
#include <stdlib.h>
|
||||
#include "lfguild.h"
|
||||
#include "database.h"
|
||||
#include "worldserver.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/rulesys.h"
|
||||
|
||||
extern WorldServer *worldserver;
|
||||
extern Database database;
|
||||
|
||||
PlayerLookingForGuild::PlayerLookingForGuild(char *Name, char *Comments, uint32 Level, uint32 Class, uint32 AACount, uint32 Timezone, uint32 TimePosted)
|
||||
{
|
||||
this->Name = Name;
|
||||
this->Comments = Comments;
|
||||
this->Level = Level;
|
||||
this->Class = Class;
|
||||
this->AACount = AACount;
|
||||
this->TimeZone = Timezone;
|
||||
this->TimePosted = TimePosted;
|
||||
}
|
||||
|
||||
GuildLookingForPlayers::GuildLookingForPlayers(char *Name, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Timezone, uint32 TimePosted)
|
||||
{
|
||||
this->Name = Name;
|
||||
this->Comments = Comments;
|
||||
this->FromLevel = FromLevel;
|
||||
this->ToLevel = ToLevel;
|
||||
this->Classes = Classes;
|
||||
this->AACount = AACount;
|
||||
this->TimeZone = Timezone;
|
||||
this->TimePosted = TimePosted;
|
||||
}
|
||||
|
||||
bool LFGuildManager::LoadDatabase()
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (!database.RunQuery(query,MakeAnyLenString(&query, "SELECT `type`,`name`,`comment`, `fromlevel`, `tolevel`, `classes`, `aacount`, `timezone`, `timeposted` FROM `lfguild`"),errbuf,&result)){
|
||||
|
||||
_log(QUERYSERV__ERROR, "Failed to load LFGuild info from database. %s %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
while((row = mysql_fetch_row(result))) {
|
||||
|
||||
uint32 type = atoul(row[0]);
|
||||
if(type == 0)
|
||||
{
|
||||
PlayerLookingForGuild p(row[1], row[2], atoul(row[3]), atoul(row[5]), atoul(row[6]), atoul(row[7]), atoul(row[8]));
|
||||
Players.push_back(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
GuildLookingForPlayers g(row[1], row[2], atoul(row[3]), atoul(row[4]), atoul(row[5]), atoul(row[6]), atoul(row[7]), atoul(row[8]));
|
||||
Guilds.push_back(g);
|
||||
}
|
||||
}
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LFGuildManager::HandlePacket(ServerPacket *pack)
|
||||
{
|
||||
char From[64];
|
||||
|
||||
pack->SetReadPosition(0);
|
||||
uint32 FromZoneID = pack->ReadUInt32();
|
||||
uint32 FromInstanceID = pack->ReadUInt32();
|
||||
pack->ReadString(From);
|
||||
pack->ReadSkipBytes(4);
|
||||
uint32 SubType = pack->ReadUInt32();
|
||||
|
||||
switch(SubType)
|
||||
{
|
||||
case QSG_LFGuild_PlayerMatches:
|
||||
{
|
||||
uint32 FromLevel = pack->ReadUInt32();
|
||||
uint32 ToLevel = pack->ReadUInt32();
|
||||
uint32 MinAA = pack->ReadUInt32();
|
||||
uint32 TimeZone = pack->ReadUInt32();
|
||||
uint32 Classes = pack->ReadUInt32();
|
||||
|
||||
SendPlayerMatches(FromZoneID, FromInstanceID, From, FromLevel, ToLevel, MinAA, TimeZone, Classes);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSG_LFGuild_UpdatePlayerInfo:
|
||||
{
|
||||
char Comments[257];
|
||||
uint32 Class = pack->ReadUInt32();
|
||||
uint32 Level = pack->ReadUInt32();
|
||||
uint32 AAPoints = pack->ReadUInt32();
|
||||
pack->ReadString(Comments);
|
||||
uint32 Toggle = pack->ReadUInt32();
|
||||
uint32 TimeZone = pack->ReadUInt32();
|
||||
|
||||
TogglePlayer(FromZoneID, FromInstanceID, From, Class, Level, AAPoints, Comments, Toggle, TimeZone);
|
||||
|
||||
break;
|
||||
}
|
||||
case QSG_LFGuild_RequestPlayerInfo:
|
||||
{
|
||||
SendPlayerStatus(FromZoneID, FromInstanceID, From);
|
||||
break;
|
||||
}
|
||||
case QSG_LFGuild_UpdateGuildInfo:
|
||||
{
|
||||
char GuildName[33], Comments[257];
|
||||
|
||||
pack->ReadString(GuildName);
|
||||
pack->ReadString(Comments);
|
||||
|
||||
uint32 FromLevel = pack->ReadUInt32();
|
||||
uint32 ToLevel = pack->ReadUInt32();
|
||||
uint32 Classes = pack->ReadUInt32();
|
||||
uint32 AACount = pack->ReadUInt32();
|
||||
uint32 Toggle = pack->ReadUInt32();
|
||||
uint32 TimeZone = pack->ReadUInt32();
|
||||
|
||||
ToggleGuild(FromZoneID, FromInstanceID, From, GuildName, Comments, FromLevel, ToLevel, Classes, AACount, Toggle, TimeZone);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case QSG_LFGuild_GuildMatches:
|
||||
{
|
||||
uint32 Level = pack->ReadUInt32();
|
||||
uint32 AAPoints = pack->ReadUInt32();
|
||||
uint32 TimeZone = pack->ReadUInt32();
|
||||
uint32 Class = pack->ReadUInt32();
|
||||
|
||||
SendGuildMatches(FromZoneID, FromInstanceID, From, Level, AAPoints, TimeZone, Class);
|
||||
break;
|
||||
}
|
||||
case QSG_LFGuild_RequestGuildInfo:
|
||||
{
|
||||
char GuildName[33];
|
||||
pack->ReadString(GuildName);
|
||||
|
||||
SendGuildStatus(FromZoneID, FromInstanceID, From, GuildName);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LFGuildManager::SendPlayerMatches(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 FromLevel, uint32 ToLevel, uint32 MinAA, uint32 TimeZone, uint32 Classes)
|
||||
{
|
||||
std::list<PlayerLookingForGuild>::iterator it;
|
||||
std::list<PlayerLookingForGuild> Matches;
|
||||
|
||||
uint32 PacketSize = strlen(From) + 21, NumberOfMatches = 0;
|
||||
|
||||
for(it = Players.begin(); it != Players.end(); ++it)
|
||||
{
|
||||
uint32 bitmask = 1 << (*it).Class ;
|
||||
|
||||
if(((*it).Level >= FromLevel) && ((*it).Level <= ToLevel) && ((*it).AACount >= MinAA) && (bitmask & Classes) && ((TimeZone == 0xFFFFFFFF) || (TimeZone == (*it).TimeZone)))
|
||||
{
|
||||
++NumberOfMatches;
|
||||
Matches.push_back(*it);
|
||||
PacketSize += (*it).Name.length() + (*it).Comments.length() + 18;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_QueryServGeneric, PacketSize);
|
||||
|
||||
pack->WriteUInt32(FromZoneID);
|
||||
pack->WriteUInt32(FromInstanceID);
|
||||
pack->WriteString(From);
|
||||
pack->WriteUInt32(QSG_LFGuild);
|
||||
pack->WriteUInt32(QSG_LFGuild_PlayerMatches);
|
||||
pack->WriteUInt32(NumberOfMatches);
|
||||
|
||||
for(it = Matches.begin(); it != Matches.end(); ++it)
|
||||
{
|
||||
pack->WriteString((*it).Name.c_str());
|
||||
pack->WriteString((*it).Comments.c_str());
|
||||
pack->WriteUInt32((*it).Level);
|
||||
pack->WriteUInt32((*it).Class);
|
||||
pack->WriteUInt32((*it).AACount);
|
||||
pack->WriteUInt32((*it).TimeZone);
|
||||
|
||||
}
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void LFGuildManager::SendGuildMatches(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 Level, uint32 AAPoints, uint32 TimeZone, uint32 Class)
|
||||
{
|
||||
std::list<GuildLookingForPlayers>::iterator it;
|
||||
std::list<GuildLookingForPlayers> Matches;
|
||||
|
||||
uint32 bitmask = 1 << Class ;
|
||||
|
||||
uint32 PacketSize = strlen(From) + 21, NumberOfMatches = 0;
|
||||
|
||||
for(it = Guilds.begin(); it != Guilds.end(); ++it)
|
||||
{
|
||||
if((Level >= (*it).FromLevel) && (Level <= (*it).ToLevel) && (AAPoints >= (*it).AACount) && (bitmask & (*it).Classes) && (((*it).TimeZone == 0xFFFFFFFF) || (TimeZone == 0xFFFFFFFF) || (TimeZone == (*it).TimeZone)))
|
||||
{
|
||||
++NumberOfMatches;
|
||||
Matches.push_back(*it);
|
||||
PacketSize += (*it).Name.length() + (*it).Comments.length() + 6;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_QueryServGeneric, PacketSize);
|
||||
|
||||
pack->WriteUInt32(FromZoneID);
|
||||
pack->WriteUInt32(FromInstanceID);
|
||||
pack->WriteString(From);
|
||||
pack->WriteUInt32(QSG_LFGuild);
|
||||
pack->WriteUInt32(QSG_LFGuild_GuildMatches);
|
||||
pack->WriteUInt32(NumberOfMatches);
|
||||
|
||||
for(it = Matches.begin(); it != Matches.end(); ++it)
|
||||
{
|
||||
pack->WriteString((*it).Name.c_str());
|
||||
pack->WriteUInt32((*it).TimeZone);
|
||||
pack->WriteString((*it).Comments.c_str());
|
||||
}
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void LFGuildManager::TogglePlayer(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 Class, uint32 Level, uint32 AAPoints, char *Comments, uint32 Toggle, uint32 TimeZone)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
|
||||
std::list<PlayerLookingForGuild>::iterator it;
|
||||
|
||||
for(it = Players.begin(); it != Players.end(); ++it)
|
||||
{
|
||||
if(!strcasecmp((*it).Name.c_str(), From))
|
||||
{
|
||||
Players.erase(it);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!database.RunQuery(query, MakeAnyLenString(&query, "DELETE FROM `lfguild` WHERE `type` = 0 AND `name` = '%s'", From), errbuf, 0, 0))
|
||||
_log(QUERYSERV__ERROR, "Error removing player from LFGuild table, query was %s, %s", query, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
uint32 Now = time(NULL);
|
||||
|
||||
if(Toggle == 1)
|
||||
{
|
||||
PlayerLookingForGuild p(From, Comments, Level, Class, AAPoints, TimeZone, Now);
|
||||
Players.push_back(p);
|
||||
if(!database.RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `lfguild` (`type`, `name`, `comment`, `fromlevel`, `tolevel`, `classes`, `aacount`, `timezone`, `timeposted`) VALUES(0, '%s', '%s', %u, 0, %u, %u, %u, %u)", From, Comments, Level, Class, AAPoints, TimeZone, Now), errbuf, 0, 0))
|
||||
_log(QUERYSERV__ERROR, "Error inserting player into LFGuild table, query was %s, %s", query, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(From) + strlen(Comments) + 30);
|
||||
|
||||
pack->WriteUInt32(FromZoneID);
|
||||
pack->WriteUInt32(FromInstanceID);
|
||||
pack->WriteString(From);
|
||||
pack->WriteUInt32(QSG_LFGuild);
|
||||
pack->WriteUInt32(QSG_LFGuild_RequestPlayerInfo);
|
||||
pack->WriteString(Comments);
|
||||
pack->WriteUInt32(TimeZone);
|
||||
pack->WriteUInt32(Now);
|
||||
pack->WriteUInt32(Toggle);
|
||||
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
}
|
||||
|
||||
void LFGuildManager::ToggleGuild(uint32 FromZoneID, uint32 FromInstanceID, char *From, char* GuildName, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Toggle, uint32 TimeZone)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
|
||||
std::list<GuildLookingForPlayers>::iterator it;
|
||||
|
||||
for(it = Guilds.begin(); it != Guilds.end(); ++it)
|
||||
{
|
||||
if(!strcasecmp((*it).Name.c_str(), GuildName))
|
||||
{
|
||||
Guilds.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!database.RunQuery(query, MakeAnyLenString(&query, "DELETE FROM `lfguild` WHERE `type` = 1 AND `name` = '%s'", GuildName), errbuf, 0, 0))
|
||||
_log(QUERYSERV__ERROR, "Error removing guild from LFGuild table, query was %s, %s", query, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
uint32 Now = time(NULL);
|
||||
|
||||
if(Toggle == 1)
|
||||
{
|
||||
GuildLookingForPlayers g(GuildName, Comments, FromLevel, ToLevel, Classes, AACount, TimeZone, Now);
|
||||
Guilds.push_back(g);
|
||||
if(!database.RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `lfguild` (`type`, `name`, `comment`, `fromlevel`, `tolevel`, `classes`, `aacount`, `timezone`, `timeposted`) VALUES(1, '%s', '%s', %u, %u, %u, %u, %u, %u)", GuildName, Comments, FromLevel, ToLevel, Classes, AACount, TimeZone, Now), errbuf, 0, 0))
|
||||
_log(QUERYSERV__ERROR, "Error inserting guild into LFGuild table, query was %s, %s", query, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
}
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_LFGuildUpdate, strlen(GuildName) + strlen(Comments) + 30);
|
||||
|
||||
pack->WriteString(GuildName);
|
||||
pack->WriteString(Comments);
|
||||
pack->WriteUInt32(FromLevel);
|
||||
pack->WriteUInt32(ToLevel);
|
||||
pack->WriteUInt32(Classes);
|
||||
pack->WriteUInt32(AACount);
|
||||
pack->WriteUInt32(TimeZone);
|
||||
pack->WriteUInt32(Now);
|
||||
pack->WriteUInt32(Toggle);
|
||||
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void LFGuildManager::ExpireEntries()
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
|
||||
std::list<PlayerLookingForGuild>::iterator it;
|
||||
std::list<GuildLookingForPlayers>::iterator it2;
|
||||
|
||||
for(it = Players.begin(); it != Players.end(); ++it)
|
||||
{
|
||||
if((*it).TimePosted + 604800 <= (uint32)time(NULL))
|
||||
{
|
||||
if(!database.RunQuery(query, MakeAnyLenString(&query, "DELETE from `lfguild` WHERE `type` = 0 AND `name` = '%s'", (*it).Name.c_str()), errbuf, 0, 0))
|
||||
_log(QUERYSERV__ERROR, "Error expiring player LFGuild entry, query was %s, %s", query, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
it = Players.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
for(it2 = Guilds.begin(); it2 != Guilds.end(); ++it2)
|
||||
{
|
||||
if((*it2).TimePosted + 2592000 <= time(NULL))
|
||||
{
|
||||
if(!database.RunQuery(query, MakeAnyLenString(&query, "DELETE from `lfguild` WHERE `type` = 1 AND `name` = '%s'", (*it2).Name.c_str()), errbuf, 0, 0))
|
||||
_log(QUERYSERV__ERROR, "Error removing guild LFGuild entry, query was %s, %s", query, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
|
||||
it2 = Guilds.erase(it2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LFGuildManager::SendPlayerStatus(uint32 FromZoneID, uint32 FromInstanceID, char *From)
|
||||
{
|
||||
|
||||
std::list<PlayerLookingForGuild>::iterator it;
|
||||
|
||||
for(it = Players.begin(); it != Players.end(); ++it)
|
||||
{
|
||||
if(!strcasecmp((*it).Name.c_str(), From))
|
||||
{
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(From) + (*it).Comments.length() + 30);
|
||||
|
||||
pack->WriteUInt32(FromZoneID);
|
||||
pack->WriteUInt32(FromInstanceID);
|
||||
pack->WriteString(From);
|
||||
pack->WriteUInt32(QSG_LFGuild);
|
||||
pack->WriteUInt32(QSG_LFGuild_RequestPlayerInfo);
|
||||
pack->WriteString((*it).Comments.c_str());
|
||||
pack->WriteUInt32((*it).TimeZone);
|
||||
pack->WriteUInt32((*it).TimePosted);
|
||||
pack->WriteUInt32(1);
|
||||
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LFGuildManager::SendGuildStatus(uint32 FromZoneID, uint32 FromInstanceID, char *From, char *GuildName)
|
||||
{
|
||||
std::list<GuildLookingForPlayers>::iterator it;
|
||||
|
||||
for(it = Guilds.begin(); it != Guilds.end(); ++it)
|
||||
{
|
||||
if(!strcasecmp((*it).Name.c_str(), GuildName))
|
||||
{
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(From) + (*it).Comments.length() + 42);
|
||||
|
||||
pack->WriteUInt32(FromZoneID);
|
||||
pack->WriteUInt32(FromInstanceID);
|
||||
pack->WriteString(From);
|
||||
pack->WriteUInt32(QSG_LFGuild);
|
||||
pack->WriteUInt32(QSG_LFGuild_RequestGuildInfo);
|
||||
pack->WriteString((*it).Comments.c_str());
|
||||
pack->WriteUInt32((*it).FromLevel);
|
||||
pack->WriteUInt32((*it).ToLevel);
|
||||
pack->WriteUInt32((*it).Classes);
|
||||
pack->WriteUInt32((*it).AACount);
|
||||
pack->WriteUInt32((*it).TimeZone);
|
||||
pack->WriteUInt32((*it).TimePosted);
|
||||
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef LFGUILD_H
|
||||
#define LFGUILD_H
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "../common/types.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
class PlayerLookingForGuild
|
||||
{
|
||||
|
||||
public:
|
||||
PlayerLookingForGuild(char *Name, char *Comments, uint32 Level, uint32 Class, uint32 AACount, uint32 Timezone, uint32 TimePosted);
|
||||
|
||||
std::string Name;
|
||||
std::string Comments;
|
||||
uint32 Level;
|
||||
uint32 Class;
|
||||
uint32 AACount;
|
||||
uint32 TimeZone;
|
||||
uint32 TimePosted;
|
||||
};
|
||||
|
||||
class GuildLookingForPlayers
|
||||
{
|
||||
|
||||
public:
|
||||
GuildLookingForPlayers(char *Name, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Timezone, uint32 TimePosted);
|
||||
|
||||
std::string Name;
|
||||
std::string Comments;
|
||||
uint32 FromLevel;
|
||||
uint32 ToLevel;
|
||||
uint32 Classes;
|
||||
uint32 AACount;
|
||||
uint32 TimeZone;
|
||||
uint32 TimePosted;
|
||||
};
|
||||
|
||||
class LFGuildManager
|
||||
{
|
||||
|
||||
public:
|
||||
bool LoadDatabase();
|
||||
void HandlePacket(ServerPacket *pack);
|
||||
void ExpireEntries();
|
||||
private:
|
||||
void SendPlayerMatches(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 FromLevel, uint32 ToLevel, uint32 MinAA, uint32 TimeZone, uint32 Classes);
|
||||
void SendGuildMatches(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 Level, uint32 AAPoints, uint32 TimeZone, uint32 Class);
|
||||
void TogglePlayer(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 Class, uint32 Level, uint32 AAPoints, char *Comments, uint32 Toggle, uint32 TimeZone);
|
||||
void ToggleGuild(uint32 FromZoneID, uint32 FromInstanceID, char *From, char* GuildName, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Toggle, uint32 TimeZone);
|
||||
void SendPlayerStatus(uint32 FromZoneID, uint32 FromInstanceID, char *From);
|
||||
void SendGuildStatus(uint32 FromZoneID, uint32 FromInstanceID, char *From, char *GuildName);
|
||||
std::list<PlayerLookingForGuild> Players;
|
||||
std::list<GuildLookingForPlayers> Guilds;
|
||||
};
|
||||
#endif /* LFGUILD_H */
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
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 "../common/debug.h"
|
||||
#include "../common/opcodemgr.h"
|
||||
#include "../common/EQStreamFactory.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/platform.h"
|
||||
#include "../common/crash.h"
|
||||
#include "database.h"
|
||||
#include "queryservconfig.h"
|
||||
#include "worldserver.h"
|
||||
#include "lfguild.h"
|
||||
#include <list>
|
||||
#include <signal.h>
|
||||
|
||||
volatile bool RunLoops = true;
|
||||
|
||||
uint32 MailMessagesSent = 0;
|
||||
uint32 ChatMessagesSent = 0;
|
||||
|
||||
TimeoutManager timeout_manager;
|
||||
|
||||
Database database;
|
||||
LFGuildManager lfguildmanager;
|
||||
string WorldShortName;
|
||||
|
||||
// RuleManager *rules = new RuleManager();
|
||||
|
||||
const queryservconfig *Config;
|
||||
|
||||
WorldServer *worldserver = 0;
|
||||
|
||||
|
||||
void CatchSignal(int sig_num) {
|
||||
|
||||
RunLoops = false;
|
||||
|
||||
if(worldserver)
|
||||
worldserver->Disconnect();
|
||||
}
|
||||
|
||||
int main() {
|
||||
RegisterExecutablePlatform(ExePlatformQueryServ);
|
||||
set_exception_handler();
|
||||
|
||||
Timer LFGuildExpireTimer(60000);
|
||||
|
||||
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
|
||||
|
||||
_log(QUERYSERV__INIT, "Starting EQEmu QueryServ.");
|
||||
|
||||
if (!queryservconfig::LoadConfig()) {
|
||||
|
||||
_log(QUERYSERV__INIT, "Loading server configuration failed.");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
Config = queryservconfig::get();
|
||||
|
||||
if(!load_log_settings(Config->LogSettingsFile.c_str()))
|
||||
_log(QUERYSERV__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
|
||||
else
|
||||
_log(QUERYSERV__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
|
||||
|
||||
WorldShortName = Config->ShortName;
|
||||
|
||||
_log(QUERYSERV__INIT, "Connecting to MySQL...");
|
||||
|
||||
if (!database.Connect(
|
||||
Config->QSDatabaseHost.c_str(),
|
||||
Config->QSDatabaseUsername.c_str(),
|
||||
Config->QSDatabasePassword.c_str(),
|
||||
Config->QSDatabaseDB.c_str(),
|
||||
Config->QSDatabasePort)) {
|
||||
_log(WORLD__INIT_ERR, "Cannot continue without a database connection.");
|
||||
return(1);
|
||||
}
|
||||
|
||||
char tmp[64];
|
||||
|
||||
// Disable the Rule system, since we could be split brained from the main database
|
||||
// if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
|
||||
// _log(WORLD__INIT, "Loading rule set '%s'", tmp);
|
||||
// if(!rules->LoadRules(&database, tmp)) {
|
||||
// _log(QUERYSERV__ERROR, "Failed to load ruleset '%s', falling back to defaults.", tmp);
|
||||
// }
|
||||
// } else {
|
||||
// if(!rules->LoadRules(&database, "default")) {
|
||||
// _log(QUERYSERV__INIT, "No rule set configured, using default rules");
|
||||
// } else {
|
||||
// _log(QUERYSERV__INIT, "Loaded default rule set 'default'", tmp);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
|
||||
_log(QUERYSERV__ERROR, "Could not set signal handler");
|
||||
return 0;
|
||||
}
|
||||
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
|
||||
_log(QUERYSERV__ERROR, "Could not set signal handler");
|
||||
return 0;
|
||||
}
|
||||
|
||||
worldserver = new WorldServer;
|
||||
|
||||
worldserver->Connect();
|
||||
|
||||
lfguildmanager.LoadDatabase();
|
||||
|
||||
while(RunLoops) {
|
||||
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
if(LFGuildExpireTimer.Check())
|
||||
lfguildmanager.ExpireEntries();
|
||||
|
||||
if (InterserverTimer.Check()) {
|
||||
if (worldserver->TryReconnect() && (!worldserver->Connected()))
|
||||
worldserver->AsyncConnect();
|
||||
}
|
||||
worldserver->Process();
|
||||
|
||||
timeout_manager.CheckTimeouts();
|
||||
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateWindowTitle(char* iNewTitle) {
|
||||
#ifdef _WINDOWS
|
||||
char tmp[500];
|
||||
if (iNewTitle) {
|
||||
snprintf(tmp, sizeof(tmp), "QueryServ: %s", iNewTitle);
|
||||
}
|
||||
else {
|
||||
snprintf(tmp, sizeof(tmp), "QueryServ");
|
||||
}
|
||||
SetConsoleTitle(tmp);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
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 "../common/debug.h"
|
||||
#include "queryservconfig.h"
|
||||
|
||||
queryservconfig *queryservconfig::_chat_config = NULL;
|
||||
|
||||
string queryservconfig::GetByName(const string &var_name) const {
|
||||
return(EQEmuConfig::GetByName(var_name));
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
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 __queryservconfig_H
|
||||
#define __queryservconfig_H
|
||||
|
||||
#include "../common/EQEmuConfig.h"
|
||||
|
||||
class queryservconfig : public EQEmuConfig {
|
||||
public:
|
||||
virtual string GetByName(const string &var_name) const;
|
||||
|
||||
private:
|
||||
|
||||
static queryservconfig *_chat_config;
|
||||
|
||||
public:
|
||||
|
||||
// Produce a const singleton
|
||||
static const queryservconfig *get() {
|
||||
if (_chat_config == NULL)
|
||||
LoadConfig();
|
||||
return(_chat_config);
|
||||
}
|
||||
|
||||
// Load the config
|
||||
static bool LoadConfig() {
|
||||
if (_chat_config != NULL)
|
||||
delete _chat_config;
|
||||
_chat_config=new queryservconfig;
|
||||
_config=_chat_config;
|
||||
|
||||
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(),"server");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,179 @@
|
||||
/* 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>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../common/servertalk.h"
|
||||
#include "worldserver.h"
|
||||
#include "queryservconfig.h"
|
||||
#include "database.h"
|
||||
#include "lfguild.h"
|
||||
#include "../common/packet_functions.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/packet_dump.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
extern const queryservconfig *Config;
|
||||
extern Database database;
|
||||
extern LFGuildManager lfguildmanager;
|
||||
|
||||
WorldServer::WorldServer()
|
||||
: WorldConnection(EmuTCPConnection::packetModeQueryServ, Config->SharedKey.c_str())
|
||||
{
|
||||
pTryReconnect = true;
|
||||
}
|
||||
|
||||
WorldServer::~WorldServer()
|
||||
{
|
||||
}
|
||||
|
||||
void WorldServer::OnConnected()
|
||||
{
|
||||
_log(QUERYSERV__INIT, "Connected to World.");
|
||||
WorldConnection::OnConnected();
|
||||
}
|
||||
|
||||
void WorldServer::Process()
|
||||
{
|
||||
WorldConnection::Process();
|
||||
|
||||
if (!Connected())
|
||||
return;
|
||||
|
||||
ServerPacket *pack = 0;
|
||||
|
||||
while((pack = tcpc.PopPacket()))
|
||||
{
|
||||
_log(QUERYSERV__TRACE, "Received Opcode: %4X", pack->opcode);
|
||||
|
||||
switch(pack->opcode)
|
||||
{
|
||||
case 0: {
|
||||
break;
|
||||
}
|
||||
case ServerOP_KeepAlive:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case ServerOP_Speech:
|
||||
{
|
||||
Server_Speech_Struct *SSS = (Server_Speech_Struct*)pack->pBuffer;
|
||||
|
||||
string tmp1 = SSS->from;
|
||||
string tmp2 = SSS->to;
|
||||
|
||||
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogTrades:
|
||||
{
|
||||
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char1_count + QS->char2_count;
|
||||
database.LogPlayerTrade(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogHandins:
|
||||
{
|
||||
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char_count + QS->npc_count;
|
||||
database.LogPlayerHandin(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogNPCKills:
|
||||
{
|
||||
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer;
|
||||
uint32 Members = pack->size - sizeof(QSPlayerLogNPCKill_Struct);
|
||||
if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct);
|
||||
database.LogPlayerNPCKill(QS, Members);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogDeletes:
|
||||
{
|
||||
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char_count;
|
||||
database.LogPlayerDelete(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogMoves:
|
||||
{
|
||||
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char_count;
|
||||
database.LogPlayerMove(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSMerchantLogTransactions:
|
||||
{
|
||||
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char_count + QS->merchant_count;
|
||||
database.LogMerchantTransaction(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QueryServGeneric:
|
||||
{
|
||||
// The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
|
||||
// each time we add functionality to queryserv.
|
||||
//
|
||||
// A ServerOP_QueryServGeneric packet has the following format:
|
||||
//
|
||||
// uint32 SourceZoneID
|
||||
// uint32 SourceInstanceID
|
||||
// char OriginatingCharacterName[0] // Null terminated name of the character this packet came from. This could be just
|
||||
// // an empty string if it has no meaning in the context of a particular packet.
|
||||
// uint32 Type
|
||||
//
|
||||
// The 'Type' field is a 'sub-opcode'. A value of 0 is used for the LFGuild packets. The next feature to be added
|
||||
// to queryserv would use 1, etc.
|
||||
//
|
||||
// Obviously, any fields in the packet following the 'Type' will be unique to the particular type of packet. The
|
||||
// 'Generic' in the name of this ServerOP code relates to the four header fields.
|
||||
char From[64];
|
||||
pack->SetReadPosition(8);
|
||||
pack->ReadString(From);
|
||||
uint32 Type = pack->ReadUInt32();
|
||||
|
||||
switch(Type)
|
||||
{
|
||||
case QSG_LFGuild:
|
||||
{
|
||||
lfguildmanager.HandlePacket(pack);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
_log(QUERYSERV__ERROR, "Received unhandled ServerOP_QueryServGeneric", Type);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
safe_delete(pack);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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 WORLDSERVER_H
|
||||
#define WORLDSERVER_H
|
||||
|
||||
#include "../common/worldconn.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
|
||||
class WorldServer : public WorldConnection
|
||||
{
|
||||
public:
|
||||
WorldServer();
|
||||
virtual ~WorldServer();
|
||||
virtual void Process();
|
||||
|
||||
private:
|
||||
virtual void OnConnected();
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user