mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-30 07:35:45 +00:00
Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c6ec2117a | |||
| 2218f46b5b | |||
| 53dcd14534 | |||
| dcbc9a358f | |||
| b512447448 | |||
| 444a4f6744 | |||
| 43ec9dc815 | |||
| 9e836a9780 | |||
| 3bc5d4b125 | |||
| 9f033df196 | |||
| 16ee25224d | |||
| 56510e6383 | |||
| bf43bda1e2 | |||
| 5708164511 | |||
| 7abb02655d | |||
| cb08c02537 | |||
| dea94ce63d | |||
| bd302b8394 | |||
| 221140c3c5 | |||
| 7092183103 | |||
| bbbebdd346 | |||
| 05723ad1e8 | |||
| 4c7a625d7c | |||
| 1b82e6b283 | |||
| 0240a9cc76 | |||
| eb02525d36 | |||
| d7097e84ff | |||
| 3de65d46b4 | |||
| 303b35a755 | |||
| a9e218acfa | |||
| 0f2da56b04 | |||
| f3f8a50d3c | |||
| bc72641eef | |||
| 18bfee5616 | |||
| 6c8930eacd | |||
| e18d4a81c5 | |||
| 77c3841a49 | |||
| 832bffa811 | |||
| 267472fc91 | |||
| 44f760d177 | |||
| 50fc4d68aa | |||
| ee167bbc64 | |||
| b20d0b84f6 | |||
| 267d73ca27 | |||
| c1626da40d | |||
| 554b41d424 | |||
| 714fb032e9 | |||
| 74dfc1ae3c | |||
| 6b1e3d94f8 | |||
| f357361474 | |||
| f8e7576ae7 | |||
| 19791195e5 | |||
| 9d766bf5dc | |||
| 7ac8fe17e5 | |||
| 959a17daea | |||
| 90406e0328 | |||
| e883703b2f |
+1
-1
@@ -15,7 +15,7 @@ volumes:
|
||||
steps:
|
||||
- name: server-build
|
||||
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
|
||||
image: akkadius/eqemu-server:latest
|
||||
image: akkadius/eqemu-server:v11
|
||||
commands:
|
||||
- sudo chown eqemu:eqemu /drone/src/ * -R
|
||||
- sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
|
||||
|
||||
@@ -28,10 +28,12 @@
|
||||
#include "../../common/strings.h"
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.h"
|
||||
#include "../../common/path_manager.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ExportSpells(SharedDatabase *db);
|
||||
void ExportSkillCaps(SharedDatabase *db);
|
||||
@@ -44,6 +46,8 @@ int main(int argc, char **argv)
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
LogInfo("Client Files Export Utility");
|
||||
if (!EQEmuConfig::LoadConfig()) {
|
||||
LogError("Unable to load configuration file");
|
||||
@@ -86,6 +90,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
@@ -126,7 +131,8 @@ void ExportSpells(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Spells");
|
||||
|
||||
FILE *f = fopen("export/spells_us.txt", "w");
|
||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||
return;
|
||||
@@ -208,7 +214,8 @@ void ExportSkillCaps(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Skill Caps");
|
||||
|
||||
FILE *f = fopen("export/SkillCaps.txt", "w");
|
||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
return;
|
||||
@@ -238,7 +245,8 @@ void ExportBaseData(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Base Data");
|
||||
|
||||
FILE *f = fopen("export/BaseData.txt", "w");
|
||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||
return;
|
||||
@@ -271,7 +279,8 @@ void ExportDBStrings(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting DB Strings");
|
||||
|
||||
FILE *f = fopen("export/dbstr_us.txt", "w");
|
||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
return;
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
#include "../../common/strings.h"
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.h"
|
||||
#include "../../common/path_manager.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ImportSpells(SharedDatabase *db);
|
||||
void ImportSkillCaps(SharedDatabase *db);
|
||||
@@ -41,6 +43,8 @@ int main(int argc, char **argv) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
LogInfo("Client Files Import Utility");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
LogError("Unable to load configuration file.");
|
||||
@@ -83,6 +87,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
@@ -127,9 +132,10 @@ bool IsStringField(int i) {
|
||||
|
||||
void ImportSpells(SharedDatabase *db) {
|
||||
LogInfo("Importing Spells");
|
||||
FILE *f = fopen("import/spells_us.txt", "r");
|
||||
std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open import/spells_us.txt to read, skipping.");
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -216,9 +222,10 @@ void ImportSpells(SharedDatabase *db) {
|
||||
void ImportSkillCaps(SharedDatabase *db) {
|
||||
LogInfo("Importing Skill Caps");
|
||||
|
||||
FILE *f = fopen("import/SkillCaps.txt", "r");
|
||||
std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,9 +258,10 @@ void ImportSkillCaps(SharedDatabase *db) {
|
||||
void ImportBaseData(SharedDatabase *db) {
|
||||
LogInfo("Importing Base Data");
|
||||
|
||||
FILE *f = fopen("import/BaseData.txt", "r");
|
||||
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open import/BaseData.txt to read, skipping.");
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -296,9 +304,10 @@ void ImportBaseData(SharedDatabase *db) {
|
||||
void ImportDBStrings(SharedDatabase *db) {
|
||||
LogInfo("Importing DB Strings");
|
||||
|
||||
FILE *f = fopen("import/dbstr_us.txt", "r");
|
||||
std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ SET(common_sources
|
||||
extprofile.cpp
|
||||
discord_manager.cpp
|
||||
faction.cpp
|
||||
file_util.cpp
|
||||
file.cpp
|
||||
guild_base.cpp
|
||||
guilds.cpp
|
||||
inventory_profile.cpp
|
||||
@@ -61,6 +61,7 @@ SET(common_sources
|
||||
packet_dump.cpp
|
||||
packet_dump_file.cpp
|
||||
packet_functions.cpp
|
||||
path_manager.cpp
|
||||
perl_eqdb.cpp
|
||||
perl_eqdb_res.cpp
|
||||
proc_launcher.cpp
|
||||
@@ -529,7 +530,7 @@ SET(common_headers
|
||||
expedition_lockout_timer.h
|
||||
extprofile.h
|
||||
faction.h
|
||||
file_util.h
|
||||
file.h
|
||||
features.h
|
||||
fixed_memory_hash_set.h
|
||||
fixed_memory_variable_hash_set.h
|
||||
@@ -565,6 +566,7 @@ SET(common_headers
|
||||
packet_dump.h
|
||||
packet_dump_file.h
|
||||
packet_functions.h
|
||||
path_manager.cpp
|
||||
platform.h
|
||||
proc_launcher.h
|
||||
profanity_manager.h
|
||||
@@ -648,6 +650,7 @@ SET(common_headers
|
||||
patches/uf_limits.h
|
||||
patches/uf_ops.h
|
||||
patches/uf_structs.h
|
||||
stacktrace/backward.hpp
|
||||
StackWalker/StackWalker.h
|
||||
util/memory_stream.h
|
||||
util/directory.h
|
||||
|
||||
+49
-33
@@ -376,9 +376,10 @@ bool Database::ReserveName(uint32 account_id, char* name) {
|
||||
* @param character_name
|
||||
* @return
|
||||
*/
|
||||
bool Database::DeleteCharacter(char *character_name) {
|
||||
bool Database::DeleteCharacter(char *character_name)
|
||||
{
|
||||
uint32 character_id = 0;
|
||||
if(!character_name || !strlen(character_name)) {
|
||||
if (!character_name || !strlen(character_name)) {
|
||||
LogInfo("DeleteCharacter: request to delete without a name (empty char slot)");
|
||||
return false;
|
||||
}
|
||||
@@ -390,45 +391,60 @@ bool Database::DeleteCharacter(char *character_name) {
|
||||
}
|
||||
|
||||
if (character_id <= 0) {
|
||||
LogError("DeleteCharacter | Invalid Character ID [{}]", character_name);
|
||||
LogError("[DeleteCharacter] Invalid Character ID [{}]", character_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string delete_type = "hard-deleted";
|
||||
if (RuleB(Character, SoftDeletes)) {
|
||||
delete_type = "soft-deleted";
|
||||
std::string query = fmt::format(
|
||||
SQL(
|
||||
UPDATE
|
||||
character_data
|
||||
SET
|
||||
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64),
|
||||
deleted_at = NOW()
|
||||
WHERE
|
||||
id = '{}'
|
||||
),
|
||||
character_id
|
||||
);
|
||||
|
||||
QueryDatabase(query);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LogInfo("DeleteCharacter | Character [{}] ({}) is being [{}]", character_name, character_id, delete_type);
|
||||
|
||||
for (const auto& iter : DatabaseSchema::GetCharacterTables()) {
|
||||
std::string table_name = iter.first;
|
||||
std::string character_id_column_name = iter.second;
|
||||
|
||||
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", character_id); // note: only use of GetMobTypeById()
|
||||
QueryDatabase(query);
|
||||
#endif
|
||||
|
||||
std::string delete_type = "hard-deleted";
|
||||
if (RuleB(Character, SoftDeletes)) {
|
||||
delete_type = "soft-deleted";
|
||||
query = fmt::format(
|
||||
SQL(
|
||||
UPDATE
|
||||
character_data
|
||||
SET
|
||||
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64),
|
||||
deleted_at = NOW()
|
||||
WHERE
|
||||
id = '{}'
|
||||
),
|
||||
character_id
|
||||
);
|
||||
|
||||
QueryDatabase(query);
|
||||
|
||||
#ifdef BOTS
|
||||
query = fmt::format(
|
||||
SQL(
|
||||
UPDATE
|
||||
bot_data
|
||||
SET
|
||||
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64)
|
||||
WHERE
|
||||
owner_id = '{}'
|
||||
),
|
||||
character_id
|
||||
);
|
||||
QueryDatabase(query);
|
||||
LogInfo("[DeleteCharacter] character_name [{}] ({}) bots are being [{}]", character_name, character_id, delete_type);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto &iter: DatabaseSchema::GetCharacterTables()) {
|
||||
std::string table_name = iter.first;
|
||||
std::string character_id_column_name = iter.second;
|
||||
|
||||
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
|
||||
}
|
||||
|
||||
LogInfo("[DeleteCharacter] character_name [{}] ({}) is being [{}]", character_name, character_id, delete_type);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../strings.h"
|
||||
#include "../eqemu_config.h"
|
||||
#include "../database_schema.h"
|
||||
#include "../file_util.h"
|
||||
#include "../file.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
@@ -383,8 +383,8 @@ void DatabaseDumpService::Dump()
|
||||
pipe_file
|
||||
);
|
||||
|
||||
if (!FileUtil::exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||
FileUtil::mkdir(GetSetDumpPath());
|
||||
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||
File::Makedir(GetSetDumpPath());
|
||||
}
|
||||
|
||||
if (IsDumpDropTableSyntaxOnly()) {
|
||||
|
||||
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#include "database.h"
|
||||
#include "extprofile.h"
|
||||
#include "path_manager.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
@@ -476,7 +477,9 @@ bool Database::CheckDatabaseConversions() {
|
||||
CheckDatabaseConvertCorpseDeblob();
|
||||
|
||||
/* Run EQEmu Server script (Checks for database updates) */
|
||||
system("perl eqemu_server.pl ran_from_world");
|
||||
|
||||
const std::string file = fmt::format("{}/eqemu_server.pl", path.GetServerPath());
|
||||
system(fmt::format("perl {} ran_from_world", file).c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -513,3 +513,69 @@ std::string EQ::constants::GetObjectTypeName(int object_type)
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> weather_type_map = {
|
||||
{WeatherTypes::None, "None"},
|
||||
{WeatherTypes::Raining, "Raining"},
|
||||
{WeatherTypes::Snowing, "Snowing"}
|
||||
};
|
||||
|
||||
return weather_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
|
||||
{
|
||||
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
|
||||
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> emote_event_type_map = {
|
||||
{ EmoteEventTypes::LeaveCombat, "Leave Combat" },
|
||||
{ EmoteEventTypes::EnterCombat, "Enter Combat" },
|
||||
{ EmoteEventTypes::OnDeath, "On Death" },
|
||||
{ EmoteEventTypes::AfterDeath, "After Death" },
|
||||
{ EmoteEventTypes::Hailed, "Hailed" },
|
||||
{ EmoteEventTypes::KilledPC, "Killed PC" },
|
||||
{ EmoteEventTypes::KilledNPC, "Killed NPC" },
|
||||
{ EmoteEventTypes::OnSpawn, "On Spawn" },
|
||||
{ EmoteEventTypes::OnDespawn, "On Despawn" }
|
||||
};
|
||||
|
||||
return emote_event_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
||||
{
|
||||
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
|
||||
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> emote_type_map = {
|
||||
{ EmoteTypes::Emote, "Emote" },
|
||||
{ EmoteTypes::Shout, "Shout" },
|
||||
{ EmoteTypes::Proximity, "Proximity" }
|
||||
};
|
||||
|
||||
return emote_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
||||
{
|
||||
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
|
||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
@@ -217,6 +217,25 @@ namespace EQ
|
||||
stanceBurnAE
|
||||
};
|
||||
|
||||
enum BotSpellIDs : int {
|
||||
Warrior = 3001,
|
||||
Cleric,
|
||||
Paladin,
|
||||
Ranger,
|
||||
Shadowknight,
|
||||
Druid,
|
||||
Monk,
|
||||
Bard,
|
||||
Rogue,
|
||||
Shaman,
|
||||
Necromancer,
|
||||
Wizard,
|
||||
Magician,
|
||||
Enchanter,
|
||||
Beastlord,
|
||||
Berserker
|
||||
};
|
||||
|
||||
enum GravityBehavior : int8 {
|
||||
Ground,
|
||||
Flying,
|
||||
@@ -312,6 +331,30 @@ namespace EQ
|
||||
NoDeposit
|
||||
};
|
||||
|
||||
enum WeatherTypes : uint8 {
|
||||
None,
|
||||
Raining,
|
||||
Snowing
|
||||
};
|
||||
|
||||
enum EmoteEventTypes : uint8 {
|
||||
LeaveCombat,
|
||||
EnterCombat,
|
||||
OnDeath,
|
||||
AfterDeath,
|
||||
Hailed,
|
||||
KilledPC,
|
||||
KilledNPC,
|
||||
OnSpawn,
|
||||
OnDespawn
|
||||
};
|
||||
|
||||
enum EmoteTypes : uint8 {
|
||||
Emote,
|
||||
Shout,
|
||||
Proximity
|
||||
};
|
||||
|
||||
const char *GetStanceName(StanceType stance_type);
|
||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||
|
||||
@@ -345,6 +388,15 @@ namespace EQ
|
||||
extern const std::map<int, std::string>& GetObjectTypeMap();
|
||||
std::string GetObjectTypeName(int object_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
|
||||
std::string GetWeatherTypeName(uint8 weather_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetEmoteEventTypeMap();
|
||||
std::string GetEmoteEventTypeName(uint8 emote_event_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
||||
std::string GetEmoteTypeName(uint8 emote_type);
|
||||
|
||||
const int STANCE_TYPE_FIRST = stancePassive;
|
||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||
|
||||
@@ -718,7 +718,7 @@ typedef enum {
|
||||
FilterPetMisses = 21, //0=show, 1=hide
|
||||
FilterFocusEffects = 22, //0=show, 1=hide
|
||||
FilterPetSpells = 23, //0=show, 1=hide
|
||||
FilterHealOverTime = 24, //0=show, 1=hide
|
||||
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
|
||||
FilterUnknown25 = 25,
|
||||
FilterUnknown26 = 26,
|
||||
FilterUnknown27 = 27,
|
||||
|
||||
+11
-6
@@ -218,13 +218,13 @@ class EQStream : public EQStreamInterface {
|
||||
|
||||
void init(bool resetSession=true);
|
||||
public:
|
||||
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
|
||||
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
|
||||
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
|
||||
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
|
||||
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
|
||||
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
|
||||
streamactive = false; }
|
||||
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
|
||||
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
|
||||
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
|
||||
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
|
||||
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
|
||||
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
|
||||
create_time = Timer::GetTimeSeconds(); }
|
||||
virtual ~EQStream() { RemoveData(); SetState(CLOSED); }
|
||||
void SetMaxLen(uint32 length) { MaxLen=length; }
|
||||
@@ -243,6 +243,11 @@ class EQStream : public EQStreamInterface {
|
||||
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
|
||||
|
||||
virtual OpcodeManager* GetOpcodeManager() const
|
||||
{
|
||||
return (*OpMgr);
|
||||
};
|
||||
|
||||
void CheckTimeout(uint32 now, uint32 timeout=30);
|
||||
bool HasOutgoingData();
|
||||
void Process(const unsigned char *data, const uint32 length);
|
||||
|
||||
@@ -30,7 +30,7 @@ struct EQStreamManagerInterfaceOptions
|
||||
|
||||
//World seems to support both compression and xor zone supports one or the others.
|
||||
//Enforce one or the other in the convienence construct
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//but that might be because it was still a bit buggy when i was testing that.
|
||||
if (compressed) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||
@@ -100,6 +100,7 @@ public:
|
||||
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
|
||||
virtual EQStreamState GetState() = 0;
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
|
||||
virtual OpcodeManager* GetOpcodeManager() const = 0;
|
||||
virtual const EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
|
||||
virtual Stats GetStats() const = 0;
|
||||
virtual void ResetStats() = 0;
|
||||
|
||||
@@ -38,12 +38,8 @@ void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
|
||||
}
|
||||
|
||||
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||
if(p == nullptr)
|
||||
if (p == nullptr) {
|
||||
return;
|
||||
|
||||
if (p->GetOpcode() != OP_SpecialMesg) {
|
||||
Log(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||
Log(Logs::General, Logs::PacketServerClientWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||
}
|
||||
|
||||
EQApplicationPacket *newp = p->Copy();
|
||||
@@ -112,3 +108,8 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
|
||||
{
|
||||
return (*m_opcodes);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,13 +34,15 @@ public:
|
||||
virtual Stats GetStats() const;
|
||||
virtual void ResetStats();
|
||||
virtual EQStreamManagerInterface* GetManager() const;
|
||||
virtual OpcodeManager* GetOpcodeManager() const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
||||
const StructStrategy *const m_structs; //we do not own this object.
|
||||
//this is a pointer to a pointer to make it less likely that a packet will
|
||||
//reference an invalid opcode manager when they are being reloaded.
|
||||
OpcodeManager **const m_opcodes; //we do not own this object.
|
||||
OpcodeManager **const m_opcodes;
|
||||
//we do not own this object.
|
||||
};
|
||||
|
||||
#endif /*EQSTREAMPROXY_H_*/
|
||||
|
||||
@@ -86,6 +86,7 @@ void EQEmuConfig::parse_config()
|
||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||
WorldUDPPort = atoi(_root["server"]["world"]["udp"].get("port", "9000").asString().c_str());
|
||||
|
||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||
@@ -217,6 +218,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
||||
if (var_name == "WorldTCPPort") {
|
||||
return (itoa(WorldTCPPort));
|
||||
}
|
||||
if (var_name == "WorldUDPPort") {
|
||||
return (itoa(WorldUDPPort));
|
||||
}
|
||||
if (var_name == "WorldIP") {
|
||||
return (WorldIP);
|
||||
}
|
||||
@@ -348,6 +352,7 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "LoginLegacy = " << LoginLegacy << std::endl;
|
||||
std::cout << "Locked = " << Locked << std::endl;
|
||||
std::cout << "WorldTCPPort = " << WorldTCPPort << std::endl;
|
||||
std::cout << "WorldUDPPort = " << WorldUDPPort << std::endl;
|
||||
std::cout << "WorldIP = " << WorldIP << std::endl;
|
||||
std::cout << "TelnetTCPPort = " << TelnetTCPPort << std::endl;
|
||||
std::cout << "TelnetIP = " << TelnetIP << std::endl;
|
||||
|
||||
+16
-5
@@ -20,7 +20,9 @@
|
||||
|
||||
#include "json/json.h"
|
||||
#include "linked_list.h"
|
||||
#include "path_manager.h"
|
||||
#include <fstream>
|
||||
#include <fmt/format.h>
|
||||
|
||||
struct LoginConfig {
|
||||
std::string LoginHost;
|
||||
@@ -49,6 +51,7 @@ class EQEmuConfig
|
||||
LinkedList<LoginConfig*> loginlist;
|
||||
bool Locked;
|
||||
uint16 WorldTCPPort;
|
||||
uint16 WorldUDPPort;
|
||||
std::string WorldIP;
|
||||
uint16 TelnetTCPPort;
|
||||
std::string TelnetIP;
|
||||
@@ -152,23 +155,31 @@ class EQEmuConfig
|
||||
}
|
||||
|
||||
// Load the config
|
||||
static bool LoadConfig()
|
||||
static bool LoadConfig(const std::string& path = "")
|
||||
{
|
||||
if (_config != nullptr) {
|
||||
return true;
|
||||
}
|
||||
_config = new EQEmuConfig;
|
||||
|
||||
return parseFile();
|
||||
return parseFile(path);
|
||||
}
|
||||
|
||||
// Load config file and parse data
|
||||
static bool parseFile() {
|
||||
static bool parseFile(const std::string& file_path = ".")
|
||||
{
|
||||
if (_config == nullptr) {
|
||||
return LoadConfig();
|
||||
return LoadConfig(file_path);
|
||||
}
|
||||
|
||||
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
|
||||
std::string file = fmt::format(
|
||||
"{}/{}",
|
||||
(file_path.empty() ? path.GetServerPath() : file_path),
|
||||
EQEmuConfig::ConfigFile
|
||||
);
|
||||
|
||||
std::ifstream fconfig(file, std::ifstream::binary);
|
||||
|
||||
try {
|
||||
fconfig >> _config->_root;
|
||||
_config->parse_config();
|
||||
|
||||
+109
-80
@@ -212,21 +212,6 @@ bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param log_category
|
||||
* @param in_message
|
||||
* @return
|
||||
*/
|
||||
std::string EQEmuLogSys::FormatOutMessageString(
|
||||
uint16 log_category,
|
||||
const std::string &in_message
|
||||
)
|
||||
{
|
||||
std::string return_string = "[" + GetPlatformName() + "] ";
|
||||
|
||||
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
@@ -423,24 +408,10 @@ void EQEmuLogSys::Out(
|
||||
...
|
||||
)
|
||||
{
|
||||
bool log_to_console = log_settings[log_category].log_to_console > 0 &&
|
||||
log_settings[log_category].log_to_console >= debug_level;
|
||||
bool log_to_file = log_settings[log_category].log_to_file > 0 &&
|
||||
log_settings[log_category].log_to_file >= debug_level;
|
||||
bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0 &&
|
||||
log_settings[log_category].log_to_gmsay >= debug_level &&
|
||||
log_category != Logs::LogCategory::Netcode &&
|
||||
(EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone ||
|
||||
EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld);
|
||||
bool log_to_discord = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone &&
|
||||
log_settings[log_category].log_to_discord > 0 &&
|
||||
log_settings[log_category].log_to_discord >= debug_level &&
|
||||
log_settings[log_category].discord_webhook_id > 0 &&
|
||||
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
|
||||
auto l = GetLogsEnabled(debug_level, log_category);
|
||||
|
||||
// bail out if nothing to log
|
||||
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay && !log_to_discord;
|
||||
if (nothing_to_log) {
|
||||
if (!l.log_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -449,23 +420,39 @@ void EQEmuLogSys::Out(
|
||||
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
std::string output_message = vStringFormat(message, args);
|
||||
va_end(args);
|
||||
// remove this when we remove all legacy logs
|
||||
bool ignore_log_legacy_format = (
|
||||
log_category == Logs::Netcode ||
|
||||
log_category == Logs::PacketServerClient ||
|
||||
log_category == Logs::PacketClientServer ||
|
||||
log_category == Logs::PacketServerToServer
|
||||
);
|
||||
|
||||
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
|
||||
|
||||
if (log_to_console) {
|
||||
EQEmuLogSys::ProcessConsoleMessage(log_category, output_debug_message);
|
||||
// remove this when we remove all legacy logs
|
||||
std::string output_message = message;
|
||||
if (!ignore_log_legacy_format) {
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
output_message = vStringFormat(message, args);
|
||||
va_end(args);
|
||||
}
|
||||
if (log_to_gmsay) {
|
||||
|
||||
if (l.log_to_console_enabled) {
|
||||
EQEmuLogSys::ProcessConsoleMessage(
|
||||
log_category,
|
||||
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
|
||||
);
|
||||
}
|
||||
if (l.log_to_gmsay_enabled) {
|
||||
m_on_log_gmsay_hook(log_category, output_message);
|
||||
}
|
||||
if (log_to_file) {
|
||||
EQEmuLogSys::ProcessLogWrite(log_category, output_debug_message);
|
||||
if (l.log_to_file_enabled) {
|
||||
EQEmuLogSys::ProcessLogWrite(
|
||||
log_category,
|
||||
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
|
||||
);
|
||||
}
|
||||
if (log_to_discord && m_on_log_discord_hook) {
|
||||
if (l.log_to_discord_enabled && m_on_log_discord_hook) {
|
||||
m_on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message);
|
||||
}
|
||||
}
|
||||
@@ -479,7 +466,7 @@ void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp)
|
||||
struct tm *time_info;
|
||||
time(&raw_time);
|
||||
time_info = localtime(&raw_time);
|
||||
strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info);
|
||||
strftime(time_stamp, 80, "[%m-%d-%Y %H:%M:%S]", time_info);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -534,37 +521,29 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
return;
|
||||
}
|
||||
|
||||
LogInfo("Starting File Log [logs/{}_{}.log]", m_platform_file_name.c_str(), getpid());
|
||||
LogInfo("Starting File Log [{}/zone/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
|
||||
|
||||
/**
|
||||
* Make directory if not exists
|
||||
*/
|
||||
EQEmuLogSys::MakeDirectory("logs/zone");
|
||||
// Make directory if not exists
|
||||
EQEmuLogSys::MakeDirectory(fmt::format("{}/zone", GetLogPath()));
|
||||
|
||||
/**
|
||||
* Open file pointer
|
||||
*/
|
||||
// Open file pointer
|
||||
process_log.open(
|
||||
StringFormat("logs/zone/%s_%i.log", m_platform_file_name.c_str(), getpid()),
|
||||
fmt::format("{}/zone/{}_{}.log", GetLogPath(), m_platform_file_name, getpid()),
|
||||
std::ios_base::app | std::ios_base::out
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
/**
|
||||
* All other processes
|
||||
*/
|
||||
// All other processes
|
||||
if (m_platform_file_name.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogInfo("Starting File Log [logs/{}_{}.log]", m_platform_file_name.c_str(), getpid());
|
||||
LogInfo("Starting File Log [{}/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
|
||||
|
||||
/**
|
||||
* Open file pointer
|
||||
*/
|
||||
// Open file pointer
|
||||
process_log.open(
|
||||
StringFormat("logs/%s_%i.log", m_platform_file_name.c_str(), getpid()),
|
||||
fmt::format("{}/{}_{}.log", GetLogPath(), m_platform_file_name.c_str(), getpid()),
|
||||
std::ios_base::app | std::ios_base::out
|
||||
);
|
||||
}
|
||||
@@ -642,10 +621,19 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
|
||||
// Auto inject categories that don't exist in the database...
|
||||
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
||||
if (std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end()) {
|
||||
|
||||
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
||||
bool is_deprecated_category = Strings::Contains(fmt::format("{}", Logs::LogCategoryName[i]), "Deprecated");
|
||||
if (!is_missing_in_database && is_deprecated_category) {
|
||||
LogInfo("Logging category [{}] ({}) is now deprecated, deleting from database", Logs::LogCategoryName[i], i);
|
||||
LogsysCategoriesRepository::DeleteOne(*m_database, i);
|
||||
}
|
||||
|
||||
if (is_missing_in_database && !is_deprecated_category) {
|
||||
LogInfo(
|
||||
"Automatically adding new log category [{0}]",
|
||||
Logs::LogCategoryName[i]
|
||||
"Automatically adding new log category [{}] ({})",
|
||||
Logs::LogCategoryName[i],
|
||||
i
|
||||
);
|
||||
|
||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||
@@ -696,13 +684,13 @@ void EQEmuLogSys::InjectTablesIfNotExist()
|
||||
CREATE TABLE discord_webhooks
|
||||
(
|
||||
id INT auto_increment primary key NULL,
|
||||
webhook_name varchar(100) NULL,
|
||||
webhook_url varchar(255) NULL,
|
||||
created_at DATETIME NULL,
|
||||
deleted_at DATETIME NULL
|
||||
) ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb4
|
||||
COLLATE=utf8mb4_general_ci;
|
||||
webhook_name varchar(100) NULL,
|
||||
webhook_url varchar(255) NULL,
|
||||
created_at DATETIME NULL,
|
||||
deleted_at DATETIME NULL
|
||||
) ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb4
|
||||
COLLATE=utf8mb4_general_ci;
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -713,15 +701,15 @@ void EQEmuLogSys::InjectTablesIfNotExist()
|
||||
m_database->QueryDatabase(
|
||||
SQL(
|
||||
CREATE TABLE `logsys_categories` (
|
||||
`log_category_id` int(11) NOT NULL,
|
||||
`log_category_description` varchar(150) DEFAULT NULL,
|
||||
`log_to_console` smallint(11) DEFAULT 0,
|
||||
`log_to_file` smallint(11) DEFAULT 0,
|
||||
`log_to_gmsay` smallint(11) DEFAULT 0,
|
||||
`log_to_discord` smallint(11) DEFAULT 0,
|
||||
`discord_webhook_id` int(11) DEFAULT 0,
|
||||
PRIMARY KEY (`log_category_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
`log_category_id` int(11) NOT NULL,
|
||||
`log_category_description` varchar(150) DEFAULT NULL,
|
||||
`log_to_console` smallint(11) DEFAULT 0,
|
||||
`log_to_file` smallint(11) DEFAULT 0,
|
||||
`log_to_gmsay` smallint(11) DEFAULT 0,
|
||||
`log_to_discord` smallint(11) DEFAULT 0,
|
||||
`discord_webhook_id` int(11) DEFAULT 0,
|
||||
PRIMARY KEY (`log_category_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -732,3 +720,44 @@ const EQEmuLogSys::DiscordWebhooks *EQEmuLogSys::GetDiscordWebhooks() const
|
||||
return m_discord_webhooks;
|
||||
}
|
||||
|
||||
EQEmuLogSys::LogEnabled EQEmuLogSys::GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
||||
{
|
||||
auto e = LogEnabled{};
|
||||
|
||||
e.log_to_console_enabled = log_settings[log_category].log_to_console > 0 &&
|
||||
log_settings[log_category].log_to_console >= debug_level;
|
||||
e.log_to_file_enabled = log_settings[log_category].log_to_file > 0 &&
|
||||
log_settings[log_category].log_to_file >= debug_level;
|
||||
e.log_to_gmsay_enabled = log_settings[log_category].log_to_gmsay > 0 &&
|
||||
log_settings[log_category].log_to_gmsay >= debug_level &&
|
||||
log_category != Logs::LogCategory::Netcode &&
|
||||
(EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone ||
|
||||
EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld);
|
||||
e.log_to_discord_enabled = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone &&
|
||||
log_settings[log_category].log_to_discord > 0 &&
|
||||
log_settings[log_category].log_to_discord >= debug_level &&
|
||||
log_settings[log_category].discord_webhook_id > 0 &&
|
||||
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
|
||||
e.log_enabled =
|
||||
e.log_to_console_enabled || e.log_to_file_enabled || e.log_to_gmsay_enabled || e.log_to_discord_enabled;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool EQEmuLogSys::IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
||||
{
|
||||
return GetLogsEnabled(debug_level, log_category).log_enabled;
|
||||
}
|
||||
|
||||
const std::string &EQEmuLogSys::GetLogPath() const
|
||||
{
|
||||
return m_log_path;
|
||||
}
|
||||
|
||||
EQEmuLogSys * EQEmuLogSys::SetLogPath(const std::string &log_path)
|
||||
{
|
||||
EQEmuLogSys::m_log_path = log_path;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+31
-11
@@ -54,7 +54,7 @@ namespace Logs {
|
||||
AI,
|
||||
Aggro,
|
||||
Attack,
|
||||
PacketClientServer,
|
||||
DeprecatedCS,
|
||||
Combat,
|
||||
Commands,
|
||||
Crash,
|
||||
@@ -88,10 +88,10 @@ namespace Logs {
|
||||
MySQLQuery,
|
||||
Mercenaries,
|
||||
QuestDebug,
|
||||
PacketServerClient,
|
||||
PacketClientServerUnhandled,
|
||||
PacketServerClientWithDump,
|
||||
PacketClientServerWithDump,
|
||||
DeprecatedSC,
|
||||
DeprecatedCSU,
|
||||
DeprecatedSCD,
|
||||
DeprecatedCSD,
|
||||
Loginserver,
|
||||
ClientLogin,
|
||||
HeadlessClient,
|
||||
@@ -132,6 +132,9 @@ namespace Logs {
|
||||
Hate,
|
||||
Discord,
|
||||
Faction,
|
||||
PacketServerClient,
|
||||
PacketClientServer,
|
||||
PacketServerToServer,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -144,7 +147,7 @@ namespace Logs {
|
||||
"AI",
|
||||
"Aggro",
|
||||
"Attack",
|
||||
"Packet :: Client -> Server",
|
||||
"Deprecated",
|
||||
"Combat",
|
||||
"Commands",
|
||||
"Crash",
|
||||
@@ -178,10 +181,10 @@ namespace Logs {
|
||||
"MySQL Query",
|
||||
"Mercenaries",
|
||||
"Quest Debug",
|
||||
"Packet :: Server -> Client",
|
||||
"Packet :: Client -> Server Unhandled",
|
||||
"Packet :: Server -> Client (Dump)",
|
||||
"Packet :: Client -> Server (Dump)",
|
||||
"Deprecated",
|
||||
"Deprecated",
|
||||
"Deprecated",
|
||||
"Deprecated",
|
||||
"Login Server",
|
||||
"Client Login",
|
||||
"Headless Client",
|
||||
@@ -222,6 +225,9 @@ namespace Logs {
|
||||
"Hate",
|
||||
"Discord",
|
||||
"Faction",
|
||||
"Packet-S->C",
|
||||
"Packet-C->S",
|
||||
"Packet-S->S"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -313,6 +319,17 @@ public:
|
||||
*/
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
|
||||
struct LogEnabled {
|
||||
bool log_to_file_enabled;
|
||||
bool log_to_console_enabled;
|
||||
bool log_to_gmsay_enabled;
|
||||
bool log_to_discord_enabled;
|
||||
bool log_enabled;
|
||||
};
|
||||
|
||||
LogEnabled GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
bool IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
|
||||
struct DiscordWebhooks {
|
||||
int id;
|
||||
std::string webhook_name;
|
||||
@@ -349,6 +366,9 @@ public:
|
||||
// database
|
||||
EQEmuLogSys *SetDatabase(Database *db);
|
||||
|
||||
[[nodiscard]] const std::string &GetLogPath() const;
|
||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
||||
|
||||
private:
|
||||
|
||||
// reference to database
|
||||
@@ -360,8 +380,8 @@ private:
|
||||
bool m_file_logs_enabled = false;
|
||||
int m_log_platform = 0;
|
||||
std::string m_platform_file_name;
|
||||
std::string m_log_path;
|
||||
|
||||
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
|
||||
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
|
||||
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
||||
|
||||
|
||||
+437
-347
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include "file_util.h"
|
||||
#include "file.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <direct.h>
|
||||
@@ -35,38 +35,48 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <filesystem>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
bool FileUtil::exists(const std::string &name)
|
||||
bool File::Exists(const std::string &name)
|
||||
{
|
||||
std::ifstream f(name.c_str());
|
||||
|
||||
return f.good();
|
||||
return fs::exists(fs::path{name});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void FileUtil::mkdir(const std::string& directory_name)
|
||||
void File::Makedir(const std::string &directory_name)
|
||||
{
|
||||
fs::create_directory(directory_name);
|
||||
fs::permissions(directory_name, fs::perms::owner_all);
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
struct _stat st;
|
||||
if (_stat(directory_name.c_str(), &st) == 0) // exists
|
||||
return;
|
||||
_mkdir(directory_name.c_str());
|
||||
#else
|
||||
struct stat st{};
|
||||
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
||||
return;
|
||||
std::string File::FindEqemuConfigPath()
|
||||
{
|
||||
if (File::Exists(fs::path{File::GetCwd() + "/eqemu_config.json"}.string())) {
|
||||
return File::GetCwd();
|
||||
}
|
||||
::mkdir(directory_name.c_str(), 0755);
|
||||
#endif
|
||||
else if (File::Exists(fs::path{File::GetCwd() + "/../eqemu_config.json"}.string())) {
|
||||
return canonical(fs::path{File::GetCwd() + "/../"}).string();
|
||||
}
|
||||
else if (File::Exists(fs::path{File::GetCwd() + "/login.json"}.string())) {
|
||||
return File::GetCwd();
|
||||
}
|
||||
else if (File::Exists(fs::path{File::GetCwd() + "/../login.json"}.string())) {
|
||||
return canonical(fs::path{File::GetCwd() + "/../"}).string();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool file_exists(const std::string& name) {
|
||||
std::ifstream f(name.c_str());
|
||||
return f.good();
|
||||
std::string File::GetCwd()
|
||||
{
|
||||
return fs::current_path().string();
|
||||
}
|
||||
@@ -18,16 +18,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_FILE_UTIL_H
|
||||
#define EQEMU_FILE_UTIL_H
|
||||
#ifndef EQEMU_FILE_H
|
||||
#define EQEMU_FILE_H
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
class FileUtil {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
class File {
|
||||
public:
|
||||
static bool exists(const std::string &name);
|
||||
static void mkdir(const std::string& directory_name);
|
||||
static bool Exists(const std::string &name);
|
||||
static void Makedir(const std::string& directory_name);
|
||||
static std::string FindEqemuConfigPath();
|
||||
static std::string GetCwd();
|
||||
};
|
||||
|
||||
bool file_exists(const std::string& name);
|
||||
bool Exists(const std::string& name);
|
||||
|
||||
#endif //EQEMU_FILE_UTIL_H
|
||||
#endif //EQEMU_FILE_H
|
||||
+2836
-2113
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@
|
||||
#include "types.h"
|
||||
#include "eqemu_exception.h"
|
||||
#include "eqemu_config.h"
|
||||
#include "path_manager.h"
|
||||
|
||||
namespace EQ {
|
||||
struct IPCMutex::Implementation {
|
||||
@@ -40,12 +41,11 @@ namespace EQ {
|
||||
#endif
|
||||
};
|
||||
|
||||
IPCMutex::IPCMutex(std::string name) : locked_(false) {
|
||||
IPCMutex::IPCMutex(const std::string& name) : locked_(false) {
|
||||
imp_ = new Implementation;
|
||||
#ifdef _WINDOWS
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string final_name = Config->SharedMemDir + "EQEmuMutex_";
|
||||
final_name += name;
|
||||
std::string final_name = fmt::format("{}/EQEmuMutex_{}", Config->SharedMemDir, name);
|
||||
|
||||
imp_->mut_ = CreateMutex(nullptr,
|
||||
FALSE,
|
||||
@@ -55,9 +55,7 @@ namespace EQ {
|
||||
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
|
||||
}
|
||||
#else
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string final_name = Config->SharedMemDir + name;
|
||||
final_name += ".lock";
|
||||
std::string final_name = fmt::format("{}/{}.lock", path.GetSharedMemoryPath(), name);
|
||||
|
||||
#ifdef __DARWIN
|
||||
#if __DARWIN_C_LEVEL < 200809L
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ namespace EQ {
|
||||
Creates a named binary semaphore, basically a semaphore that is init S <- 1
|
||||
\param name The name of this mutex.
|
||||
*/
|
||||
IPCMutex(std::string name);
|
||||
IPCMutex(const std::string& name);
|
||||
|
||||
//! Destructor
|
||||
~IPCMutex();
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace EQ {
|
||||
|
||||
struct MemoryMappedFile::Implementation {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../event/task.h"
|
||||
#include "../data_verification.h"
|
||||
#include "crc32.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include <zlib.h>
|
||||
#include <fmt/format.h>
|
||||
#include <sstream>
|
||||
@@ -308,6 +309,8 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
m_combined[1] = OP_Combined;
|
||||
m_last_session_stats = Clock::now();
|
||||
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
||||
|
||||
LogNetcode("New session [{}] with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
|
||||
}
|
||||
|
||||
//new connection made as client
|
||||
@@ -466,7 +469,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
for (int i = 1; i >= 0; --i) {
|
||||
switch (m_encode_passes[i]) {
|
||||
case EncodeXOR:
|
||||
if (temp.GetInt8(0) == 0)
|
||||
if (temp.GetInt8(0) == 0)
|
||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
else
|
||||
Decode(temp, 1, temp.Length() - 1);
|
||||
@@ -630,6 +633,8 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
DynamicPacket p;
|
||||
p.PutSerialize(0, reply);
|
||||
InternalSend(p);
|
||||
|
||||
LogNetcode("[OP_SessionRequest] Session [{}] started with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -647,6 +652,12 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
|
||||
m_max_packet_size = reply.max_packet_size;
|
||||
ChangeStatus(StatusConnected);
|
||||
|
||||
LogNetcode(
|
||||
"[OP_SessionResponse] Session [{}] refresh with encode key [{}]",
|
||||
m_connect_code,
|
||||
HostToNetwork(m_encode_key)
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -771,6 +782,12 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
SendDisconnect();
|
||||
}
|
||||
|
||||
LogNetcode(
|
||||
"[OP_SessionDisconnect] Session [{}] disconnect with encode key [{}]",
|
||||
m_connect_code,
|
||||
HostToNetwork(m_encode_key)
|
||||
);
|
||||
|
||||
ChangeStatus(StatusDisconnecting);
|
||||
break;
|
||||
}
|
||||
@@ -835,6 +852,7 @@ bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
||||
}
|
||||
|
||||
if (p.Length() < (size_t)m_crc_bytes) {
|
||||
LogNetcode("Session [{}] ignored packet (crc bytes invalid on session)", m_connect_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1078,7 +1096,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto resends = 0;
|
||||
auto now = Clock::now();
|
||||
auto s = &m_streams[stream];
|
||||
@@ -1113,7 +1131,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((size_t)time_since_last_send.count() > entry.second.resend_delay) {
|
||||
auto &p = entry.second.packet;
|
||||
if (p.Length() >= DaybreakHeader::size()) {
|
||||
@@ -1406,8 +1424,8 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
sent.first_sent = Clock::now();
|
||||
sent.times_resent = 0;
|
||||
sent.resend_delay = EQ::Clamp(
|
||||
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
||||
m_owner->m_options.resend_delay_min,
|
||||
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
||||
m_owner->m_options.resend_delay_min,
|
||||
m_owner->m_options.resend_delay_max);
|
||||
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||
stream->sequence_out++;
|
||||
|
||||
@@ -65,6 +65,15 @@ EQ::Net::EQStream::~EQStream()
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||
|
||||
LogPacketServerClient(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(p->GetOpcode()),
|
||||
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
|
||||
p->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "")
|
||||
);
|
||||
|
||||
if (m_opcode_manager && *m_opcode_manager) {
|
||||
uint16 opcode = 0;
|
||||
if (p->GetOpcodeBypass() != 0) {
|
||||
|
||||
@@ -57,6 +57,10 @@ namespace EQ
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) {
|
||||
m_opcode_manager = opm;
|
||||
}
|
||||
virtual OpcodeManager * GetOpcodeManager() const
|
||||
{
|
||||
return (*m_opcode_manager);
|
||||
};
|
||||
|
||||
virtual Stats GetStats() const;
|
||||
virtual void ResetStats();
|
||||
|
||||
@@ -135,7 +135,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
|
||||
auto leg_opcode = *(uint16_t*)&m_buffer[current];
|
||||
auto leg_size = *(uint16_t*)&m_buffer[current + 2] - 4;
|
||||
|
||||
//this creates a small edge case where the exact size of a
|
||||
//this creates a small edge case where the exact size of a
|
||||
//packet from the modern protocol can't be "43061256"
|
||||
//so in send we pad it one byte if that's the case
|
||||
if (leg_opcode == ServerOP_NewLSInfo && leg_size == sizeof(ServerNewLSInfo_Struct)) {
|
||||
@@ -319,6 +319,16 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
||||
size_t message_len = length;
|
||||
EQ::Net::StaticPacket packet(&data[0], message_len);
|
||||
|
||||
const auto is_detail_enabled = LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerToServer);
|
||||
if (opcode != ServerOP_KeepAlive || is_detail_enabled) {
|
||||
LogPacketServerToServer(
|
||||
"[{:#06x}] Size [{}] {}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
(is_detail_enabled ? "\n" + packet.ToString() : "")
|
||||
);
|
||||
}
|
||||
|
||||
auto cb = m_message_callbacks.find(opcode);
|
||||
if (cb != m_message_callbacks.end()) {
|
||||
cb->second(opcode, packet);
|
||||
|
||||
@@ -184,6 +184,9 @@ uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
||||
MOpcodes.lock();
|
||||
res = emu_to_eq[emu_op];
|
||||
MOpcodes.unlock();
|
||||
|
||||
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
|
||||
|
||||
#ifdef DEBUG_TRANSLATE
|
||||
fprintf(stderr, "M Translate Emu %s (%d) to EQ 0x%.4x\n", OpcodeNames[emu_op], emu_op, res);
|
||||
#endif
|
||||
|
||||
+4
-12
@@ -32,6 +32,7 @@
|
||||
#include "../inventory_profile.h"
|
||||
#include "rof_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -75,12 +76,8 @@ namespace RoF
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
if (opcodes == nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
|
||||
//load up the opcode manager.
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
@@ -118,12 +115,7 @@ namespace RoF
|
||||
//we need to go to every stream and replace it's manager.
|
||||
|
||||
if (opcodes != nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
|
||||
+5
-12
@@ -32,6 +32,7 @@
|
||||
#include "../inventory_profile.h"
|
||||
#include "rof2_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -76,12 +77,9 @@ namespace RoF2
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
if (opcodes == nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
|
||||
//load up the opcode manager.
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
@@ -122,12 +120,7 @@ namespace RoF2
|
||||
//we need to go to every stream and replace it's manager.
|
||||
|
||||
if (opcodes != nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
|
||||
+3
-12
@@ -32,6 +32,7 @@
|
||||
#include "../item_instance.h"
|
||||
#include "sod_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -69,12 +70,7 @@ namespace SoD
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
if (opcodes == nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
//load up the opcode manager.
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
@@ -115,12 +111,7 @@ namespace SoD
|
||||
//we need to go to every stream and replace it's manager.
|
||||
|
||||
if (opcodes != nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
|
||||
+3
-12
@@ -32,6 +32,7 @@
|
||||
#include "../item_instance.h"
|
||||
#include "sof_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -69,12 +70,7 @@ namespace SoF
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
if (opcodes == nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
//load up the opcode manager.
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
@@ -113,12 +109,7 @@ namespace SoF
|
||||
//we need to go to every stream and replace it's manager.
|
||||
|
||||
if (opcodes != nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "../strings.h"
|
||||
#include "../item_instance.h"
|
||||
#include "titanium_structs.h"
|
||||
#include "../path_manager.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@@ -69,11 +70,7 @@ namespace Titanium
|
||||
auto Config = EQEmuConfig::get();
|
||||
//create our opcode manager if we havent already
|
||||
if (opcodes == nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
//load up the opcode manager.
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
@@ -114,12 +111,7 @@ namespace Titanium
|
||||
//we need to go to every stream and replace it's manager.
|
||||
|
||||
if (opcodes != nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
|
||||
+3
-12
@@ -32,6 +32,7 @@
|
||||
#include "../item_instance.h"
|
||||
#include "uf_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -69,12 +70,7 @@ namespace UF
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
if (opcodes == nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
//load up the opcode manager.
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
@@ -115,12 +111,7 @@ namespace UF
|
||||
//we need to go to every stream and replace it's manager.
|
||||
|
||||
if (opcodes != nullptr) {
|
||||
//TODO: get this file name from the config file
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string opfile = Config->PatchDir;
|
||||
opfile += "patch_";
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "path_manager.h"
|
||||
#include "file.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "eqemu_config.h"
|
||||
#include "strings.h"
|
||||
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
inline std::string striptrailingslash(const std::string &file_path)
|
||||
{
|
||||
if (file_path.back() == '/' || file_path.back() == '\\') {
|
||||
return file_path.substr(0, file_path.length() - 1);
|
||||
}
|
||||
|
||||
return file_path;
|
||||
}
|
||||
|
||||
void PathManager::LoadPaths()
|
||||
{
|
||||
m_server_path = File::FindEqemuConfigPath();
|
||||
|
||||
std::filesystem::current_path(m_server_path);
|
||||
|
||||
LogInfo("[PathManager] server [{}]", m_server_path);
|
||||
|
||||
if (!EQEmuConfig::LoadConfig()) {
|
||||
LogError("[PathManager] Failed to load eqemu config");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto c = EQEmuConfig::get();
|
||||
|
||||
// maps
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->MapDir}.string())) {
|
||||
m_maps_path = fs::relative(fs::path{m_server_path + "/" + c->MapDir}).string();
|
||||
}
|
||||
else if (File::Exists(fs::path{m_server_path + "/maps"}.string())) {
|
||||
m_maps_path = fs::relative(fs::path{m_server_path + "/maps"}).string();
|
||||
}
|
||||
else if (File::Exists(fs::path{m_server_path + "/Maps"}.string())) {
|
||||
m_maps_path = fs::relative(fs::path{m_server_path + "/Maps"}).string();
|
||||
}
|
||||
|
||||
// quests
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->QuestDir}.string())) {
|
||||
m_quests_path = fs::relative(fs::path{m_server_path + "/" + c->QuestDir}).string();
|
||||
}
|
||||
|
||||
// plugins
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->PluginDir}.string())) {
|
||||
m_plugins_path = fs::relative(fs::path{m_server_path + "/" + c->PluginDir}).string();
|
||||
}
|
||||
|
||||
// lua_modules
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->LuaModuleDir}.string())) {
|
||||
m_lua_modules_path = fs::relative(fs::path{m_server_path + "/" + c->LuaModuleDir}).string();
|
||||
}
|
||||
|
||||
// lua mods
|
||||
if (File::Exists(fs::path{ m_server_path + "/mods" }.string())) {
|
||||
m_lua_mods_path = fs::relative(fs::path{ m_server_path + "/mods" }).string();
|
||||
}
|
||||
|
||||
// patches
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->PatchDir}.string())) {
|
||||
m_patch_path = fs::relative(fs::path{m_server_path + "/" + c->PatchDir}).string();
|
||||
}
|
||||
|
||||
// shared_memory_path
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->SharedMemDir}.string())) {
|
||||
m_shared_memory_path = fs::relative(fs::path{ m_server_path + "/" + c->SharedMemDir }).string();
|
||||
}
|
||||
|
||||
// logging path
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->LogDir}.string())) {
|
||||
m_log_path = fs::relative(fs::path{m_server_path + "/" + c->LogDir}).string();
|
||||
}
|
||||
|
||||
LogInfo("[PathManager] logs [{}]", m_log_path);
|
||||
LogInfo("[PathManager] lua mods [{}]", m_lua_mods_path);
|
||||
LogInfo("[PathManager] lua_modules [{}]", m_lua_modules_path);
|
||||
LogInfo("[PathManager] maps [{}]", m_maps_path);
|
||||
LogInfo("[PathManager] patches [{}]", m_patch_path);
|
||||
LogInfo("[PathManager] plugins [{}]", m_plugins_path);
|
||||
LogInfo("[PathManager] quests [{}]", m_quests_path);
|
||||
LogInfo("[PathManager] shared_memory [{}]", m_shared_memory_path);
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetServerPath() const
|
||||
{
|
||||
return m_server_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetMapsPath() const
|
||||
{
|
||||
return m_maps_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetQuestsPath() const
|
||||
{
|
||||
return m_quests_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetPluginsPath() const
|
||||
{
|
||||
return m_plugins_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetSharedMemoryPath() const
|
||||
{
|
||||
return m_shared_memory_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetLogPath() const
|
||||
{
|
||||
return m_log_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetPatchPath() const
|
||||
{
|
||||
return m_patch_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetLuaModulesPath() const
|
||||
{
|
||||
return m_lua_modules_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetLuaModsPath() const
|
||||
{
|
||||
return m_lua_mods_path;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef EQEMU_PATH_MANAGER_H
|
||||
#define EQEMU_PATH_MANAGER_H
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
class PathManager {
|
||||
public:
|
||||
void LoadPaths();
|
||||
|
||||
[[nodiscard]] const std::string &GetLogPath() const;
|
||||
[[nodiscard]] const std::string &GetLuaModsPath() const;
|
||||
[[nodiscard]] const std::string &GetLuaModulesPath() const;
|
||||
[[nodiscard]] const std::string &GetMapsPath() const;
|
||||
[[nodiscard]] const std::string &GetPatchPath() const;
|
||||
[[nodiscard]] const std::string &GetPluginsPath() const;
|
||||
[[nodiscard]] const std::string &GetQuestsPath() const;
|
||||
[[nodiscard]] const std::string &GetServerPath() const;
|
||||
[[nodiscard]] const std::string &GetSharedMemoryPath() const;
|
||||
|
||||
private:
|
||||
std::string m_log_path;
|
||||
std::string m_lua_mods_path;
|
||||
std::string m_lua_modules_path;
|
||||
std::string m_maps_path;
|
||||
std::string m_patch_path;
|
||||
std::string m_plugins_path;
|
||||
std::string m_quests_path;
|
||||
std::string m_server_path;
|
||||
std::string m_shared_memory_path;
|
||||
};
|
||||
|
||||
extern PathManager path;
|
||||
|
||||
#endif //EQEMU_PATH_MANAGER_H
|
||||
@@ -67,6 +67,8 @@ std::string GetPlatformName()
|
||||
return "Launch";
|
||||
case EQEmuExePlatform::ExePlatformHC:
|
||||
return "HC";
|
||||
case EQEmuExePlatform::ExePlatformTests:
|
||||
return "Tests";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
+2
-1
@@ -36,7 +36,8 @@ enum EQEmuExePlatform
|
||||
ExePlatformSharedMemory,
|
||||
ExePlatformClientImport,
|
||||
ExePlatformClientExport,
|
||||
ExePlatformHC
|
||||
ExePlatformHC,
|
||||
ExePlatformTests
|
||||
};
|
||||
|
||||
void RegisterExecutablePlatform(EQEmuExePlatform p);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "rulesys.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "database.h"
|
||||
#include "strings.h"
|
||||
#include <cstdlib>
|
||||
|
||||
@@ -491,6 +491,7 @@ RULE_INT(Combat, FrontalStunImmunityRaces, 512, "Bitmask for Races than have fro
|
||||
RULE_BOOL(Combat, NPCsUseFrontalStunImmunityRaces, true, "Enable or disable NPCs using frontal stun immunity Races from Combat:FrontalStunImmunityRaces, true by default.")
|
||||
RULE_BOOL(Combat, AssassinateOnlyHumanoids, true, "Enable or disable Assassinate only being allowed on Humanoids, true by default.")
|
||||
RULE_BOOL(Combat, HeadshotOnlyHumanoids, true, "Enable or disable Headshot only being allowed on Humanoids, true by default.")
|
||||
RULE_BOOL(Combat, EnableWarriorShielding, true, "Enable or disable Warrior Shielding Ability (/shield), true by default.")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(NPC)
|
||||
@@ -686,6 +687,7 @@ RULE_REAL(AA, ModernAAScalingStartPercent, 1000, "1000% or 10x AA experience at
|
||||
RULE_INT(AA, ModernAAScalingAAMinimum, 0, "The minimum number of earned AA before AA experience scaling begins")
|
||||
RULE_INT(AA, ModernAAScalingAALimit, 4000, "The number of earned AA when AA experience scaling ends")
|
||||
RULE_BOOL(AA, SoundForAAEarned, false, "Play sound when AA point earned")
|
||||
RULE_INT(AA, UnusedAAPointCap, -1, "Cap for Unused AA Points. Default: -1. NOTE: DO NOT LOWER THIS WITHOUT KNOWING WHAT YOU ARE DOING. MAY RESULT IN PLAYERS LOSING AAs.")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Console)
|
||||
|
||||
+10
-8
@@ -41,6 +41,7 @@
|
||||
#include "repositories/criteria/content_filter_criteria.h"
|
||||
#include "repositories/account_repository.h"
|
||||
#include "repositories/faction_association_repository.h"
|
||||
#include "path_manager.h"
|
||||
|
||||
namespace ItemField
|
||||
{
|
||||
@@ -940,7 +941,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
|
||||
const auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("items");
|
||||
mutex.Lock();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("items");
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("items"));
|
||||
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
|
||||
items_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
|
||||
items_hash = std::make_unique<EQ::FixedMemoryHashSet<EQ::ItemData>>(static_cast<uint8*>(items_mmf->Get()), items_mmf->Size());
|
||||
@@ -1436,7 +1437,7 @@ bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) {
|
||||
const auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("faction");
|
||||
mutex.Lock();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("faction");
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("faction"));
|
||||
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
|
||||
faction_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
|
||||
faction_hash = std::make_unique<EQ::FixedMemoryHashSet<NPCFactionList>>(static_cast<uint8*>(faction_mmf->Get()), faction_mmf->Size());
|
||||
@@ -1509,7 +1510,7 @@ bool SharedDatabase::LoadFactionAssociation(const std::string &prefix)
|
||||
auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("factionassociations");
|
||||
mutex.Lock();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("factionassociations");
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("factionassociations"));
|
||||
faction_associations_mmf = std::unique_ptr<EQ::MemoryMappedFile>(new EQ::MemoryMappedFile(file_name));
|
||||
faction_associations_hash = std::unique_ptr<EQ::FixedMemoryHashSet<FactionAssociations>>(
|
||||
new EQ::FixedMemoryHashSet<FactionAssociations>(reinterpret_cast<uint8 *>(faction_associations_mmf->Get()),
|
||||
@@ -1704,7 +1705,7 @@ bool SharedDatabase::LoadSkillCaps(const std::string &prefix) {
|
||||
const auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("skill_caps");
|
||||
mutex.Lock();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("skill_caps");
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("skill_caps"));
|
||||
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
|
||||
skill_caps_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
|
||||
mutex.Unlock();
|
||||
@@ -1863,7 +1864,7 @@ bool SharedDatabase::LoadSpells(const std::string &prefix, int32 *records, const
|
||||
EQ::IPCMutex mutex("spells");
|
||||
mutex.Lock();
|
||||
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("spells");
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("spells"));
|
||||
spells_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
|
||||
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
|
||||
*records = *static_cast<uint32*>(spells_mmf->Get());
|
||||
@@ -2077,7 +2078,7 @@ bool SharedDatabase::LoadBaseData(const std::string &prefix) {
|
||||
EQ::IPCMutex mutex("base_data");
|
||||
mutex.Lock();
|
||||
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("base_data");
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("base_data"));
|
||||
base_data_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
|
||||
mutex.Unlock();
|
||||
} catch(std::exception& ex) {
|
||||
@@ -2398,12 +2399,13 @@ bool SharedDatabase::LoadLoot(const std::string &prefix) {
|
||||
const auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("loot");
|
||||
mutex.Lock();
|
||||
std::string file_name_lt = Config->SharedMemDir + prefix + std::string("loot_table");
|
||||
std::string file_name_lt = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("loot_table"));
|
||||
|
||||
loot_table_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name_lt);
|
||||
loot_table_hash = std::make_unique<EQ::FixedMemoryVariableHashSet<LootTable_Struct>>(
|
||||
static_cast<uint8*>(loot_table_mmf->Get()),
|
||||
loot_table_mmf->Size());
|
||||
std::string file_name_ld = Config->SharedMemDir + prefix + std::string("loot_drop");
|
||||
std::string file_name_ld = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("loot_drop"));
|
||||
loot_drop_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name_ld);
|
||||
loot_drop_hash = std::make_unique<EQ::FixedMemoryVariableHashSet<LootDrop_Struct>>(
|
||||
static_cast<uint8*>(loot_drop_mmf->Get()),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+1
-15
@@ -49,20 +49,6 @@ enum class TaskTimerType
|
||||
Request
|
||||
};
|
||||
|
||||
// live alt currency types, may not match current server alternate currency ids
|
||||
enum class AltCurrencyType
|
||||
{
|
||||
RadiantCrystal = 4,
|
||||
EbonCrystal = 5,
|
||||
MarkOfValor = 31,
|
||||
CommemorativeCoin = 33,
|
||||
PieceOfEight = 37,
|
||||
RemnantOfTranquility = 38,
|
||||
SathirTradeGem = 41,
|
||||
BathezidTradeGem = 43,
|
||||
FroststoneDucat = 48,
|
||||
};
|
||||
|
||||
struct ActivityInformation {
|
||||
int req_activity_id;
|
||||
int step;
|
||||
@@ -216,7 +202,7 @@ struct TaskInformation {
|
||||
int faction_amount{}; // faction hit value
|
||||
TaskMethodType reward_method;
|
||||
int reward_points;
|
||||
AltCurrencyType reward_point_type;
|
||||
int32_t reward_point_type;
|
||||
int activity_count{};
|
||||
uint8_t min_level{};
|
||||
uint8_t max_level{};
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9208
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9212
|
||||
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9029
|
||||
|
||||
+12
-12
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "zone_store.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
#include "stacktrace/backward.hpp"
|
||||
|
||||
ZoneStore::ZoneStore() = default;
|
||||
ZoneStore::~ZoneStore() = default;
|
||||
@@ -81,12 +82,6 @@ const char *ZoneStore::GetZoneName(uint32 zone_id, bool error_unknown)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"[GetZoneName] Failed to get zone name by zone_id [{}] error_unknown [{}]",
|
||||
zone_id,
|
||||
(error_unknown ? "true" : "false")
|
||||
);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -107,12 +102,6 @@ const char *ZoneStore::GetZoneLongName(uint32 zone_id, bool error_unknown)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"[GetZoneLongName] Failed to get zone long name by zone_id [{}] error_unknown [{}]",
|
||||
zone_id,
|
||||
(error_unknown ? "true" : "false")
|
||||
);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -185,6 +174,17 @@ ZoneRepository::Zone *ZoneStore::GetZone(const char *in_zone_name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ZoneRepository::Zone *ZoneStore::GetZone(std::string in_zone_name)
|
||||
{
|
||||
for (auto &z: m_zones) {
|
||||
if (z.short_name == in_zone_name) {
|
||||
return &z;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::vector<ZoneRepository::Zone> &ZoneStore::GetZones() const
|
||||
{
|
||||
return m_zones;
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
|
||||
ZoneRepository::Zone *GetZone(uint32 zone_id, int version = 0);
|
||||
ZoneRepository::Zone *GetZone(const char *in_zone_name);
|
||||
ZoneRepository::Zone *GetZone(std::string in_zone_name);
|
||||
uint32 GetZoneID(const char *in_zone_name);
|
||||
uint32 GetZoneID(std::string zone_name);
|
||||
std::string GetZoneName(uint32 zone_id);
|
||||
|
||||
+20
-8
@@ -21,6 +21,7 @@
|
||||
#include "../common/proc_launcher.h"
|
||||
#include "../common/eqemu_config.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/path_manager.h"
|
||||
#include "../common/platform.h"
|
||||
#include "../common/crash.h"
|
||||
#include "../common/unix.h"
|
||||
@@ -33,6 +34,7 @@
|
||||
#include <time.h>
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
PathManager path;
|
||||
|
||||
bool RunLoops = false;
|
||||
|
||||
@@ -43,6 +45,8 @@ int main(int argc, char *argv[]) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
std::string launcher_name;
|
||||
if(argc == 2) {
|
||||
launcher_name = argv[1];
|
||||
@@ -101,11 +105,17 @@ int main(int argc, char *argv[]) {
|
||||
Log(Logs::Detail, Logs::Launcher, "Starting main loop...");
|
||||
|
||||
ProcLauncher *launch = ProcLauncher::get();
|
||||
|
||||
RunLoops = true;
|
||||
while(RunLoops) {
|
||||
auto loop_fn = [&](EQ::Timer* t) {
|
||||
//Advance the timer to our current point in time
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
if (!RunLoops) {
|
||||
EQ::EventLoop::Get().Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let the process manager look for dead children
|
||||
*/
|
||||
@@ -116,29 +126,31 @@ int main(int argc, char *argv[]) {
|
||||
*/
|
||||
zone = zones.begin();
|
||||
zend = zones.end();
|
||||
for(; zone != zend; ++zone) {
|
||||
if(!zone->second->Process())
|
||||
for (; zone != zend; ++zone) {
|
||||
if (!zone->second->Process())
|
||||
to_remove.insert(zone->first);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kill off any zones which have stopped
|
||||
*/
|
||||
while(!to_remove.empty()) {
|
||||
while (!to_remove.empty()) {
|
||||
std::string rem = *to_remove.begin();
|
||||
to_remove.erase(rem);
|
||||
zone = zones.find(rem);
|
||||
if(zone == zones.end()) {
|
||||
if (zone == zones.end()) {
|
||||
//wtf...
|
||||
continue;
|
||||
}
|
||||
delete zone->second;
|
||||
zones.erase(rem);
|
||||
}
|
||||
};
|
||||
|
||||
EQ::EventLoop::Get().Process();
|
||||
Sleep(5);
|
||||
}
|
||||
EQ::Timer process_timer(loop_fn);
|
||||
process_timer.Start(32, true);
|
||||
|
||||
EQ::EventLoop::Get().Run();
|
||||
|
||||
//try to be semi-nice about this... without waiting too long
|
||||
zone = zones.begin();
|
||||
|
||||
+34
-54
@@ -26,13 +26,13 @@ bool Client::Process()
|
||||
{
|
||||
EQApplicationPacket *app = m_connection->PopPacket();
|
||||
while (app) {
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("Application packet received from client (size {0})", app->Size());
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(app);
|
||||
}
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
m_connection->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
|
||||
if (m_client_status == cs_failed_to_login) {
|
||||
delete app;
|
||||
@@ -42,9 +42,7 @@ bool Client::Process()
|
||||
|
||||
switch (app->GetOpcode()) {
|
||||
case OP_SessionReady: {
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogInfo("Session ready received from client");
|
||||
}
|
||||
LogInfo("Session ready received from client account {}", GetClientDescription());
|
||||
Handle_SessionReady((const char *) app->pBuffer, app->Size());
|
||||
break;
|
||||
}
|
||||
@@ -54,9 +52,7 @@ bool Client::Process()
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogInfo("Login received from client");
|
||||
}
|
||||
LogInfo("Login received from client {}", GetClientDescription());
|
||||
|
||||
Handle_Login((const char *) app->pBuffer, app->Size());
|
||||
break;
|
||||
@@ -67,9 +63,7 @@ bool Client::Process()
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("Server list request received from client");
|
||||
}
|
||||
LogInfo("Server list request received from client {}", GetClientDescription());
|
||||
|
||||
SendServerListPacket(*(uint32_t *) app->pBuffer);
|
||||
break;
|
||||
@@ -83,13 +77,6 @@ bool Client::Process()
|
||||
Handle_Play((const char *) app->pBuffer);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (LogSys.log_settings[Logs::PacketClientServerUnhandled].is_category_enabled == 1) {
|
||||
char dump[64];
|
||||
app->build_header_dump(dump);
|
||||
LogError("Recieved unhandled application packet from the client: [{}]", dump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete app;
|
||||
@@ -128,10 +115,6 @@ void Client::Handle_SessionReady(const char *data, unsigned int size)
|
||||
buf->base_reply.success = true;
|
||||
buf->base_reply.error_str_id = 0x65; // 101 "No Error"
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp);
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(outapp);
|
||||
delete outapp;
|
||||
}
|
||||
@@ -290,14 +273,12 @@ void Client::Handle_Play(const char *data)
|
||||
auto server_id_in = (unsigned int) play->server_number;
|
||||
auto sequence_in = (unsigned int) play->base_header.sequence;
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogInfo(
|
||||
"Play received from client [{0}] server number {1} sequence {2}",
|
||||
GetAccountName(),
|
||||
server_id_in,
|
||||
sequence_in
|
||||
);
|
||||
}
|
||||
LogInfo(
|
||||
"[Handle_Play] Play received from client [{}] server number [{}] sequence [{}]",
|
||||
GetAccountName(),
|
||||
server_id_in,
|
||||
sequence_in
|
||||
);
|
||||
|
||||
m_play_server_id = (unsigned int) play->server_number;
|
||||
m_play_sequence_id = sequence_in;
|
||||
@@ -310,21 +291,14 @@ void Client::Handle_Play(const char *data)
|
||||
*/
|
||||
void Client::SendServerListPacket(uint32 seq)
|
||||
{
|
||||
auto outapp = server.server_manager->CreateServerListPacket(this, seq);
|
||||
auto app = server.server_manager->CreateServerListPacket(this, seq);
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp.get());
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(outapp.get());
|
||||
m_connection->QueuePacket(app.get());
|
||||
}
|
||||
|
||||
void Client::SendPlayResponse(EQApplicationPacket *outapp)
|
||||
{
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("Sending play response for {0}", GetAccountName());
|
||||
// server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size);
|
||||
}
|
||||
LogInfo("Sending play response for {}", GetClientDescription());
|
||||
m_connection->QueuePacket(outapp);
|
||||
}
|
||||
|
||||
@@ -422,10 +396,6 @@ void Client::DoFailedLogin()
|
||||
outapp.WriteData(&base_header, sizeof(base_header));
|
||||
outapp.WriteData(&encrypted_buffer, sizeof(encrypted_buffer));
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(&outapp);
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(&outapp);
|
||||
m_client_status = cs_failed_to_login;
|
||||
}
|
||||
@@ -576,10 +546,6 @@ void Client::DoSuccessfulLogin(
|
||||
outapp->WriteData(&base_header, sizeof(base_header));
|
||||
outapp->WriteData(&encrypted_buffer, sizeof(encrypted_buffer));
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp.get());
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(outapp.get());
|
||||
|
||||
m_client_status = cs_logged_in;
|
||||
@@ -596,7 +562,7 @@ void Client::SendExpansionPacketData(PlayerLoginReply_Struct& plrs)
|
||||
|
||||
|
||||
if (server.options.IsDisplayExpansions()) {
|
||||
|
||||
|
||||
int32_t expansion = server.options.GetMaxExpansions();
|
||||
int32_t owned_expansion = (expansion << 1) | 1;
|
||||
|
||||
@@ -839,3 +805,17 @@ bool Client::ProcessHealthCheck(std::string username)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Client::GetClientDescription()
|
||||
{
|
||||
in_addr in{};
|
||||
in.s_addr = GetConnection()->GetRemoteIP();
|
||||
std::string client_ip = inet_ntoa(in);
|
||||
|
||||
return fmt::format(
|
||||
"account_name [{}] account_id ({}) ip_address [{}]",
|
||||
GetAccountName(),
|
||||
GetAccountID(),
|
||||
client_ip
|
||||
);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
* @param size
|
||||
*/
|
||||
void Handle_Login(const char *data, unsigned int size);
|
||||
|
||||
|
||||
/**
|
||||
* Sends the expansion data packet
|
||||
*
|
||||
@@ -111,6 +111,12 @@ public:
|
||||
*/
|
||||
std::string GetAccountName() const { return m_account_name; }
|
||||
|
||||
/**
|
||||
* Returns a description for the client for logging
|
||||
* @return std::string
|
||||
*/
|
||||
std::string GetClientDescription();
|
||||
|
||||
/**
|
||||
* Gets the key generated at login for this client
|
||||
*
|
||||
|
||||
@@ -6,6 +6,7 @@ extern bool run_server;
|
||||
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/misc.h"
|
||||
#include "../common/path_manager.h"
|
||||
|
||||
ClientManager::ClientManager()
|
||||
{
|
||||
@@ -15,13 +16,18 @@ ClientManager::ClientManager()
|
||||
|
||||
titanium_stream = new EQ::Net::EQStreamManager(titanium_opts);
|
||||
titanium_ops = new RegularOpcodeManager;
|
||||
if (!titanium_ops->LoadOpcodes(
|
||||
|
||||
std::string opcodes_path = fmt::format(
|
||||
"{}/{}",
|
||||
path.GetServerPath(),
|
||||
server.config.GetVariableString(
|
||||
"client_configuration",
|
||||
"titanium_opcodes",
|
||||
"login_opcodes.conf"
|
||||
).c_str())) {
|
||||
)
|
||||
);
|
||||
|
||||
if (!titanium_ops->LoadOpcodes(opcodes_path.c_str())) {
|
||||
LogError(
|
||||
"ClientManager fatal error: couldn't load opcodes for Titanium file [{0}]",
|
||||
server.config.GetVariableString("client_configuration", "titanium_opcodes", "login_opcodes.conf")
|
||||
@@ -49,14 +55,18 @@ ClientManager::ClientManager()
|
||||
EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false);
|
||||
sod_stream = new EQ::Net::EQStreamManager(sod_opts);
|
||||
sod_ops = new RegularOpcodeManager;
|
||||
if (
|
||||
!sod_ops->LoadOpcodes(
|
||||
server.config.GetVariableString(
|
||||
"client_configuration",
|
||||
"sod_opcodes",
|
||||
"login_opcodes.conf"
|
||||
).c_str()
|
||||
)) {
|
||||
|
||||
opcodes_path = fmt::format(
|
||||
"{}/{}",
|
||||
path.GetServerPath(),
|
||||
server.config.GetVariableString(
|
||||
"client_configuration",
|
||||
"sod_opcodes",
|
||||
"login_opcodes.conf"
|
||||
)
|
||||
);
|
||||
|
||||
if (!sod_ops->LoadOpcodes(opcodes_path.c_str())) {
|
||||
LogError(
|
||||
"ClientManager fatal error: couldn't load opcodes for SoD file {0}",
|
||||
server.config.GetVariableString("client_configuration", "sod_opcodes", "login_opcodes.conf").c_str()
|
||||
|
||||
+35
-23
@@ -11,6 +11,7 @@
|
||||
#include "loginserver_webserver.h"
|
||||
#include "loginserver_command_handler.h"
|
||||
#include "../common/strings.h"
|
||||
#include "../common/path_manager.h"
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
@@ -20,6 +21,7 @@
|
||||
LoginServer server;
|
||||
EQEmuLogSys LogSys;
|
||||
bool run_server = true;
|
||||
PathManager path;
|
||||
|
||||
void ResolveAddresses();
|
||||
void CatchSignal(int sig_num)
|
||||
@@ -42,18 +44,11 @@ void LoadDatabaseConnection()
|
||||
|
||||
void LoadServerConfig()
|
||||
{
|
||||
server.config = EQ::JsonConfigFile::Load("login.json");
|
||||
server.config = EQ::JsonConfigFile::Load(
|
||||
fmt::format("{}/login.json", path.GetServerPath())
|
||||
);
|
||||
LogInfo("Config System Init");
|
||||
|
||||
|
||||
/**
|
||||
* Logging
|
||||
*/
|
||||
server.options.Trace(server.config.GetVariableBool("logging", "trace", false));
|
||||
server.options.WorldTrace(server.config.GetVariableBool("logging", "world_trace", false));
|
||||
server.options.DumpInPackets(server.config.GetVariableBool("logging", "dump_packets_in", false));
|
||||
server.options.DumpOutPackets(server.config.GetVariableBool("logging", "dump_packets_out", false));
|
||||
|
||||
/**
|
||||
* Worldservers
|
||||
*/
|
||||
@@ -63,7 +58,7 @@ void LoadServerConfig()
|
||||
"reject_duplicate_servers",
|
||||
false
|
||||
)
|
||||
);
|
||||
);
|
||||
server.options.SetShowPlayerCount(server.config.GetVariableBool("worldservers", "show_player_count", false));
|
||||
server.options.AllowUnregistered(
|
||||
server.config.GetVariableBool(
|
||||
@@ -90,8 +85,18 @@ void LoadServerConfig()
|
||||
/**
|
||||
* Expansion Display Settings
|
||||
*/
|
||||
server.options.DisplayExpansions(server.config.GetVariableBool("client_configuration", "display_expansions", false)); //disable by default
|
||||
server.options.MaxExpansions(server.config.GetVariableInt("client_configuration", "max_expansions_mask", 67108863)); //enable display of all expansions
|
||||
server.options.DisplayExpansions(
|
||||
server.config.GetVariableBool(
|
||||
"client_configuration",
|
||||
"display_expansions",
|
||||
false
|
||||
)); //disable by default
|
||||
server.options.MaxExpansions(
|
||||
server.config.GetVariableInt(
|
||||
"client_configuration",
|
||||
"max_expansions_mask",
|
||||
67108863
|
||||
)); //enable display of all expansions
|
||||
|
||||
/**
|
||||
* Account
|
||||
@@ -171,6 +176,8 @@ int main(int argc, char **argv)
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
}
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
/**
|
||||
* Command handler
|
||||
*/
|
||||
@@ -181,7 +188,7 @@ int main(int argc, char **argv)
|
||||
LoadDatabaseConnection();
|
||||
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
LogSys.log_settings[Logs::Debug].log_to_console = static_cast<uint8>(Logs::General);
|
||||
LogSys.log_settings[Logs::Debug].log_to_console = static_cast<uint8>(Logs::General);
|
||||
LogSys.log_settings[Logs::Debug].is_category_enabled = 1;
|
||||
|
||||
LoginserverCommandHandler::CommandHandler(argc, argv);
|
||||
@@ -196,6 +203,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (argc == 1) {
|
||||
LogSys.SetDatabase(server.db)
|
||||
->SetLogPath("logs")
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
}
|
||||
@@ -258,10 +266,6 @@ int main(int argc, char **argv)
|
||||
web_api_thread.detach();
|
||||
}
|
||||
|
||||
LogInfo("[Config] [Logging] IsTraceOn [{0}]", server.options.IsTraceOn());
|
||||
LogInfo("[Config] [Logging] IsWorldTraceOn [{0}]", server.options.IsWorldTraceOn());
|
||||
LogInfo("[Config] [Logging] IsDumpInPacketsOn [{0}]", server.options.IsDumpInPacketsOn());
|
||||
LogInfo("[Config] [Logging] IsDumpOutPacketsOn [{0}]", server.options.IsDumpOutPacketsOn());
|
||||
LogInfo("[Config] [Account] CanAutoCreateAccounts [{0}]", server.options.CanAutoCreateAccounts());
|
||||
LogInfo("[Config] [Client_Configuration] DisplayExpansions [{0}]", server.options.IsDisplayExpansions());
|
||||
LogInfo("[Config] [Client_Configuration] MaxExpansions [{0}]", server.options.GetMaxExpansions());
|
||||
@@ -285,13 +289,21 @@ int main(int argc, char **argv)
|
||||
LogInfo("[Config] [Security] IsPasswordLoginAllowed [{0}]", server.options.IsPasswordLoginAllowed());
|
||||
LogInfo("[Config] [Security] IsUpdatingInsecurePasswords [{0}]", server.options.IsUpdatingInsecurePasswords());
|
||||
|
||||
while (run_server) {
|
||||
auto loop_fn = [&](EQ::Timer* t) {
|
||||
Timer::SetCurrentTime();
|
||||
server.client_manager->Process();
|
||||
EQ::EventLoop::Get().Process();
|
||||
|
||||
Sleep(5);
|
||||
}
|
||||
if (!run_server) {
|
||||
EQ::EventLoop::Get().Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
server.client_manager->Process();
|
||||
};
|
||||
|
||||
EQ::Timer process_timer(loop_fn);
|
||||
process_timer.Start(32, true);
|
||||
|
||||
EQ::EventLoop::Get().Run();
|
||||
|
||||
LogInfo("Server Shutdown");
|
||||
|
||||
|
||||
@@ -13,9 +13,6 @@ public:
|
||||
*/
|
||||
Options() :
|
||||
allow_unregistered(true),
|
||||
trace(false),
|
||||
dump_in_packets(false),
|
||||
dump_out_packets(false),
|
||||
display_expansions(false),
|
||||
max_expansions_mask(0),
|
||||
encryption_mode(5),
|
||||
@@ -42,46 +39,6 @@ public:
|
||||
*/
|
||||
inline bool IsUnregisteredAllowed() const { return allow_unregistered; }
|
||||
|
||||
/**
|
||||
* Sets trace.
|
||||
*/
|
||||
inline void Trace(bool b) { trace = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of trace.
|
||||
*/
|
||||
inline bool IsTraceOn() const { return trace; }
|
||||
|
||||
/**
|
||||
* Sets trace.
|
||||
*/
|
||||
inline void WorldTrace(bool b) { world_trace = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of trace.
|
||||
*/
|
||||
inline bool IsWorldTraceOn() const { return world_trace; }
|
||||
|
||||
/**
|
||||
* Sets dump_in_packets.
|
||||
*/
|
||||
inline void DumpInPackets(bool b) { dump_in_packets = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of dump_in_packets.
|
||||
*/
|
||||
inline bool IsDumpInPacketsOn() const { return dump_in_packets; }
|
||||
|
||||
/**
|
||||
* Sets dump_out_packets.
|
||||
*/
|
||||
inline void DumpOutPackets(bool b) { dump_out_packets = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of dump_out_packets.
|
||||
*/
|
||||
inline bool IsDumpOutPacketsOn() const { return dump_out_packets; }
|
||||
|
||||
/**
|
||||
* Sets encryption_mode.
|
||||
*/
|
||||
@@ -148,10 +105,6 @@ public:
|
||||
|
||||
private:
|
||||
bool allow_unregistered;
|
||||
bool trace;
|
||||
bool world_trace;
|
||||
bool dump_in_packets;
|
||||
bool dump_out_packets;
|
||||
bool display_expansions;
|
||||
bool reject_duplicate_servers;
|
||||
bool world_dev_test_servers_list_bottom;
|
||||
|
||||
@@ -180,21 +180,23 @@ void ServerManager::SendUserToWorldRequest(
|
||||
EQ::Net::DynamicPacket outapp;
|
||||
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
|
||||
|
||||
auto *user_to_world_request = (UsertoWorldRequest_Struct *) outapp.Data();
|
||||
user_to_world_request->worldid = server_id;
|
||||
user_to_world_request->lsaccountid = client_account_id;
|
||||
strncpy(user_to_world_request->login, &client_loginserver[0], 64);
|
||||
auto *r = (UsertoWorldRequest_Struct *) outapp.Data();
|
||||
r->worldid = server_id;
|
||||
r->lsaccountid = client_account_id;
|
||||
strncpy(r->login, &client_loginserver[0], 64);
|
||||
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
|
||||
found = true;
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
LogInfo("{0}", outapp.ToString());
|
||||
}
|
||||
LogNetcode(
|
||||
"[UsertoWorldRequest] [Size: {}]\n{}",
|
||||
outapp.Length(),
|
||||
outapp.ToString()
|
||||
);
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (!found && server.options.IsTraceOn()) {
|
||||
if (!found) {
|
||||
LogError("Client requested a user to world but supplied an invalid id of {0}", server_id);
|
||||
}
|
||||
}
|
||||
|
||||
+98
-154
@@ -79,17 +79,12 @@ void WorldServer::Reset()
|
||||
*/
|
||||
void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: [{0}], (size {1})",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessNewLSInfo] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(ServerNewLSInfo_Struct)) {
|
||||
LogError(
|
||||
@@ -129,18 +124,13 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packe
|
||||
*/
|
||||
void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
Log(
|
||||
Logs::Detail,
|
||||
Logs::Netcode,
|
||||
"Application packet received from server: 0x%.4X, (size %u)",
|
||||
LogNetcode(
|
||||
"[ProcessLSStatus] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length()
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
|
||||
if (packet.Length() < sizeof(ServerLSStatus_Struct)) {
|
||||
LogError(
|
||||
"Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun"
|
||||
@@ -151,15 +141,13 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet
|
||||
|
||||
auto *ls_status = (ServerLSStatus_Struct *) packet.Data();
|
||||
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]",
|
||||
GetServerLongName(),
|
||||
ls_status->status,
|
||||
ls_status->num_players,
|
||||
ls_status->num_zones
|
||||
);
|
||||
}
|
||||
LogDebug(
|
||||
"World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]",
|
||||
GetServerLongName(),
|
||||
ls_status->status,
|
||||
ls_status->num_players,
|
||||
ls_status->num_zones
|
||||
);
|
||||
|
||||
Handle_LSStatus(ls_status);
|
||||
}
|
||||
@@ -170,17 +158,12 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet
|
||||
*/
|
||||
void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: [{0}], (size {1})",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessUserToWorldResponseLegacy] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) {
|
||||
LogError(
|
||||
@@ -191,19 +174,11 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
return;
|
||||
}
|
||||
|
||||
//I don't use world trace for this and here is why:
|
||||
//Because this is a part of the client login procedure it makes tracking client errors
|
||||
//While keeping world server spam with multiple servers connected almost impossible.
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("User-To-World Response received");
|
||||
}
|
||||
|
||||
auto *r = (UsertoWorldResponseLegacy_Struct *) packet.Data();
|
||||
|
||||
LogDebug("Trying to find client with user id of [{0}]", r->lsaccountid);
|
||||
Client *client = server.client_manager->GetClient(r->lsaccountid, "eqemu");
|
||||
if (client) {
|
||||
|
||||
LogDebug(
|
||||
"Found client with user id of [{0}] and account name of [{1}]",
|
||||
r->lsaccountid,
|
||||
@@ -254,21 +229,13 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Sending play response: allowed [{0}] sequence [{1}] server number [{2}] message [{3}]",
|
||||
per->base_reply.success,
|
||||
per->base_header.sequence,
|
||||
per->server_number,
|
||||
per->base_reply.error_str_id
|
||||
);
|
||||
|
||||
LogDebug("[Size: [{0}]] {1}", outapp->size, DumpPacketToString(outapp));
|
||||
}
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp);
|
||||
}
|
||||
LogDebug(
|
||||
"Sending play response: allowed [{0}] sequence [{1}] server number [{2}] message [{3}]",
|
||||
per->base_reply.success,
|
||||
per->base_header.sequence,
|
||||
per->server_number,
|
||||
per->base_reply.error_str_id
|
||||
);
|
||||
|
||||
client->SendPlayResponse(outapp);
|
||||
delete outapp;
|
||||
@@ -287,17 +254,12 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
*/
|
||||
void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: 0x%.4X, (size %u)",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessUserToWorldResponse] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(UsertoWorldResponse_Struct)) {
|
||||
LogError(
|
||||
@@ -308,25 +270,18 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
|
||||
return;
|
||||
}
|
||||
|
||||
//I don't use world trace for this and here is why:
|
||||
//Because this is a part of the client login procedure it makes tracking client errors
|
||||
//While keeping world server spam with multiple servers connected almost impossible.
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("User-To-World Response received");
|
||||
}
|
||||
|
||||
auto user_to_world_response = (UsertoWorldResponse_Struct *) packet.Data();
|
||||
LogDebug("Trying to find client with user id of [{0}]", user_to_world_response->lsaccountid);
|
||||
|
||||
Client *client = server.client_manager->GetClient(
|
||||
Client *c = server.client_manager->GetClient(
|
||||
user_to_world_response->lsaccountid,
|
||||
user_to_world_response->login
|
||||
);
|
||||
|
||||
if (client) {
|
||||
if (c) {
|
||||
LogDebug("Found client with user id of [{0}] and account name of {1}",
|
||||
user_to_world_response->lsaccountid,
|
||||
client->GetAccountName().c_str()
|
||||
c->GetAccountName().c_str()
|
||||
);
|
||||
|
||||
auto *outapp = new EQApplicationPacket(
|
||||
@@ -334,69 +289,62 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
|
||||
sizeof(PlayEverquestResponse_Struct)
|
||||
);
|
||||
|
||||
auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
|
||||
per->base_header.sequence = client->GetPlaySequence();
|
||||
per->server_number = client->GetPlayServerID();
|
||||
auto *r = (PlayEverquestResponse_Struct *) outapp->pBuffer;
|
||||
r->base_header.sequence = c->GetPlaySequence();
|
||||
r->server_number = c->GetPlayServerID();
|
||||
|
||||
LogDebug(
|
||||
"Found sequence and play of [{0}] [{1}]",
|
||||
client->GetPlaySequence(),
|
||||
client->GetPlayServerID()
|
||||
c->GetPlaySequence(),
|
||||
c->GetPlayServerID()
|
||||
);
|
||||
|
||||
LogDebug("[Size: [{0}]] {1}", outapp->size, DumpPacketToString(outapp));
|
||||
|
||||
if (user_to_world_response->response > 0) {
|
||||
per->base_reply.success = true;
|
||||
r->base_reply.success = true;
|
||||
SendClientAuth(
|
||||
client->GetConnection()->GetRemoteAddr(),
|
||||
client->GetAccountName(),
|
||||
client->GetKey(),
|
||||
client->GetAccountID(),
|
||||
client->GetLoginServerName()
|
||||
c->GetConnection()->GetRemoteAddr(),
|
||||
c->GetAccountName(),
|
||||
c->GetKey(),
|
||||
c->GetAccountID(),
|
||||
c->GetLoginServerName()
|
||||
);
|
||||
}
|
||||
|
||||
switch (user_to_world_response->response) {
|
||||
case UserToWorldStatusSuccess:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_NONE;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_NONE;
|
||||
break;
|
||||
case UserToWorldStatusWorldUnavail:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_SERVER_UNAVAILABLE;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_SERVER_UNAVAILABLE;
|
||||
break;
|
||||
case UserToWorldStatusSuspended:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_SUSPENDED;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_SUSPENDED;
|
||||
break;
|
||||
case UserToWorldStatusBanned:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_BANNED;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_BANNED;
|
||||
break;
|
||||
case UserToWorldStatusWorldAtCapacity:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_WORLD_MAX_CAPACITY;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_WORLD_MAX_CAPACITY;
|
||||
break;
|
||||
case UserToWorldStatusAlreadyOnline:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_ACTIVE_CHARACTER;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_ACTIVE_CHARACTER;
|
||||
break;
|
||||
default:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_UNKNOWN;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug(
|
||||
"Sending play response with following data, allowed [{0}], sequence {1}, server number {2}, message {3}",
|
||||
per->base_reply.success,
|
||||
per->base_header.sequence,
|
||||
per->server_number,
|
||||
per->base_reply.error_str_id
|
||||
);
|
||||
LogDebug("[Size: [{0}]] {1}", outapp->size, DumpPacketToString(outapp));
|
||||
}
|
||||
LogDebug(
|
||||
"Sending play response with following data, allowed [{0}], sequence {1}, server number {2}, message {3}",
|
||||
r->base_reply.success,
|
||||
r->base_header.sequence,
|
||||
r->server_number,
|
||||
r->base_reply.error_str_id
|
||||
);
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp);
|
||||
}
|
||||
|
||||
client->SendPlayResponse(outapp);
|
||||
c->SendPlayResponse(outapp);
|
||||
delete outapp;
|
||||
}
|
||||
else {
|
||||
@@ -413,17 +361,12 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
|
||||
*/
|
||||
void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: [{0}], (size {1})",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessLSAccountUpdate] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) {
|
||||
LogError(
|
||||
@@ -434,9 +377,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
|
||||
return;
|
||||
}
|
||||
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug("ServerOP_LSAccountUpdate packet received from [{0}]", m_short_name);
|
||||
}
|
||||
LogDebug("ServerOP_LSAccountUpdate packet received from [{0}]", m_short_name);
|
||||
|
||||
auto *loginserver_update = (ServerLSAccountUpdate_Struct *) packet.Data();
|
||||
if (IsServerTrusted()) {
|
||||
@@ -607,34 +548,34 @@ void WorldServer::SendClientAuth(
|
||||
)
|
||||
{
|
||||
EQ::Net::DynamicPacket outapp;
|
||||
ClientAuth_Struct client_auth{};
|
||||
ClientAuth_Struct a{};
|
||||
|
||||
client_auth.loginserver_account_id = account_id;
|
||||
a.loginserver_account_id = account_id;
|
||||
|
||||
strncpy(client_auth.account_name, account.c_str(), 30);
|
||||
strncpy(client_auth.key, key.c_str(), 30);
|
||||
strncpy(a.account_name, account.c_str(), 30);
|
||||
strncpy(a.key, key.c_str(), 30);
|
||||
|
||||
client_auth.lsadmin = 0;
|
||||
client_auth.is_world_admin = 0;
|
||||
client_auth.ip = inet_addr(ip.c_str());
|
||||
strncpy(client_auth.loginserver_name, &loginserver_name[0], 64);
|
||||
a.lsadmin = 0;
|
||||
a.is_world_admin = 0;
|
||||
a.ip = inet_addr(ip.c_str());
|
||||
strncpy(a.loginserver_name, &loginserver_name[0], 64);
|
||||
|
||||
const std::string &client_address(ip);
|
||||
std::string world_address(m_connection->Handle()->RemoteIP());
|
||||
|
||||
if (client_address == world_address) {
|
||||
client_auth.is_client_from_local_network = 1;
|
||||
a.is_client_from_local_network = 1;
|
||||
}
|
||||
else if (IpUtil::IsIpInPrivateRfc1918(client_address)) {
|
||||
LogInfo("Client is authenticating from a local address [{0}]", client_address);
|
||||
client_auth.is_client_from_local_network = 1;
|
||||
a.is_client_from_local_network = 1;
|
||||
}
|
||||
else {
|
||||
client_auth.is_client_from_local_network = 0;
|
||||
a.is_client_from_local_network = 0;
|
||||
}
|
||||
|
||||
struct in_addr ip_addr{};
|
||||
ip_addr.s_addr = client_auth.ip;
|
||||
ip_addr.s_addr = a.ip;
|
||||
|
||||
LogInfo(
|
||||
"Client authentication response: world_address [{0}] client_address [{1}]",
|
||||
@@ -645,22 +586,25 @@ void WorldServer::SendClientAuth(
|
||||
LogInfo(
|
||||
"Sending Client Authentication Response ls_account_id [{0}] ls_name [{1}] name [{2}] key [{3}] ls_admin [{4}] "
|
||||
"world_admin [{5}] ip [{6}] local [{7}]",
|
||||
client_auth.loginserver_account_id,
|
||||
client_auth.loginserver_name,
|
||||
client_auth.account_name,
|
||||
client_auth.key,
|
||||
client_auth.lsadmin,
|
||||
client_auth.is_world_admin,
|
||||
a.loginserver_account_id,
|
||||
a.loginserver_name,
|
||||
a.account_name,
|
||||
a.key,
|
||||
a.lsadmin,
|
||||
a.is_world_admin,
|
||||
inet_ntoa(ip_addr),
|
||||
client_auth.is_client_from_local_network
|
||||
a.is_client_from_local_network
|
||||
);
|
||||
|
||||
outapp.PutSerialize(0, client_auth);
|
||||
outapp.PutSerialize(0, a);
|
||||
m_connection->Send(ServerOP_LSClientAuth, outapp);
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(ServerOP_LSClientAuth, outapp);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ServerOP_LSClientAuth] Sending [{:#04x}] [Size: {}]\n{}",
|
||||
ServerOP_LSClientAuth,
|
||||
outapp.Length(),
|
||||
outapp.ToString()
|
||||
);
|
||||
}
|
||||
|
||||
constexpr static int MAX_ACCOUNT_NAME_LENGTH = 30;
|
||||
|
||||
+18
-4
@@ -31,6 +31,7 @@
|
||||
#include "queryservconfig.h"
|
||||
#include "lfguild.h"
|
||||
#include "worldserver.h"
|
||||
#include "../common/path_manager.h"
|
||||
#include <list>
|
||||
#include <signal.h>
|
||||
#include <thread>
|
||||
@@ -43,6 +44,7 @@ std::string WorldShortName;
|
||||
const queryservconfig *Config;
|
||||
WorldServer *worldserver = 0;
|
||||
EQEmuLogSys LogSys;
|
||||
PathManager path;
|
||||
|
||||
void CatchSignal(int sig_num)
|
||||
{
|
||||
@@ -56,6 +58,8 @@ int main()
|
||||
set_exception_handler();
|
||||
Timer LFGuildExpireTimer(60000);
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
LogInfo("Starting EQEmu QueryServ");
|
||||
if (!queryservconfig::LoadConfig()) {
|
||||
LogInfo("Loading server configuration failed");
|
||||
@@ -80,6 +84,7 @@ int main()
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
@@ -99,15 +104,24 @@ int main()
|
||||
/* Load Looking For Guild Manager */
|
||||
lfguildmanager.LoadDatabase();
|
||||
|
||||
while (RunLoops) {
|
||||
auto loop_fn = [&](EQ::Timer* t) {
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
if (!RunLoops) {
|
||||
EQ::EventLoop::Get().Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
if (LFGuildExpireTimer.Check()) {
|
||||
lfguildmanager.ExpireEntries();
|
||||
}
|
||||
};
|
||||
|
||||
EQ::Timer process_timer(loop_fn);
|
||||
process_timer.Start(32, true);
|
||||
|
||||
EQ::EventLoop::Get().Run();
|
||||
|
||||
EQ::EventLoop::Get().Process();
|
||||
Sleep(5);
|
||||
}
|
||||
LogSys.CloseFileLogs();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ public:
|
||||
}
|
||||
|
||||
// Load the config
|
||||
static bool LoadConfig() {
|
||||
static bool LoadConfig(const std::string& path = "") {
|
||||
if (_chat_config != nullptr)
|
||||
delete _chat_config;
|
||||
_chat_config=new queryservconfig;
|
||||
_config=_chat_config;
|
||||
|
||||
return _config->parseFile();
|
||||
return _config->parseFile(path);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -36,10 +36,12 @@
|
||||
#include "base_data.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
#include "../common/zone_store.h"
|
||||
#include "../common/path_manager.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <direct.h>
|
||||
@@ -83,6 +85,8 @@ int main(int argc, char **argv)
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
LogInfo("Shared Memory Loader Program");
|
||||
if (!EQEmuConfig::LoadConfig()) {
|
||||
LogError("Unable to load configuration file");
|
||||
@@ -124,6 +128,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ SET(tests_headers
|
||||
|
||||
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
||||
|
||||
TARGET_LINK_LIBRARIES(tests common cppunit fmt)
|
||||
TARGET_LINK_LIBRARIES(tests common cppunit fmt ${SERVER_LIBS})
|
||||
|
||||
INSTALL(TARGETS tests RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
|
||||
|
||||
+14
-6
@@ -20,6 +20,8 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "../common/platform.h"
|
||||
#include "../common/path_manager.h"
|
||||
#include "memory_mapped_file_test.h"
|
||||
#include "ipc_mutex_test.h"
|
||||
#include "fixed_memory_test.h"
|
||||
@@ -30,17 +32,23 @@
|
||||
#include "data_verification_test.h"
|
||||
#include "skills_util_test.h"
|
||||
#include "task_state_test.h"
|
||||
#include "../common/eqemu_config.h"
|
||||
|
||||
const EQEmuConfig *Config;
|
||||
EQEmuLogSys LogSys;
|
||||
PathManager path;
|
||||
|
||||
int main()
|
||||
{
|
||||
RegisterExecutablePlatform(ExePlatformClientImport);
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
path.LoadPaths();
|
||||
|
||||
int main() {
|
||||
auto ConfigLoadResult = EQEmuConfig::LoadConfig();
|
||||
Config = EQEmuConfig::get();
|
||||
Config = EQEmuConfig::get();
|
||||
try {
|
||||
std::ofstream outfile("test_output.txt");
|
||||
std::ofstream outfile("test_output.txt");
|
||||
std::unique_ptr<Test::Output> output(new Test::TextOutput(Test::TextOutput::Verbose, outfile));
|
||||
Test::Suite tests;
|
||||
Test::Suite tests;
|
||||
tests.add(new MemoryMappedFileTest());
|
||||
tests.add(new IPCMutexTest());
|
||||
tests.add(new FixedMemoryHashTest());
|
||||
@@ -52,7 +60,7 @@ int main() {
|
||||
tests.add(new SkillsUtilsTest());
|
||||
tests.add(new TaskStateTest());
|
||||
tests.run(*output, true);
|
||||
} catch(...) {
|
||||
} catch (...) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
+14
-2
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "clientlist.h"
|
||||
#include "database.h"
|
||||
#include "chatchannel.h"
|
||||
#include "../common/path_manager.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
@@ -478,8 +479,11 @@ Clientlist::Clientlist(int ChatPort) {
|
||||
|
||||
const ucsconfig *Config = ucsconfig::get();
|
||||
|
||||
LogInfo("Loading [{}]", Config->MailOpCodesFile.c_str());
|
||||
if (!ChatOpMgr->LoadOpcodes(Config->MailOpCodesFile.c_str()))
|
||||
|
||||
std::string opcodes_file = fmt::format("{}/{}", path.GetServerPath(), Config->MailOpCodesFile);
|
||||
|
||||
LogInfo("Loading [{}]", opcodes_file);
|
||||
if (!ChatOpMgr->LoadOpcodes(opcodes_file.c_str()))
|
||||
exit(1);
|
||||
|
||||
chatsf->OnNewConnection([this](std::shared_ptr<EQ::Net::EQStream> stream) {
|
||||
@@ -615,6 +619,14 @@ void Clientlist::Process()
|
||||
while (KeyValid && !(*it)->GetForceDisconnect() && (app = (*it)->ClientStream->PopPacket())) {
|
||||
EmuOpcode opcode = app->GetOpcode();
|
||||
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
(*it)->ClientStream->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
|
||||
switch (opcode) {
|
||||
case OP_MailLogin: {
|
||||
char *PacketBuffer = (char *)app->pBuffer + 1;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "../common/net/tcp_server.h"
|
||||
#include "../common/net/servertalk_client_connection.h"
|
||||
#include "../common/discord_manager.h"
|
||||
#include "../common/path_manager.h"
|
||||
|
||||
ChatChannelList *ChannelList;
|
||||
Clientlist *g_Clientlist;
|
||||
@@ -45,6 +46,7 @@ EQEmuLogSys LogSys;
|
||||
Database database;
|
||||
WorldServer *worldserver = nullptr;
|
||||
DiscordManager discord_manager;
|
||||
PathManager path;
|
||||
|
||||
const ucsconfig *Config;
|
||||
|
||||
@@ -101,6 +103,8 @@ int main() {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
// Check every minute for unused channels we can delete
|
||||
//
|
||||
Timer ChannelListProcessTimer(60000);
|
||||
@@ -132,6 +136,7 @@ int main() {
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
|
||||
+2
-2
@@ -40,13 +40,13 @@ public:
|
||||
}
|
||||
|
||||
// Load the config
|
||||
static bool LoadConfig() {
|
||||
static bool LoadConfig(const std::string& path = "") {
|
||||
if (_chat_config != nullptr)
|
||||
delete _chat_config;
|
||||
_chat_config=new ucsconfig;
|
||||
_config=_chat_config;
|
||||
|
||||
return _config->parseFile();
|
||||
return _config->parseFile(path);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -74,6 +74,10 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
||||
{
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadLogs: {
|
||||
LogSys.LoadLogDatabaseSettings();
|
||||
break;
|
||||
}
|
||||
case ServerOP_DiscordWebhookMessage: {
|
||||
auto *q = (DiscordWebhookMessage_Struct *) p.Data();
|
||||
|
||||
|
||||
@@ -50,6 +50,11 @@ if ($Config{osname} =~ /Win|MS/i) {
|
||||
$OS = "Windows";
|
||||
}
|
||||
|
||||
if (-e "../eqemu_config.json") {
|
||||
print "[Info] Config is up one level, let's set current directory up one level...\n";
|
||||
chdir("../");
|
||||
}
|
||||
|
||||
#############################################
|
||||
# internet check
|
||||
#############################################
|
||||
@@ -83,6 +88,8 @@ if (-d "bin") {
|
||||
$bin_dir = "bin/";
|
||||
}
|
||||
|
||||
my $world_path = get_world_path();
|
||||
|
||||
#############################################
|
||||
# run routines
|
||||
#############################################
|
||||
@@ -540,14 +547,6 @@ sub do_installer_routines
|
||||
print `"$path" --host $host --user $root_user --password="$root_password" -N -B -e "FLUSH PRIVILEGES"`;
|
||||
}
|
||||
|
||||
my $world_path = "world";
|
||||
if (-e "bin/world") {
|
||||
$world_path = "bin/world";
|
||||
}
|
||||
elsif (-e "bin/world.exe") {
|
||||
$world_path = "bin/world.exe";
|
||||
}
|
||||
|
||||
#::: Get Binary DB version
|
||||
if ($OS eq "Windows") {
|
||||
@db_version = split(': ', `"$world_path" db_version`);
|
||||
@@ -592,15 +591,6 @@ sub check_for_input
|
||||
|
||||
sub check_for_world_bootup_database_update
|
||||
{
|
||||
|
||||
my $world_path = "world";
|
||||
if (-e "bin/world") {
|
||||
$world_path = "bin/world";
|
||||
}
|
||||
elsif (-e "bin/world.exe") {
|
||||
$world_path = "bin/world.exe";
|
||||
}
|
||||
|
||||
$binary_database_version = 0;
|
||||
$local_database_version = 0;
|
||||
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
my $filename = './common/eqemu_logsys.h';
|
||||
open(my $fh, '<:encoding(UTF-8)', $filename)
|
||||
or die "Could not open file '$filename' $!";
|
||||
|
||||
my $contents = "";
|
||||
while (my $row = <$fh>) {
|
||||
chomp $row;
|
||||
$contents .= $row . "\n";
|
||||
}
|
||||
|
||||
my @enum = split('enum LogCategory \{', $contents);
|
||||
|
||||
if (scalar(@enum) > 0) {
|
||||
# print $enum[1];
|
||||
my @second_split = split('};', $enum[1]);
|
||||
if (scalar(@second_split) > 0) {
|
||||
my $categories = $second_split[0];
|
||||
$categories =~ s/^\s+//;
|
||||
$categories =~ s/\s+$//;
|
||||
$categories =~ s/ //g;
|
||||
$categories =~ s/ //g;
|
||||
$categories =~ s/\n//g;
|
||||
$categories =~ s/None=0,//g;
|
||||
$categories =~ s/,MaxCategoryID//g;
|
||||
$categories =~ s/\/\*//g;
|
||||
$categories =~ s/\*\///g;
|
||||
$categories =~ s/Don'tRemovethis//g;
|
||||
|
||||
my @cats = split(',', $categories);
|
||||
|
||||
foreach my $cat (@cats) {
|
||||
print "#define Log" . $cat . "(message, ...) do {\\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::" . $cat . "))\\
|
||||
OutF(LogSys, Logs::General, Logs::" . $cat . ", __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\\
|
||||
} while (0)
|
||||
|
||||
#define Log" . $cat . "Detail(message, ...) do {\\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::" . $cat . "))\\
|
||||
OutF(LogSys, Logs::Detail, Logs::" . $cat . ", __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\\
|
||||
} while (0)
|
||||
|
||||
";
|
||||
# print "$cat\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close $fh;
|
||||
@@ -1,241 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Author: Akkadius
|
||||
# @file: lua-doc-parser.pl
|
||||
# @description: Script meant to parse the source code to build the LUA API list
|
||||
|
||||
use File::Find;
|
||||
use Data::Dumper;
|
||||
|
||||
sub usage() {
|
||||
print "Usage:\n";
|
||||
print " --client - Prints methods for just client class methods\n";
|
||||
print " --mob - Prints methods for just mob class methods\n";
|
||||
print " --npc - Prints methods for just npc class methods\n";
|
||||
print " --entity - Prints methods for just entity class methods\n";
|
||||
print " --entity_list - Prints methods for just entity_list class methods\n";
|
||||
print " --door - Prints methods for just door class methods\n";
|
||||
print " --object - Prints methods for just object class methods\n";
|
||||
print " --group - Prints methods for just group class methods\n";
|
||||
print " --raid - Prints methods for just raid class methods\n";
|
||||
print " --item - Prints methods for just item class methods\n";
|
||||
print " --iteminst - Prints methods for just iteminst class methods\n";
|
||||
print " --inventory - Prints methods for just inventory class methods\n";
|
||||
print " --corpse - Prints methods for just corpse class methods\n";
|
||||
print " --hate_entry - Prints methods for just hate_entry class methods\n";
|
||||
print " --quest - Prints methods for just quest class methods\n";
|
||||
print " --spell - Prints methods for just spell class methods\n";
|
||||
print " --spawn - Prints methods for just spawn class methods\n";
|
||||
print " --packet - Prints methods for just packet class methods\n";
|
||||
print " --stat_bonuses - Prints methods for just stat_bonuses class methods\n";
|
||||
print " --all - Prints methods for all classes\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if($#ARGV < 0) {
|
||||
usage();
|
||||
}
|
||||
|
||||
#::: Open File
|
||||
my $filename = 'lua-api.md';
|
||||
open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
|
||||
|
||||
my $export = $ARGV[0];
|
||||
$export=~s/--//g;
|
||||
|
||||
my $export_file_search = $export;
|
||||
|
||||
if ($export eq "quest") {
|
||||
$export_file_search = "lua_general";
|
||||
}
|
||||
|
||||
my @files;
|
||||
my $start_dir = "zone/";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
|
||||
#::: Skip non lua.cpp files
|
||||
if($file!~/lua_/i || $file!~/cpp/i){
|
||||
next;
|
||||
}
|
||||
|
||||
#::: If we are specifying a specific class type, skip everything else
|
||||
if ($export ne "all" && $export ne "") {
|
||||
if ($file!~/$export_file_search\.cpp/i) {
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
@methods = ();
|
||||
$split_key = "";
|
||||
$object_prefix = "";
|
||||
|
||||
#::: Client Export
|
||||
if ($export=~/all|client/i && $file=~/_client/i) {
|
||||
$split_key = "Client::";
|
||||
$object_prefix = "client:";
|
||||
}
|
||||
|
||||
#::: Mob Export
|
||||
if ($export=~/all|mob/i && $file=~/_mob/i) {
|
||||
$split_key = "Mob::";
|
||||
$object_prefix = "mob:";
|
||||
}
|
||||
|
||||
#::: NPC Export
|
||||
if ($export=~/all|npc/i && $file=~/_npc/i) {
|
||||
$split_key = "NPC::";
|
||||
$object_prefix = "npc:";
|
||||
}
|
||||
|
||||
#::: Object Export
|
||||
if ($export=~/all|object/i && $file=~/_object/i) {
|
||||
$split_key = "Object::";
|
||||
$object_prefix = "object:";
|
||||
}
|
||||
|
||||
#::: Door Export
|
||||
if ($export=~/all|door/i && $file=~/_door/i) {
|
||||
$split_key = "Door::";
|
||||
$object_prefix = "door:";
|
||||
}
|
||||
|
||||
#::: Entity Export
|
||||
if ($export=~/all|entity/i && $file=~/_entity/i) {
|
||||
$split_key = "Entity::";
|
||||
$object_prefix = "entity:";
|
||||
}
|
||||
|
||||
#::: Entity List Export
|
||||
if ($export=~/all|entity_list/i && $file=~/_entity_list/i) {
|
||||
$split_key = "EntityList::";
|
||||
$object_prefix = "entity_list:";
|
||||
}
|
||||
|
||||
#::: Group
|
||||
if ($export=~/all|group/i && $file=~/_group/i) {
|
||||
$split_key = "Group::";
|
||||
$object_prefix = "group:";
|
||||
}
|
||||
|
||||
#::: Raid
|
||||
if ($export=~/all|raid/i && $file=~/_raid/i) {
|
||||
$split_key = "Raid::";
|
||||
$object_prefix = "raid:";
|
||||
}
|
||||
|
||||
#::: Corpse
|
||||
if ($export=~/all|corpse/i && $file=~/_corpse/i) {
|
||||
$split_key = "Corpse::";
|
||||
$object_prefix = "corpse:";
|
||||
}
|
||||
|
||||
#::: Hateentry
|
||||
if ($export=~/all|hate_entry/i && $file=~/_hate_entry/i) {
|
||||
$split_key = "HateEntry::";
|
||||
$object_prefix = "hate_entry:";
|
||||
}
|
||||
|
||||
#::: Spell
|
||||
if ($export=~/all|spell/i && $file=~/_spell/i) {
|
||||
$split_key = "Spell::";
|
||||
$object_prefix = "spell:";
|
||||
}
|
||||
|
||||
#::: Spawn
|
||||
if ($export=~/all|spawn/i && $file=~/_spawn/i) {
|
||||
$split_key = "Spawn::";
|
||||
$object_prefix = "spawn:";
|
||||
}
|
||||
|
||||
#::: StatBonuses
|
||||
if ($export=~/all|stat_bonuses/i && $file=~/stat_bonuses/i) {
|
||||
$split_key = "StatBonuses::";
|
||||
$object_prefix = "statbonuses:";
|
||||
}
|
||||
|
||||
#::: Item
|
||||
if ($export=~/all|item/i && $file=~/_item/i) {
|
||||
$split_key = "Item::";
|
||||
$object_prefix = "item:";
|
||||
}
|
||||
|
||||
#::: ItemInst
|
||||
if ($export=~/all|iteminst/i && $file=~/_iteminst/i) {
|
||||
$split_key = "ItemInst::";
|
||||
$object_prefix = "iteminst:";
|
||||
}
|
||||
|
||||
#::: Inventory
|
||||
if ($export=~/all|inventory/i && $file=~/_inventory/i) {
|
||||
$split_key = "Inventory::";
|
||||
$object_prefix = "inventory:";
|
||||
}
|
||||
|
||||
#::: Packet
|
||||
if ($export=~/all|packet/i && $file=~/_packet/i) {
|
||||
$split_key = "Packet::";
|
||||
$object_prefix = "packet:";
|
||||
}
|
||||
|
||||
#::: Quest
|
||||
if ($export=~/all|quest/i && $file=~/lua_general/i) {
|
||||
$split_key = " lua_";
|
||||
$object_prefix = "eq.";
|
||||
}
|
||||
|
||||
#::: Open File
|
||||
print "\nOpening '" . $file . "'\n";
|
||||
|
||||
if ($split_key eq "") {
|
||||
next;
|
||||
}
|
||||
|
||||
open (FILE, $file);
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
$line = $_;
|
||||
|
||||
@data = split(" ", $line);
|
||||
|
||||
if ((lc(substr($data[1], 0, 4)) eq "lua_") && $line!~/luabind/i && $line!~/return |#ifdef|struct /i) {
|
||||
#::: Get return type
|
||||
$return_type = trim($data[0]);
|
||||
|
||||
@method_split = split($split_key, $line);
|
||||
@method_end = split("{", $method_split[1]);
|
||||
|
||||
$method = $object_prefix . trim($method_end[0]) . "; -- " . $return_type . "\n";
|
||||
|
||||
push @methods, $method;
|
||||
}
|
||||
}
|
||||
|
||||
#::: Header
|
||||
$header = $split_key;
|
||||
$header =~s/:://g;
|
||||
|
||||
print $fh "# " . $header . "\n";
|
||||
print $fh "```lua\n";
|
||||
|
||||
@methods = sort @methods;
|
||||
foreach $method (@methods) {
|
||||
print $fh $method;
|
||||
print $method;
|
||||
}
|
||||
|
||||
print $fh "```\n\n";
|
||||
}
|
||||
|
||||
close $fh;
|
||||
|
||||
#::: Trim Whitespaces
|
||||
sub trim {
|
||||
my $string = $_[0];
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
return $string;
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Author: Akkadius
|
||||
# @file: perl-doc-parser.pl
|
||||
# @description: Script meant to parse the source code to build the Perl API list
|
||||
|
||||
use File::Find;
|
||||
use Data::Dumper;
|
||||
|
||||
sub usage() {
|
||||
print "Usage:\n";
|
||||
print " --client - Prints methods for just client class methods\n";
|
||||
print " --mob - Prints methods for just mob class methods\n";
|
||||
print " --npc - Prints methods for just npc class methods\n";
|
||||
print " --entity - Prints methods for just entity class methods\n";
|
||||
print " --door - Prints methods for just door class methods\n";
|
||||
print " --object - Prints methods for just object class methods\n";
|
||||
print " --group - Prints methods for just group class methods\n";
|
||||
print " --raid - Prints methods for just raid class methods\n";
|
||||
print " --questitem - Prints methods for just questitem class methods\n";
|
||||
print " --corpse - Prints methods for just corpse class methods\n";
|
||||
print " --hateentry - Prints methods for just hateentry class methods\n";
|
||||
print " --quest - Prints methods for just quest class methods\n";
|
||||
print " --all - Prints methods for all classes\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if($#ARGV < 0) {
|
||||
usage();
|
||||
}
|
||||
|
||||
my $export = $ARGV[0];
|
||||
$export=~s/--//g;
|
||||
|
||||
my $export_file_search = $export;
|
||||
|
||||
if ($export eq "quest") {
|
||||
$export_file_search = "embparser_api";
|
||||
}
|
||||
|
||||
my @files;
|
||||
my $start_dir = "zone/";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
|
||||
#::: Skip non Perl files
|
||||
if($file!~/perl_|embparser_api/i){
|
||||
next;
|
||||
}
|
||||
|
||||
#::: If we are specifying a specific class type, skip everything else
|
||||
if ($export ne "all" && $export ne "") {
|
||||
if ($file!~/$export_file_search/i) {
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
@methods = ();
|
||||
$split_key = "";
|
||||
$object_prefix = "";
|
||||
|
||||
#::: Open File
|
||||
print "\nOpening '" . $file . "'\n";
|
||||
open (FILE, $file);
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
$line = $_;
|
||||
|
||||
if ($line=~/Perl_croak/i && $line=~/Usa/i && $line=~/::/i && $line!~/::new/i) {
|
||||
|
||||
#::: Client export
|
||||
if ($export=~/all|client/i && $line=~/Client::/i) {
|
||||
$split_key = "Client::";
|
||||
$object_prefix = "\$client->";
|
||||
}
|
||||
|
||||
#::: Mob export
|
||||
if ($export=~/all|mob/i && $line=~/Mob::/i) {
|
||||
$split_key = "Mob::";
|
||||
$object_prefix = "\$mob->";
|
||||
}
|
||||
|
||||
#::: NPC export
|
||||
if ($export=~/all|npc/i && $line=~/NPC::/i) {
|
||||
$split_key = "NPC::";
|
||||
$object_prefix = "\$npc->";
|
||||
}
|
||||
|
||||
#::: Corpse export
|
||||
if ($export=~/all|corpse/i && $line=~/Corpse::/i) {
|
||||
$split_key = "Corpse::";
|
||||
$object_prefix = "\$corpse->";
|
||||
}
|
||||
|
||||
#::: Entity export
|
||||
if ($export=~/all|entity/i && $line=~/EntityList::/i) {
|
||||
$split_key = "EntityList::";
|
||||
$object_prefix = "\$entity_list->";
|
||||
}
|
||||
|
||||
#::: Doors export
|
||||
if ($export=~/all|door/i && $line=~/Doors::/i) {
|
||||
$split_key = "Doors::";
|
||||
$object_prefix = "\$door->";
|
||||
}
|
||||
|
||||
#::: Object export
|
||||
if ($export=~/all|object/i && $line=~/Object::/i) {
|
||||
$split_key = "Object::";
|
||||
$object_prefix = "\$object->";
|
||||
}
|
||||
|
||||
#::: Group export
|
||||
if ($export=~/all|group/i && $line=~/Group::/i) {
|
||||
$split_key = "Group::";
|
||||
$object_prefix = "\$group->";
|
||||
}
|
||||
|
||||
#::: Raid export
|
||||
if ($export=~/all|raid/i && $line=~/Raid::/i) {
|
||||
$split_key = "Raid::";
|
||||
$object_prefix = "\$raid->";
|
||||
}
|
||||
|
||||
#::: Hateentry export
|
||||
if ($export=~/all|hateentry/i && $line=~/HateEntry::/i) {
|
||||
$split_key = "HateEntry::";
|
||||
$object_prefix = "\$hate_entry->";
|
||||
}
|
||||
|
||||
#::: Questitem export
|
||||
if ($export=~/all|questitem/i && $line=~/QuestItem::/i) {
|
||||
$split_key = "QuestItem::";
|
||||
$object_prefix = "\$quest_item->";
|
||||
}
|
||||
|
||||
#::: Quest:: exports
|
||||
if ($export=~/all|quest/i && $line=~/quest::/i) {
|
||||
$split_key = "quest::";
|
||||
$object_prefix = "\quest::";
|
||||
}
|
||||
|
||||
#::: Split on croak usage
|
||||
@data = split($split_key, $line);
|
||||
$usage = trim($data[1]);
|
||||
|
||||
#::: Split out param borders and get method name
|
||||
@params_begin = split('\(', $usage);
|
||||
$method_name = trim($params_begin[0]);
|
||||
|
||||
#::: Get params string built
|
||||
@params_end = split('\)', $params_begin[1]);
|
||||
$params_string = trim($params_end[0]);
|
||||
$params_string =~s/THIS\,//g;
|
||||
$params_string =~s/THIS//g;
|
||||
$params_string = trim($params_string);
|
||||
|
||||
$method = $object_prefix . $method_name . "(" . lc($params_string) . ")\n";
|
||||
|
||||
push @methods, $method;
|
||||
}
|
||||
}
|
||||
|
||||
@methods = sort @methods;
|
||||
foreach $method (@methods) {
|
||||
print $method;
|
||||
}
|
||||
}
|
||||
|
||||
#::: Trim Whitespaces
|
||||
sub trim {
|
||||
my $string = $_[0];
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
return $string;
|
||||
}
|
||||
@@ -462,6 +462,10 @@
|
||||
9206|2022_09_03_fix_door_destination_headings.sql|SELECT * FROM db_version WHERE version >= 9206|empty|
|
||||
9207|2022_09_03_fix_zone_point_heading_data.sql|SELECT * FROM db_version WHERE version >= 9207|empty|
|
||||
9208|2022_09_25_task_concat_matchlists.sql|SHOW COLUMNS FROM `task_activities` LIKE 'npc_id'|not_empty|
|
||||
9209|2022_09_28_discord_webhooks.sql|SHOW COLUMNS FROM `logsys_categories` LIKE 'log_to_discord'|empty|
|
||||
9210|2022_10_11_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and client_version_mask = 4294967232|empty|
|
||||
9211|2022_10_14_fix_neriak_pok_stone.sql|select * from doors where id = 2057 and `name` = 'POKNRKPORT500' and client_version_mask = 4294967232|empty|
|
||||
9212|2022_10_14_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and dest_zone = 'misty'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
SET SESSION group_concat_max_len = 1048576;
|
||||
SET collation_connection = latin1_swedish_ci;
|
||||
|
||||
-- backup original(s)
|
||||
CREATE TABLE `goallists_backup_9_25_2022` LIKE `goallists`;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE logsys_categories
|
||||
ADD log_to_discord smallint(11) default 0 AFTER log_to_gmsay;
|
||||
ALTER TABLE logsys_categories
|
||||
ADD discord_webhook_id int(11) default 0 AFTER log_to_discord;
|
||||
@@ -0,0 +1,2 @@
|
||||
REPLACE INTO `doors` (`id`, `doorid`, `zone`, `version`, `name`, `pos_y`, `pos_x`, `pos_z`, `heading`, `opentype`, `guild`, `lockpick`, `keyitem`, `nokeyring`, `triggerdoor`, `triggertype`, `disable_timer`, `doorisopen`, `door_param`, `dest_zone`, `dest_instance`, `dest_x`, `dest_y`, `dest_z`, `dest_heading`, `invert_state`, `incline`, `size`, `buffer`, `client_version_mask`, `is_ldon_door`, `dz_switch_id`, `min_expansion`, `max_expansion`, `content_flags`, `content_flags_disabled`) VALUES (2040, 37, 'PoKnowledge', 0, 'POKRVPORT500', 908.668, 1228.06, -156.248, 384, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'mistythicket', 0, -209, -324, 8, 253, 0, 0, 100, -559.555, 4294967232, 0, 0, -1, -1, NULL, NULL);
|
||||
REPLACE INTO `doors` (`id`, `doorid`, `zone`, `version`, `name`, `pos_y`, `pos_x`, `pos_z`, `heading`, `opentype`, `guild`, `lockpick`, `keyitem`, `nokeyring`, `triggerdoor`, `triggertype`, `disable_timer`, `doorisopen`, `door_param`, `dest_zone`, `dest_instance`, `dest_x`, `dest_y`, `dest_z`, `dest_heading`, `invert_state`, `incline`, `size`, `buffer`, `client_version_mask`, `is_ldon_door`, `dz_switch_id`, `min_expansion`, `max_expansion`, `content_flags`, `content_flags_disabled`) VALUES (36669, 158, 'PoKnowledge', 0, 'POKRVPORT500', 908.668, 1228.06, -156.248, 384, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'misty', 0, -1262.71, -546, 8, 2, 0, 0, 100, -559.555, 63, 0, 0, -1, -1, NULL, NULL);
|
||||
@@ -0,0 +1 @@
|
||||
REPLACE INTO `doors` (`id`, `doorid`, `zone`, `version`, `name`, `pos_y`, `pos_x`, `pos_z`, `heading`, `opentype`, `guild`, `lockpick`, `keyitem`, `nokeyring`, `triggerdoor`, `triggertype`, `disable_timer`, `doorisopen`, `door_param`, `dest_zone`, `dest_instance`, `dest_x`, `dest_y`, `dest_z`, `dest_heading`, `invert_state`, `incline`, `size`, `buffer`, `client_version_mask`, `is_ldon_door`, `dz_switch_id`, `min_expansion`, `max_expansion`, `content_flags`, `content_flags_disabled`) VALUES (2040, 37, 'PoKnowledge', 0, 'POKRVPORT500', 908.668, 1228.06, -156.248, 384, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'misty', 0, -1262.71, -546, 8, 2, 0, 0, 100, -559.555, 4294967232, 0, 0, -1, -1, NULL, NULL);
|
||||
@@ -0,0 +1,2 @@
|
||||
REPLACE INTO `doors` (`id`, `doorid`, `zone`, `version`, `name`, `pos_y`, `pos_x`, `pos_z`, `heading`, `opentype`, `guild`, `lockpick`, `keyitem`, `nokeyring`, `triggerdoor`, `triggertype`, `disable_timer`, `doorisopen`, `door_param`, `dest_zone`, `dest_instance`, `dest_x`, `dest_y`, `dest_z`, `dest_heading`, `invert_state`, `incline`, `size`, `buffer`, `client_version_mask`, `is_ldon_door`, `dz_switch_id`, `min_expansion`, `max_expansion`, `content_flags`, `content_flags_disabled`) VALUES (2057, 20, 'PoKnowledge', 0, 'POKNRKPORT500', -909.187, 131.793, -156.148, 256, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'nektulos', 1, -840, -809, 9, 999, 0, 0, 100, 733.98, 4294967232, 0, 0, -1, -1, NULL, NULL);
|
||||
REPLACE INTO `doors` (`id`, `doorid`, `zone`, `version`, `name`, `pos_y`, `pos_x`, `pos_z`, `heading`, `opentype`, `guild`, `lockpick`, `keyitem`, `nokeyring`, `triggerdoor`, `triggertype`, `disable_timer`, `doorisopen`, `door_param`, `dest_zone`, `dest_instance`, `dest_x`, `dest_y`, `dest_z`, `dest_heading`, `invert_state`, `incline`, `size`, `buffer`, `client_version_mask`, `is_ldon_door`, `dz_switch_id`, `min_expansion`, `max_expansion`, `content_flags`, `content_flags_disabled`) VALUES (17151, 157, 'PoKnowledge', 0, 'POKNRKPORT500', -909.187, 131.793, -156.148, 256, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'nektulos', 0, -840, -809, 9, 999, 0, 0, 100, 733.98, 3, 0, 0, -1, -1, NULL, NULL);
|
||||
+70
-70
@@ -1,78 +1,78 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
SET(world_sources
|
||||
adventure.cpp
|
||||
adventure_manager.cpp
|
||||
client.cpp
|
||||
cliententry.cpp
|
||||
clientlist.cpp
|
||||
console.cpp
|
||||
dynamic_zone.cpp
|
||||
dynamic_zone_manager.cpp
|
||||
eql_config.cpp
|
||||
eqemu_api_world_data_service.cpp
|
||||
expedition_database.cpp
|
||||
expedition_message.cpp
|
||||
launcher_link.cpp
|
||||
launcher_list.cpp
|
||||
lfplist.cpp
|
||||
login_server.cpp
|
||||
login_server_list.cpp
|
||||
main.cpp
|
||||
queryserv.cpp
|
||||
shared_task_manager.cpp
|
||||
shared_task_world_messaging.cpp
|
||||
ucs.cpp
|
||||
web_interface.cpp
|
||||
web_interface_eqw.cpp
|
||||
wguild_mgr.cpp
|
||||
world_event_scheduler.cpp
|
||||
world_config.cpp
|
||||
world_console_connection.cpp
|
||||
world_server_command_handler.cpp
|
||||
worlddb.cpp
|
||||
world_boot.cpp
|
||||
zonelist.cpp
|
||||
zoneserver.cpp
|
||||
)
|
||||
adventure.cpp
|
||||
adventure_manager.cpp
|
||||
client.cpp
|
||||
cliententry.cpp
|
||||
clientlist.cpp
|
||||
console.cpp
|
||||
dynamic_zone.cpp
|
||||
dynamic_zone_manager.cpp
|
||||
eql_config.cpp
|
||||
eqemu_api_world_data_service.cpp
|
||||
expedition_database.cpp
|
||||
expedition_message.cpp
|
||||
launcher_link.cpp
|
||||
launcher_list.cpp
|
||||
lfplist.cpp
|
||||
login_server.cpp
|
||||
login_server_list.cpp
|
||||
main.cpp
|
||||
queryserv.cpp
|
||||
shared_task_manager.cpp
|
||||
shared_task_world_messaging.cpp
|
||||
ucs.cpp
|
||||
web_interface.cpp
|
||||
web_interface_eqw.cpp
|
||||
wguild_mgr.cpp
|
||||
world_event_scheduler.cpp
|
||||
world_config.cpp
|
||||
world_console_connection.cpp
|
||||
world_server_cli.cpp
|
||||
worlddb.cpp
|
||||
world_boot.cpp
|
||||
zonelist.cpp
|
||||
zoneserver.cpp
|
||||
)
|
||||
|
||||
SET(world_headers
|
||||
adventure.h
|
||||
adventure_manager.h
|
||||
adventure_template.h
|
||||
client.h
|
||||
cliententry.h
|
||||
clientlist.h
|
||||
console.h
|
||||
dynamic_zone.h
|
||||
dynamic_zone_manager.h
|
||||
eql_config.h
|
||||
eqemu_api_world_data_service.h
|
||||
expedition_database.h
|
||||
expedition_message.h
|
||||
launcher_link.h
|
||||
launcher_list.h
|
||||
lfplist.h
|
||||
login_server.h
|
||||
login_server_list.h
|
||||
queryserv.h
|
||||
shared_task_manager.h
|
||||
shared_task_world_messaging.h
|
||||
sof_char_create_data.h
|
||||
ucs.h
|
||||
web_interface.h
|
||||
web_interface_eqw.h
|
||||
wguild_mgr.h
|
||||
world_config.h
|
||||
world_console_connection.h
|
||||
world_tcp_connection.h
|
||||
world_server_command_handler.h
|
||||
worlddb.h
|
||||
world_boot.h
|
||||
world_event_scheduler.h
|
||||
zonelist.h
|
||||
zoneserver.h
|
||||
)
|
||||
adventure.h
|
||||
adventure_manager.h
|
||||
adventure_template.h
|
||||
client.h
|
||||
cliententry.h
|
||||
clientlist.h
|
||||
console.h
|
||||
dynamic_zone.h
|
||||
dynamic_zone_manager.h
|
||||
eql_config.h
|
||||
eqemu_api_world_data_service.h
|
||||
expedition_database.h
|
||||
expedition_message.h
|
||||
launcher_link.h
|
||||
launcher_list.h
|
||||
lfplist.h
|
||||
login_server.h
|
||||
login_server_list.h
|
||||
queryserv.h
|
||||
shared_task_manager.h
|
||||
shared_task_world_messaging.h
|
||||
sof_char_create_data.h
|
||||
ucs.h
|
||||
web_interface.h
|
||||
web_interface_eqw.h
|
||||
wguild_mgr.h
|
||||
world_config.h
|
||||
world_console_connection.h
|
||||
world_tcp_connection.h
|
||||
world_server_cli.h
|
||||
worlddb.h
|
||||
world_boot.h
|
||||
world_event_scheduler.h
|
||||
zonelist.h
|
||||
zoneserver.h
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(world ${world_sources} ${world_headers})
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "../../common/eqemu_logsys_log_aliases.h"
|
||||
#include "../worlddb.h"
|
||||
|
||||
void WorldserverCLI::CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Copies a character into a destination account";
|
||||
|
||||
std::vector<std::string> arguments = {
|
||||
"source_character_name",
|
||||
"destination_character_name",
|
||||
"destination_account_name"
|
||||
};
|
||||
std::vector<std::string> options = {};
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv);
|
||||
|
||||
std::string source_character_name = cmd(2).str();
|
||||
std::string destination_character_name = cmd(3).str();
|
||||
std::string destination_account_name = cmd(4).str();
|
||||
|
||||
LogInfo(
|
||||
"Attempting to copy character [{}] to [{}] via account [{}]",
|
||||
source_character_name,
|
||||
destination_character_name,
|
||||
destination_account_name
|
||||
);
|
||||
|
||||
database.CopyCharacter(
|
||||
source_character_name,
|
||||
destination_character_name,
|
||||
destination_account_name
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "../../common/database/database_dump_service.h"
|
||||
|
||||
void WorldserverCLI::DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Dumps server database tables";
|
||||
|
||||
std::vector<std::string> arguments = {};
|
||||
std::vector<std::string> options = {
|
||||
"--all",
|
||||
"--content-tables",
|
||||
"--login-tables",
|
||||
"--player-tables",
|
||||
"--bot-tables",
|
||||
"--state-tables",
|
||||
"--system-tables",
|
||||
"--query-serv-tables",
|
||||
"--table-structure-only",
|
||||
"--table-lock",
|
||||
"--dump-path=",
|
||||
"--dump-output-to-console",
|
||||
"--drop-table-syntax-only",
|
||||
"--compress"
|
||||
};
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv);
|
||||
|
||||
auto s = new DatabaseDumpService();
|
||||
bool dump_all = cmd[{"-a", "--all"}];
|
||||
|
||||
if (!cmd("--dump-path").str().empty()) {
|
||||
s->SetDumpPath(cmd("--dump-path").str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Option
|
||||
*/
|
||||
s->SetDumpContentTables(cmd[{"--content-tables"}] || dump_all);
|
||||
s->SetDumpLoginServerTables(cmd[{"--login-tables"}] || dump_all);
|
||||
s->SetDumpPlayerTables(cmd[{"--player-tables"}] || dump_all);
|
||||
s->SetDumpBotTables(cmd[{"--bot-tables"}] || dump_all);
|
||||
s->SetDumpStateTables(cmd[{"--state-tables"}] || dump_all);
|
||||
s->SetDumpSystemTables(cmd[{"--system-tables"}] || dump_all);
|
||||
s->SetDumpQueryServerTables(cmd[{"--query-serv-tables"}] || dump_all);
|
||||
s->SetDumpAllTables(dump_all);
|
||||
|
||||
s->SetDumpWithNoData(cmd[{"--table-structure-only"}]);
|
||||
s->SetDumpTableLock(cmd[{"--table-lock"}]);
|
||||
s->SetDumpWithCompression(cmd[{"--compress"}]);
|
||||
s->SetDumpOutputToConsole(cmd[{"--dump-output-to-console"}]);
|
||||
s->SetDumpDropTableSyntaxOnly(cmd[{"--drop-table-syntax-only"}]);
|
||||
|
||||
/**
|
||||
* Dump
|
||||
*/
|
||||
s->Dump();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "../../common/database_schema.h"
|
||||
#include "../../common/json/json.h"
|
||||
|
||||
void WorldserverCLI::DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Displays server database schema";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value player_tables_json;
|
||||
std::vector<std::string> player_tables = DatabaseSchema::GetPlayerTables();
|
||||
for (const auto &table: player_tables) {
|
||||
player_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value content_tables_json;
|
||||
std::vector<std::string> content_tables = DatabaseSchema::GetContentTables();
|
||||
for (const auto &table: content_tables) {
|
||||
content_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value server_tables_json;
|
||||
std::vector<std::string> server_tables = DatabaseSchema::GetServerTables();
|
||||
for (const auto &table: server_tables) {
|
||||
server_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value login_tables_json;
|
||||
std::vector<std::string> login_tables = DatabaseSchema::GetLoginTables();
|
||||
for (const auto &table: login_tables) {
|
||||
login_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value state_tables_json;
|
||||
std::vector<std::string> state_tables = DatabaseSchema::GetStateTables();
|
||||
for (const auto &table: state_tables) {
|
||||
state_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value version_tables_json;
|
||||
std::vector<std::string> version_tables = DatabaseSchema::GetVersionTables();
|
||||
for (const auto &table: version_tables) {
|
||||
version_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value bot_tables_json;
|
||||
std::vector<std::string> bot_tables = DatabaseSchema::GetBotTables();
|
||||
for (const auto &table: bot_tables) {
|
||||
bot_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value schema;
|
||||
|
||||
schema["content_tables"] = content_tables_json;
|
||||
schema["login_tables"] = login_tables_json;
|
||||
schema["player_tables"] = player_tables_json;
|
||||
schema["server_tables"] = server_tables_json;
|
||||
schema["state_tables"] = state_tables_json;
|
||||
schema["version_tables"] = version_tables_json;
|
||||
schema["bot_tables"] = bot_tables_json;
|
||||
|
||||
std::stringstream payload;
|
||||
payload << schema;
|
||||
|
||||
std::cout << payload.str() << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "../worlddb.h"
|
||||
|
||||
void WorldserverCLI::DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Sets account status by account name";
|
||||
|
||||
std::vector<std::string> arguments = {
|
||||
"{name}",
|
||||
"{status}"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = {};
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv);
|
||||
|
||||
database.SetAccountStatus(
|
||||
cmd(2).str(),
|
||||
std::stoi(cmd(3).str())
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "../../common/version.h"
|
||||
#include "../../common/json/json.h"
|
||||
|
||||
void WorldserverCLI::DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Shows database version";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value database_version;
|
||||
|
||||
database_version["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
||||
database_version["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION;
|
||||
|
||||
std::stringstream payload;
|
||||
payload << database_version;
|
||||
|
||||
std::cout << payload.str() << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "../../common/zone_store.h"
|
||||
|
||||
void WorldserverCLI::TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
zone_store.LoadZones(database);
|
||||
|
||||
const char* zonename = ZoneName(0);
|
||||
if (zonename == 0) {
|
||||
LogInfo("Zone name is 0");
|
||||
}
|
||||
if (zonename == nullptr) {
|
||||
LogInfo("Zone name is nullptr");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "../../common/rulesys.h"
|
||||
#include "../../common/repositories/content_flags_repository.h"
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/repositories/criteria/content_filter_criteria.h"
|
||||
#include "../worlddb.h"
|
||||
|
||||
void WorldserverCLI::ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Expansion test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RuleManager::Instance()->LoadRules(&database, "default", false)) {
|
||||
LogInfo("No rule set configured, using default rules");
|
||||
}
|
||||
|
||||
content_service.SetCurrentExpansion(RuleI(Expansion, CurrentExpansion));
|
||||
|
||||
std::vector<ContentFlagsRepository::ContentFlags> flags = {};
|
||||
auto f = ContentFlagsRepository::NewEntity();
|
||||
f.enabled = 1;
|
||||
|
||||
std::vector<std::string> flag_names = {
|
||||
"hateplane_enabled",
|
||||
"patch_nerf_7077",
|
||||
};
|
||||
|
||||
for (auto &name: flag_names) {
|
||||
f.flag_name = name;
|
||||
flags.push_back(f);
|
||||
}
|
||||
|
||||
content_service.SetContentFlags(flags);
|
||||
|
||||
LogInfo(
|
||||
"Current expansion is [{}] ({}) is Velious Enabled [{}] Criteria [{}]",
|
||||
content_service.GetCurrentExpansion(),
|
||||
content_service.GetCurrentExpansionName(),
|
||||
content_service.IsTheScarsOfVeliousEnabled() ? "true" : "false",
|
||||
ContentFilterCriteria::apply()
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "../../common/repositories/instance_list_repository.h"
|
||||
#include "../worlddb.h"
|
||||
|
||||
void WorldserverCLI::TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert one
|
||||
*/
|
||||
auto e = InstanceListRepository::NewEntity();
|
||||
|
||||
e.zone = 999;
|
||||
e.version = 1;
|
||||
e.is_global = 1;
|
||||
e.start_time = 0;
|
||||
e.duration = 0;
|
||||
e.never_expires = 1;
|
||||
|
||||
auto inserted = InstanceListRepository::InsertOne(database, e);
|
||||
|
||||
LogInfo("Inserted ID is [{}] zone [{}]", inserted.id, inserted.zone);
|
||||
|
||||
/**
|
||||
* Find one
|
||||
*/
|
||||
auto f = InstanceListRepository::FindOne(database, inserted.id);
|
||||
|
||||
LogInfo("Found ID is [{}] zone [{}]", f.id, f.zone);
|
||||
|
||||
/**
|
||||
* Update one
|
||||
*/
|
||||
LogInfo("Updating instance id [{}] zone [{}]", f.id, f.zone);
|
||||
|
||||
int update_instance_list_count = InstanceListRepository::UpdateOne(database, f);
|
||||
|
||||
f.zone = 777;
|
||||
|
||||
LogInfo(
|
||||
"Updated instance id [{}] zone [{}] affected [{}]",
|
||||
f.id,
|
||||
f.zone,
|
||||
update_instance_list_count
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Delete one
|
||||
*/
|
||||
int deleted = InstanceListRepository::DeleteOne(database, f.id);
|
||||
|
||||
LogInfo("Deleting one instance [{}] deleted count [{}]", f.id, deleted);
|
||||
|
||||
/**
|
||||
* Insert many
|
||||
*/
|
||||
std::vector<InstanceListRepository::InstanceList> instance_lists;
|
||||
|
||||
auto b = InstanceListRepository::NewEntity();
|
||||
|
||||
b.zone = 999;
|
||||
b.version = 1;
|
||||
b.is_global = 1;
|
||||
b.start_time = 0;
|
||||
b.duration = 0;
|
||||
b.never_expires = 1;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
instance_lists.push_back(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Many
|
||||
*/
|
||||
int inserted_count = InstanceListRepository::InsertMany(database, instance_lists);
|
||||
|
||||
LogInfo("Bulk insertion test, inserted [{}]", inserted_count);
|
||||
|
||||
for (auto &entry: InstanceListRepository::GetWhere(database, fmt::format("zone = {}", 999))) {
|
||||
LogInfo("Iterating through entry id [{}] zone [{}]", entry.id, entry.zone);
|
||||
}
|
||||
|
||||
LogInfo("[Max ID] {}", InstanceListRepository::GetMaxId(database));
|
||||
LogInfo("[Count] {}", InstanceListRepository::Count(database));
|
||||
LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 999"));
|
||||
LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 777"));
|
||||
|
||||
/**
|
||||
* Delete where
|
||||
*/
|
||||
int deleted_count = InstanceListRepository::DeleteWhere(database, fmt::format("zone = {}", 999));
|
||||
|
||||
LogInfo("Bulk deletion test, deleted [{}]", deleted_count);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "../../common/repositories/zone_repository.h"
|
||||
|
||||
void WorldserverCLI::TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto zones = ZoneRepository::GetWhere(content_db, "short_name = 'anguish'");
|
||||
|
||||
for (auto &zone: zones) {
|
||||
LogInfo(
|
||||
"Zone [{}] long_name [{}] id [{}]",
|
||||
zone.short_name,
|
||||
zone.long_name,
|
||||
zone.id
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "../../common/json/json.h"
|
||||
#include "../../common/version.h"
|
||||
|
||||
void WorldserverCLI::Version(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Shows server version";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value j;
|
||||
|
||||
j["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION;
|
||||
j["compile_date"] = COMPILE_DATE;
|
||||
j["compile_time"] = COMPILE_TIME;
|
||||
j["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
||||
j["server_version"] = CURRENT_VERSION;
|
||||
|
||||
std::stringstream payload;
|
||||
payload << j;
|
||||
|
||||
std::cout << payload.str() << std::endl;
|
||||
}
|
||||
+8
-1
@@ -35,6 +35,7 @@
|
||||
#include "../common/emu_versions.h"
|
||||
#include "../common/random.h"
|
||||
#include "../common/shareddb.h"
|
||||
#include "../common/opcodemgr.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "worlddb.h"
|
||||
@@ -1009,7 +1010,13 @@ bool Client::HandlePacket(const EQApplicationPacket *app) {
|
||||
|
||||
EmuOpcode opcode = app->GetOpcode();
|
||||
|
||||
LogNetcode("Received EQApplicationPacket [{:#04x}]", opcode);
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
eqs->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
|
||||
if (!eqs->CheckState(ESTABLISHED)) {
|
||||
LogInfo("Client disconnected (net inactive on send)");
|
||||
|
||||
@@ -686,8 +686,8 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S
|
||||
int idx=-1;
|
||||
while(iterator.MoreElements()) {
|
||||
cle = iterator.GetData();
|
||||
|
||||
const char* tmpZone = ZoneName(cle->zone());
|
||||
|
||||
if (
|
||||
(cle->Online() >= CLE_Status::Zoning) &&
|
||||
(!cle->GetGM() || cle->Anon() != 1 || admin >= cle->Admin()) &&
|
||||
|
||||
@@ -490,7 +490,7 @@ bool LoginServer::Connect()
|
||||
[this](EQ::Net::ServertalkClient *client) {
|
||||
if (client) {
|
||||
LogInfo(
|
||||
"Connected to Loginserver: [{0}:{1}]",
|
||||
"Connected to Loginserver [{0}:{1}]",
|
||||
m_loginserver_address,
|
||||
m_loginserver_port
|
||||
);
|
||||
@@ -499,7 +499,6 @@ bool LoginServer::Connect()
|
||||
zoneserver_list.SendLSZones();
|
||||
|
||||
m_statusupdate_timer = std::make_unique<EQ::Timer>(
|
||||
|
||||
LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) {
|
||||
SendStatus();
|
||||
}
|
||||
|
||||
+22
-8
@@ -88,13 +88,15 @@ union semun {
|
||||
#include "dynamic_zone_manager.h"
|
||||
#include "expedition_database.h"
|
||||
|
||||
#include "world_server_command_handler.h"
|
||||
#include "world_server_cli.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
#include "../common/repositories/character_task_timers_repository.h"
|
||||
#include "../common/zone_store.h"
|
||||
#include "world_event_scheduler.h"
|
||||
#include "shared_task_manager.h"
|
||||
#include "world_boot.h"
|
||||
#include "../common/path_manager.h"
|
||||
|
||||
|
||||
ZoneStore zone_store;
|
||||
ClientList client_list;
|
||||
@@ -115,6 +117,7 @@ const WorldConfig *Config;
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
WebInterfaceList web_interface;
|
||||
PathManager path;
|
||||
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
@@ -142,6 +145,8 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
if (!WorldBoot::LoadServerConfig()) {
|
||||
return 0;
|
||||
}
|
||||
@@ -332,8 +337,8 @@ int main(int argc, char **argv)
|
||||
);
|
||||
|
||||
WorldBoot::CheckForPossibleConfigurationIssues();
|
||||
|
||||
EQStreamManagerInterfaceOptions opts(9000, false, false);
|
||||
|
||||
EQStreamManagerInterfaceOptions opts(Config->WorldUDPPort, false, false);
|
||||
opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
@@ -366,8 +371,14 @@ int main(int argc, char **argv)
|
||||
}
|
||||
);
|
||||
|
||||
while (RunLoops) {
|
||||
auto loop_fn = [&](EQ::Timer* t) {
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
if (!RunLoops) {
|
||||
EQ::EventLoop::Get().Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
eqs = nullptr;
|
||||
|
||||
//give the stream identifier a chance to do its work....
|
||||
@@ -376,7 +387,7 @@ int main(int argc, char **argv)
|
||||
//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{};
|
||||
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.
|
||||
LogInfo("Checking inbound connection [{}] against BannedIPs table", inet_ntoa(in));
|
||||
@@ -442,10 +453,13 @@ int main(int argc, char **argv)
|
||||
);
|
||||
UpdateWindowTitle(window_title);
|
||||
}
|
||||
};
|
||||
|
||||
EQ::Timer process_timer(loop_fn);
|
||||
process_timer.Start(32, true);
|
||||
|
||||
EQ::EventLoop::Get().Run();
|
||||
|
||||
EQ::EventLoop::Get().Process();
|
||||
Sleep(5);
|
||||
}
|
||||
LogInfo("World main loop completed");
|
||||
LogInfo("Shutting down zone connections (if any)");
|
||||
zoneserver_list.KillAll();
|
||||
|
||||
+19
-8
@@ -18,19 +18,25 @@
|
||||
#include "world_boot.h"
|
||||
#include "world_config.h"
|
||||
#include "world_event_scheduler.h"
|
||||
#include "world_server_command_handler.h"
|
||||
#include "world_server_cli.h"
|
||||
#include "../common/zone_store.h"
|
||||
#include "worlddb.h"
|
||||
#include "zonelist.h"
|
||||
#include "zoneserver.h"
|
||||
#include "../common/ip_util.h"
|
||||
#include "../common/zone_store.h"
|
||||
#include "../common/path_manager.h"
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
extern WorldConfig Config;
|
||||
|
||||
void WorldBoot::GMSayHookCallBackProcessWorld(uint16 log_category, std::string message)
|
||||
{
|
||||
// we don't want to loop up with chat messages
|
||||
if (message.find("OP_SpecialMesg") != std::string::npos) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cut messages down to 4000 max to prevent client crash
|
||||
if (!message.empty()) {
|
||||
message = message.substr(0, 4000);
|
||||
@@ -84,10 +90,11 @@ bool WorldBoot::HandleCommandInput(int argc, char **argv)
|
||||
// command handler
|
||||
if (argc > 1) {
|
||||
LogSys.SilenceConsoleLogging();
|
||||
path.LoadPaths();
|
||||
WorldConfig::LoadConfig();
|
||||
LoadDatabaseConnections();
|
||||
LogSys.EnableConsoleLogging();
|
||||
WorldserverCommandHandler::CommandHandler(argc, argv);
|
||||
WorldserverCLI::CommandHandler(argc, argv);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -164,14 +171,14 @@ int get_file_size(const std::string &filename) // path to file
|
||||
|
||||
void WorldBoot::CheckForServerScript(bool force_download)
|
||||
{
|
||||
const std::string file = "eqemu_server.pl";
|
||||
const std::string file = fmt::format("{}/eqemu_server.pl", path.GetServerPath());
|
||||
std::ifstream f(file);
|
||||
|
||||
/* Fetch EQEmu Server script */
|
||||
if (!f || get_file_size(file) < 100 || force_download) {
|
||||
|
||||
if (force_download) {
|
||||
std::remove("eqemu_server.pl");
|
||||
std::remove(fmt::format("{}/eqemu_server.pl", path.GetServerPath()).c_str());
|
||||
} /* Delete local before fetch */
|
||||
|
||||
std::cout << "Pulling down EQEmu Server Maintenance Script (eqemu_server.pl)..." << std::endl;
|
||||
@@ -194,13 +201,15 @@ void WorldBoot::CheckForServerScript(bool force_download)
|
||||
if (auto res = r.Get(u.get_path().c_str())) {
|
||||
if (res->status == 200) {
|
||||
// write file
|
||||
std::ofstream out("eqemu_server.pl");
|
||||
|
||||
std::string script = fmt::format("{}/eqemu_server.pl", path.GetServerPath());
|
||||
std::ofstream out(script);
|
||||
out << res->body;
|
||||
out.close();
|
||||
#ifdef _WIN32
|
||||
#else
|
||||
system("chmod 755 eqemu_server.pl");
|
||||
system("chmod +x eqemu_server.pl");
|
||||
system(fmt::format("chmod 755 {}", script).c_str());
|
||||
system(fmt::format("chmod +x {}", script).c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -211,7 +220,8 @@ void WorldBoot::CheckForXMLConfigUpgrade()
|
||||
{
|
||||
if (!std::ifstream("eqemu_config.json") && std::ifstream("eqemu_config.xml")) {
|
||||
CheckForServerScript(true);
|
||||
if (system("perl eqemu_server.pl convert_xml")) {}
|
||||
std::string command = fmt::format("perl {}/eqemu_server.pl convert_xml", path.GetServerPath());
|
||||
if (system(command.c_str())) {}
|
||||
}
|
||||
else {
|
||||
CheckForServerScript();
|
||||
@@ -286,6 +296,7 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
||||
|
||||
// logging system init
|
||||
auto logging = LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings();
|
||||
|
||||
if (RuleB(Logging, WorldGMSayLogging)) {
|
||||
|
||||
@@ -46,13 +46,13 @@ public:
|
||||
}
|
||||
|
||||
// Load the config
|
||||
static bool LoadConfig() {
|
||||
static bool LoadConfig(const std::string& path = "") {
|
||||
if (_world_config != nullptr)
|
||||
delete _world_config;
|
||||
_world_config=new WorldConfig;
|
||||
_config=_world_config;
|
||||
|
||||
return _config->parseFile();
|
||||
return _config->parseFile(path);
|
||||
}
|
||||
|
||||
// Accessors for the static private object
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "world_server_cli.h"
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void WorldserverCLI::CommandHandler(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1) { return; }
|
||||
|
||||
argh::parser cmd;
|
||||
cmd.parse(argc, argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION);
|
||||
EQEmuCommand::DisplayDebug(cmd);
|
||||
|
||||
/**
|
||||
* Declare command mapping
|
||||
*/
|
||||
auto function_map = EQEmuCommand::function_map;
|
||||
|
||||
/**
|
||||
* Register commands
|
||||
*/
|
||||
function_map["world:version"] = &WorldserverCLI::Version;
|
||||
function_map["character:copy-character"] = &WorldserverCLI::CopyCharacter;
|
||||
function_map["database:version"] = &WorldserverCLI::DatabaseVersion;
|
||||
function_map["database:set-account-status"] = &WorldserverCLI::DatabaseSetAccountStatus;
|
||||
function_map["database:schema"] = &WorldserverCLI::DatabaseGetSchema;
|
||||
function_map["database:dump"] = &WorldserverCLI::DatabaseDump;
|
||||
function_map["test:test"] = &WorldserverCLI::TestCommand;
|
||||
function_map["test:expansion"] = &WorldserverCLI::ExpansionTestCommand;
|
||||
function_map["test:repository"] = &WorldserverCLI::TestRepository;
|
||||
function_map["test:repository2"] = &WorldserverCLI::TestRepository2;
|
||||
|
||||
EQEmuCommand::HandleMenu(function_map, cmd, argc, argv);
|
||||
}
|
||||
|
||||
#include "cli/copy_character.cpp"
|
||||
#include "cli/database_dump.cpp"
|
||||
#include "cli/database_get_schema.cpp"
|
||||
#include "cli/database_set_account_status.cpp"
|
||||
#include "cli/database_version.cpp"
|
||||
#include "cli/test.cpp"
|
||||
#include "cli/test_expansion.cpp"
|
||||
#include "cli/test_repository.cpp"
|
||||
#include "cli/test_repository_2.cpp"
|
||||
#include "cli/version.cpp"
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "iostream"
|
||||
#include "../common/cli/eqemu_command_handler.h"
|
||||
|
||||
#ifndef EQEMU_WORLD_SERVER_COMMAND_HANDLER_H
|
||||
#define EQEMU_WORLD_SERVER_COMMAND_HANDLER_H
|
||||
|
||||
class WorldserverCLI {
|
||||
public:
|
||||
static void CommandHandler(int argc, char **argv);
|
||||
static void Version(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
static void TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_WORLD_SERVER_COMMAND_HANDLER_H
|
||||
@@ -1,523 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* 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 "world_server_command_handler.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/discord/discord.h"
|
||||
#include "../common/json/json.h"
|
||||
#include "../common/version.h"
|
||||
#include "worlddb.h"
|
||||
#include "../common/database_schema.h"
|
||||
#include "../common/database/database_dump_service.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
#include "../common/repositories/criteria/content_filter_criteria.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/repositories/instance_list_repository.h"
|
||||
#include "../common/repositories/zone_repository.h"
|
||||
#include "../zone/queryserv.h"
|
||||
|
||||
namespace WorldserverCommandHandler {
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void CommandHandler(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1) { return; }
|
||||
|
||||
argh::parser cmd;
|
||||
cmd.parse(argc, argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION);
|
||||
EQEmuCommand::DisplayDebug(cmd);
|
||||
|
||||
/**
|
||||
* Declare command mapping
|
||||
*/
|
||||
auto function_map = EQEmuCommand::function_map;
|
||||
|
||||
/**
|
||||
* Register commands
|
||||
*/
|
||||
function_map["world:version"] = &WorldserverCommandHandler::Version;
|
||||
function_map["character:copy-character"] = &WorldserverCommandHandler::CopyCharacter;
|
||||
function_map["database:version"] = &WorldserverCommandHandler::DatabaseVersion;
|
||||
function_map["database:set-account-status"] = &WorldserverCommandHandler::DatabaseSetAccountStatus;
|
||||
function_map["database:schema"] = &WorldserverCommandHandler::DatabaseGetSchema;
|
||||
function_map["database:dump"] = &WorldserverCommandHandler::DatabaseDump;
|
||||
function_map["test:test"] = &WorldserverCommandHandler::TestCommand;
|
||||
function_map["test:expansion"] = &WorldserverCommandHandler::ExpansionTestCommand;
|
||||
function_map["test:repository"] = &WorldserverCommandHandler::TestRepository;
|
||||
function_map["test:repository2"] = &WorldserverCommandHandler::TestRepository2;
|
||||
|
||||
EQEmuCommand::HandleMenu(function_map, cmd, argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Shows database version";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value database_version;
|
||||
|
||||
database_version["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
||||
database_version["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION;
|
||||
|
||||
std::stringstream payload;
|
||||
payload << database_version;
|
||||
|
||||
std::cout << payload.str() << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void Version(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Shows server version";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value database_version;
|
||||
|
||||
database_version["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION;
|
||||
database_version["compile_date"] = COMPILE_DATE;
|
||||
database_version["compile_time"] = COMPILE_TIME;
|
||||
database_version["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
||||
database_version["server_version"] = CURRENT_VERSION;
|
||||
|
||||
std::stringstream payload;
|
||||
payload << database_version;
|
||||
|
||||
std::cout << payload.str() << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Sets account status by account name";
|
||||
|
||||
std::vector<std::string> arguments = {
|
||||
"{name}",
|
||||
"{status}"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = {};
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv);
|
||||
|
||||
database.SetAccountStatus(
|
||||
cmd(2).str(),
|
||||
std::stoi(cmd(3).str())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Displays server database schema";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value player_tables_json;
|
||||
std::vector<std::string> player_tables = DatabaseSchema::GetPlayerTables();
|
||||
for (const auto &table: player_tables) {
|
||||
player_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value content_tables_json;
|
||||
std::vector<std::string> content_tables = DatabaseSchema::GetContentTables();
|
||||
for (const auto &table: content_tables) {
|
||||
content_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value server_tables_json;
|
||||
std::vector<std::string> server_tables = DatabaseSchema::GetServerTables();
|
||||
for (const auto &table: server_tables) {
|
||||
server_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value login_tables_json;
|
||||
std::vector<std::string> login_tables = DatabaseSchema::GetLoginTables();
|
||||
for (const auto &table: login_tables) {
|
||||
login_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value state_tables_json;
|
||||
std::vector<std::string> state_tables = DatabaseSchema::GetStateTables();
|
||||
for (const auto &table: state_tables) {
|
||||
state_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value version_tables_json;
|
||||
std::vector<std::string> version_tables = DatabaseSchema::GetVersionTables();
|
||||
for (const auto &table: version_tables) {
|
||||
version_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value bot_tables_json;
|
||||
std::vector<std::string> bot_tables = DatabaseSchema::GetBotTables();
|
||||
for (const auto &table: bot_tables) {
|
||||
bot_tables_json.append(table);
|
||||
}
|
||||
|
||||
Json::Value schema;
|
||||
|
||||
schema["content_tables"] = content_tables_json;
|
||||
schema["login_tables"] = login_tables_json;
|
||||
schema["player_tables"] = player_tables_json;
|
||||
schema["server_tables"] = server_tables_json;
|
||||
schema["state_tables"] = state_tables_json;
|
||||
schema["version_tables"] = version_tables_json;
|
||||
schema["bot_tables"] = bot_tables_json;
|
||||
|
||||
std::stringstream payload;
|
||||
payload << schema;
|
||||
|
||||
std::cout << payload.str() << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Dumps server database tables";
|
||||
|
||||
std::vector<std::string> arguments = {};
|
||||
std::vector<std::string> options = {
|
||||
"--all",
|
||||
"--content-tables",
|
||||
"--login-tables",
|
||||
"--player-tables",
|
||||
"--bot-tables",
|
||||
"--state-tables",
|
||||
"--system-tables",
|
||||
"--query-serv-tables",
|
||||
"--table-structure-only",
|
||||
"--table-lock",
|
||||
"--dump-path=",
|
||||
"--dump-output-to-console",
|
||||
"--drop-table-syntax-only",
|
||||
"--compress"
|
||||
};
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv);
|
||||
|
||||
auto database_dump_service = new DatabaseDumpService();
|
||||
bool dump_all = cmd[{"-a", "--all"}];
|
||||
|
||||
if (!cmd("--dump-path").str().empty()) {
|
||||
database_dump_service->SetDumpPath(cmd("--dump-path").str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Option
|
||||
*/
|
||||
database_dump_service->SetDumpContentTables(cmd[{"--content-tables"}] || dump_all);
|
||||
database_dump_service->SetDumpLoginServerTables(cmd[{"--login-tables"}] || dump_all);
|
||||
database_dump_service->SetDumpPlayerTables(cmd[{"--player-tables"}] || dump_all);
|
||||
database_dump_service->SetDumpBotTables(cmd[{"--bot-tables"}] || dump_all);
|
||||
database_dump_service->SetDumpStateTables(cmd[{"--state-tables"}] || dump_all);
|
||||
database_dump_service->SetDumpSystemTables(cmd[{"--system-tables"}] || dump_all);
|
||||
database_dump_service->SetDumpQueryServerTables(cmd[{"--query-serv-tables"}] || dump_all);
|
||||
database_dump_service->SetDumpAllTables(dump_all);
|
||||
|
||||
database_dump_service->SetDumpWithNoData(cmd[{"--table-structure-only"}]);
|
||||
database_dump_service->SetDumpTableLock(cmd[{"--table-lock"}]);
|
||||
database_dump_service->SetDumpWithCompression(cmd[{"--compress"}]);
|
||||
database_dump_service->SetDumpOutputToConsole(cmd[{"--dump-output-to-console"}]);
|
||||
database_dump_service->SetDumpDropTableSyntaxOnly(cmd[{"--drop-table-syntax-only"}]);
|
||||
|
||||
/**
|
||||
* Dump
|
||||
*/
|
||||
database_dump_service->Dump();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Expansion test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RuleManager::Instance()->LoadRules(&database, "default", false)) {
|
||||
LogInfo("No rule set configured, using default rules");
|
||||
}
|
||||
|
||||
content_service.SetCurrentExpansion(RuleI(Expansion, CurrentExpansion));
|
||||
|
||||
std::vector<ContentFlagsRepository::ContentFlags> flags = {};
|
||||
auto f = ContentFlagsRepository::NewEntity();
|
||||
f.enabled = 1;
|
||||
|
||||
std::vector<std::string> flag_names = {
|
||||
"hateplane_enabled",
|
||||
"patch_nerf_7077",
|
||||
};
|
||||
|
||||
for (auto &name: flag_names) {
|
||||
f.flag_name = name;
|
||||
flags.push_back(f);
|
||||
}
|
||||
|
||||
content_service.SetContentFlags(flags);
|
||||
|
||||
LogInfo(
|
||||
"Current expansion is [{}] ({}) is Velious Enabled [{}] Criteria [{}]",
|
||||
content_service.GetCurrentExpansion(),
|
||||
content_service.GetCurrentExpansionName(),
|
||||
content_service.IsTheScarsOfVeliousEnabled() ? "true" : "false",
|
||||
ContentFilterCriteria::apply()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert one
|
||||
*/
|
||||
auto instance_list_entry = InstanceListRepository::NewEntity();
|
||||
|
||||
instance_list_entry.zone = 999;
|
||||
instance_list_entry.version = 1;
|
||||
instance_list_entry.is_global = 1;
|
||||
instance_list_entry.start_time = 0;
|
||||
instance_list_entry.duration = 0;
|
||||
instance_list_entry.never_expires = 1;
|
||||
|
||||
auto instance_list_inserted = InstanceListRepository::InsertOne(database, instance_list_entry);
|
||||
|
||||
LogInfo("Inserted ID is [{}] zone [{}]", instance_list_inserted.id, instance_list_inserted.zone);
|
||||
|
||||
/**
|
||||
* Find one
|
||||
*/
|
||||
auto found_instance_list = InstanceListRepository::FindOne(database, instance_list_inserted.id);
|
||||
|
||||
LogInfo("Found ID is [{}] zone [{}]", found_instance_list.id, found_instance_list.zone);
|
||||
|
||||
/**
|
||||
* Update one
|
||||
*/
|
||||
LogInfo("Updating instance id [{}] zone [{}]", found_instance_list.id, found_instance_list.zone);
|
||||
|
||||
int update_instance_list_count = InstanceListRepository::UpdateOne(database, found_instance_list);
|
||||
|
||||
found_instance_list.zone = 777;
|
||||
|
||||
LogInfo(
|
||||
"Updated instance id [{}] zone [{}] affected [{}]",
|
||||
found_instance_list.id,
|
||||
found_instance_list.zone,
|
||||
update_instance_list_count
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Delete one
|
||||
*/
|
||||
int deleted = InstanceListRepository::DeleteOne(database, found_instance_list.id);
|
||||
|
||||
LogInfo("Deleting one instance [{}] deleted count [{}]", found_instance_list.id, deleted);
|
||||
|
||||
/**
|
||||
* Insert many
|
||||
*/
|
||||
std::vector<InstanceListRepository::InstanceList> instance_lists;
|
||||
|
||||
auto instance_list_entry_bulk = InstanceListRepository::NewEntity();
|
||||
|
||||
instance_list_entry_bulk.zone = 999;
|
||||
instance_list_entry_bulk.version = 1;
|
||||
instance_list_entry_bulk.is_global = 1;
|
||||
instance_list_entry_bulk.start_time = 0;
|
||||
instance_list_entry_bulk.duration = 0;
|
||||
instance_list_entry_bulk.never_expires = 1;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
instance_lists.push_back(instance_list_entry_bulk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Many
|
||||
*/
|
||||
int inserted_count = InstanceListRepository::InsertMany(database, instance_lists);
|
||||
|
||||
LogInfo("Bulk insertion test, inserted [{}]", inserted_count);
|
||||
|
||||
for (auto &entry: InstanceListRepository::GetWhere(database, fmt::format("zone = {}", 999))) {
|
||||
LogInfo("Iterating through entry id [{}] zone [{}]", entry.id, entry.zone);
|
||||
}
|
||||
|
||||
LogInfo("[Max ID] {}", InstanceListRepository::GetMaxId(database));
|
||||
LogInfo("[Count] {}", InstanceListRepository::Count(database));
|
||||
LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 999"));
|
||||
LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 777"));
|
||||
|
||||
/**
|
||||
* Delete where
|
||||
*/
|
||||
int deleted_count = InstanceListRepository::DeleteWhere(database, fmt::format("zone = {}", 999));
|
||||
|
||||
LogInfo("Bulk deletion test, deleted [{}]", deleted_count);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Test command";
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto zones = ZoneRepository::GetWhere(content_db, "short_name = 'anguish'");
|
||||
|
||||
for (auto &zone: zones) {
|
||||
LogInfo(
|
||||
"Zone [{}] long_name [{}] id [{}]",
|
||||
zone.short_name,
|
||||
zone.long_name,
|
||||
zone.id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param cmd
|
||||
* @param description
|
||||
*/
|
||||
void CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
{
|
||||
description = "Copies a character into a destination account";
|
||||
|
||||
std::vector<std::string> arguments = {
|
||||
"source_character_name",
|
||||
"destination_character_name",
|
||||
"destination_account_name"
|
||||
};
|
||||
std::vector<std::string> options = {};
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv);
|
||||
|
||||
std::string source_character_name = cmd(2).str();
|
||||
std::string destination_character_name = cmd(3).str();
|
||||
std::string destination_account_name = cmd(4).str();
|
||||
|
||||
LogInfo(
|
||||
"Attempting to copy character [{}] to [{}] via account [{}]",
|
||||
source_character_name,
|
||||
destination_character_name,
|
||||
destination_account_name
|
||||
);
|
||||
|
||||
database.CopyCharacter(
|
||||
source_character_name,
|
||||
destination_character_name,
|
||||
destination_account_name
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* 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 "iostream"
|
||||
#include "../common/cli/eqemu_command_handler.h"
|
||||
|
||||
#ifndef EQEMU_WORLD_SERVER_COMMAND_HANDLER_H
|
||||
#define EQEMU_WORLD_SERVER_COMMAND_HANDLER_H
|
||||
|
||||
namespace WorldserverCommandHandler {
|
||||
void CommandHandler(int argc, char **argv);
|
||||
void Version(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
void TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_WORLD_SERVER_COMMAND_HANDLER_H
|
||||
@@ -94,7 +94,7 @@ ZoneServer::~ZoneServer() {
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoneServer::SetZone(uint32 in_zone_id, uint32 in_instance_id, bool is_static_zone) {
|
||||
bool ZoneServer::SetZone(uint32 in_zone_id, uint32 in_instance_id, bool in_is_static_zone) {
|
||||
is_booting_up = false;
|
||||
|
||||
std::string zone_short_name = ZoneName(in_zone_id, true);
|
||||
@@ -114,7 +114,7 @@ bool ZoneServer::SetZone(uint32 in_zone_id, uint32 in_instance_id, bool is_stati
|
||||
) :
|
||||
""
|
||||
),
|
||||
is_static_zone ? " (Static)" : ""
|
||||
in_is_static_zone ? " (Static)" : ""
|
||||
);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ bool ZoneServer::SetZone(uint32 in_zone_id, uint32 in_instance_id, bool is_stati
|
||||
LSSleepUpdate(GetPrevZoneID());
|
||||
}
|
||||
|
||||
is_static_zone = is_static_zone;
|
||||
is_static_zone = in_is_static_zone;
|
||||
|
||||
strn0cpy(zone_name, zone_short_name.c_str(), sizeof(zone_name));
|
||||
strn0cpy(long_name, zone_long_name.c_str(), sizeof(long_name));
|
||||
@@ -1354,6 +1354,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
}
|
||||
case ServerOP_ReloadLogs: {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
UCSLink.SendPacket(pack);
|
||||
LogSys.LoadLogDatabaseSettings();
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public:
|
||||
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 SendKeepAlive();
|
||||
bool SetZone(uint32 in_zone_id, uint32 in_instance_id = 0, bool is_static_zone = false);
|
||||
bool SetZone(uint32 in_zone_id, uint32 in_instance_id = 0, bool in_is_static_zone = false);
|
||||
void TriggerBootup(uint32 in_zone_id = 0, uint32 in_instance_id = 0, const char* admin_name = 0, bool is_static_zone = false);
|
||||
void Disconnect() { auto handle = tcpc->Handle(); if (handle) { handle->Disconnect(); } }
|
||||
void IncomingClient(Client* client);
|
||||
|
||||
+12
-4
@@ -1372,11 +1372,19 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possib
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (GetOwner() && IsPet())
|
||||
AggroAmount = AggroAmount * RuleI(Aggro, PetSpellAggroMod) / 100;
|
||||
|
||||
if (!ignore_default_buff && IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id))
|
||||
if (GetOwner() && IsPet()) {
|
||||
AggroAmount = AggroAmount * RuleI(Aggro, PetSpellAggroMod) / 100;
|
||||
}
|
||||
|
||||
if (!ignore_default_buff && IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) {
|
||||
AggroAmount = IsBardSong(spell_id) ? 2 : 9;
|
||||
}
|
||||
|
||||
// overrides the hate (ex. Healing Splash), can be negative (but function will return 0).
|
||||
if (spells[spell_id].hate_added != 0) {
|
||||
AggroAmount = spells[spell_id].hate_added;
|
||||
}
|
||||
|
||||
if (AggroAmount > 0) {
|
||||
int HateMod = RuleI(Aggro, SpellAggroMod);
|
||||
@@ -1385,7 +1393,7 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possib
|
||||
AggroAmount = (AggroAmount * HateMod) / 100;
|
||||
}
|
||||
|
||||
return std::max(0, AggroAmount);
|
||||
return std::max(0, AggroAmount + spells[spell_id].bonus_hate); //Bonus Hate from spells like Aurora of Morrow
|
||||
}
|
||||
|
||||
void Mob::AddFeignMemory(Mob* attacker) {
|
||||
|
||||
@@ -829,7 +829,7 @@ Json::Value ApiGetZoneAttributes(EQ::Net::WebsocketServerConnection *connection,
|
||||
|
||||
Json::Value ApiGetLogsysCategories(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
if (!zone || (zone && zone->GetZoneID() == 0)) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user