mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-19 13:28:25 +00:00
Implement initial expedition system
Add Expeditions logging category Add handlers for all Dynamic Zone/Expedition related opcodes Add FormatName string_util function to format character names Add Zone::IsZone helper method Add cross zone MessageString support with variable parameters Add static Client method helpers for cross zone messaging Add #dz gm command to debug expedition cache for current zone
This commit is contained in:
@@ -9,6 +9,7 @@ SET(world_sources
|
||||
console.cpp
|
||||
eql_config.cpp
|
||||
eqemu_api_world_data_service.cpp
|
||||
expedition.cpp
|
||||
launcher_link.cpp
|
||||
launcher_list.cpp
|
||||
lfplist.cpp
|
||||
@@ -39,6 +40,7 @@ SET(world_headers
|
||||
console.h
|
||||
eql_config.h
|
||||
eqemu_api_world_data_service.h
|
||||
expedition.h
|
||||
launcher_link.h
|
||||
launcher_list.h
|
||||
lfplist.h
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 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 "expedition.h"
|
||||
#include "clientlist.h"
|
||||
#include "cliententry.h"
|
||||
#include "zonelist.h"
|
||||
#include "zoneserver.h"
|
||||
#include "worlddb.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
extern ClientList client_list;
|
||||
extern ZSList zoneserver_list;
|
||||
|
||||
void Expedition::PurgeEmptyExpeditions()
|
||||
{
|
||||
std::string query = SQL(
|
||||
DELETE expedition FROM expedition_details expedition
|
||||
LEFT JOIN (
|
||||
SELECT expedition_id, COUNT(IF(is_current_member = TRUE, 1, NULL)) member_count
|
||||
FROM expedition_members
|
||||
GROUP BY expedition_id
|
||||
) AS expedition_members
|
||||
ON expedition_members.expedition_id = expedition.id
|
||||
WHERE expedition_members.expedition_id IS NULL OR expedition_members.member_count <= 0
|
||||
);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
{
|
||||
LogExpeditions("Failed to purge empty expeditions");
|
||||
}
|
||||
}
|
||||
|
||||
void Expedition::PurgeExpiredCharacterLockouts()
|
||||
{
|
||||
std::string query = SQL(
|
||||
DELETE FROM expedition_character_lockouts
|
||||
WHERE expire_time <= NOW();
|
||||
);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
{
|
||||
LogExpeditions("Failed to purge expired lockouts");
|
||||
}
|
||||
}
|
||||
|
||||
void Expedition::AddPlayer(ServerPacket* pack)
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerDzCommand_Struct*>(pack->pBuffer);
|
||||
|
||||
ClientListEntry* invited_cle = client_list.FindCharacter(buf->target_name);
|
||||
if (invited_cle && invited_cle->Server())
|
||||
{
|
||||
// continue in the add target's zone
|
||||
buf->is_char_online = true;
|
||||
invited_cle->Server()->SendPacket(pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add target not online, return to inviter
|
||||
ClientListEntry* inviter_cle = client_list.FindCharacter(buf->requester_name);
|
||||
if (inviter_cle && inviter_cle->Server())
|
||||
{
|
||||
inviter_cle->Server()->SendPacket(pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Expedition::MakeLeader(ServerPacket* pack)
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerDzCommand_Struct*>(pack->pBuffer);
|
||||
|
||||
// notify requester (old leader) and new leader of the result
|
||||
ZoneServer* new_leader_zs = nullptr;
|
||||
ClientListEntry* new_leader_cle = client_list.FindCharacter(buf->target_name);
|
||||
if (new_leader_cle && new_leader_cle->Server())
|
||||
{
|
||||
buf->is_char_online = true;
|
||||
new_leader_zs = new_leader_cle->Server();
|
||||
new_leader_zs->SendPacket(pack);
|
||||
}
|
||||
|
||||
// if old and new leader are in the same zone only send one message
|
||||
ClientListEntry* requester_cle = client_list.FindCharacter(buf->requester_name);
|
||||
if (requester_cle && requester_cle->Server() && requester_cle->Server() != new_leader_zs)
|
||||
{
|
||||
requester_cle->Server()->SendPacket(pack);
|
||||
}
|
||||
}
|
||||
|
||||
void Expedition::GetOnlineMembers(ServerPacket* pack)
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerExpeditionCharacters_Struct*>(pack->pBuffer);
|
||||
|
||||
// not efficient but only requested during caching
|
||||
char zone_name[64] = {0};
|
||||
std::vector<ClientListEntry*> all_clients;
|
||||
all_clients.reserve(client_list.GetClientCount());
|
||||
client_list.GetClients(zone_name, all_clients);
|
||||
|
||||
for (uint32_t i = 0; i < buf->count; ++i)
|
||||
{
|
||||
for (const auto& cle : all_clients)
|
||||
{
|
||||
if (cle && cle->CharID() == buf->entries[i].character_id)
|
||||
{
|
||||
buf->entries[i].character_zone_id = cle->zone();
|
||||
buf->entries[i].character_instance_id = cle->instance();
|
||||
buf->entries[i].character_online = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zoneserver_list.SendPacket(buf->sender_zone_id, buf->sender_instance_id, pack);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WORLD_EXPEDITION_H
|
||||
#define WORLD_EXPEDITION_H
|
||||
|
||||
class ServerPacket;
|
||||
|
||||
namespace Expedition
|
||||
{
|
||||
void PurgeEmptyExpeditions();
|
||||
void PurgeExpiredCharacterLockouts();
|
||||
void AddPlayer(ServerPacket* pack);
|
||||
void MakeLeader(ServerPacket* pack);
|
||||
void GetOnlineMembers(ServerPacket* pack);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -88,6 +88,7 @@ union semun {
|
||||
#include "queryserv.h"
|
||||
#include "web_interface.h"
|
||||
#include "console.h"
|
||||
#include "expedition.h"
|
||||
|
||||
#include "../common/net/servertalk_server.h"
|
||||
#include "../zone/data_bucket.h"
|
||||
@@ -429,6 +430,10 @@ int main(int argc, char** argv) {
|
||||
Timer PurgeInstanceTimer(450000);
|
||||
PurgeInstanceTimer.Start(450000);
|
||||
|
||||
LogInfo("Purging expired expeditions");
|
||||
Expedition::PurgeEmptyExpeditions(); //database.PurgeExpiredExpeditions();
|
||||
Expedition::PurgeExpiredCharacterLockouts();
|
||||
|
||||
LogInfo("Loading char create info");
|
||||
content_db.LoadCharacterCreateAllocations();
|
||||
content_db.LoadCharacterCreateCombos();
|
||||
@@ -599,6 +604,8 @@ int main(int argc, char** argv) {
|
||||
if (PurgeInstanceTimer.Check()) {
|
||||
database.PurgeExpiredInstances();
|
||||
database.PurgeAllDeletedDataBuckets();
|
||||
Expedition::PurgeEmptyExpeditions();
|
||||
Expedition::PurgeExpiredCharacterLockouts();
|
||||
}
|
||||
|
||||
if (EQTimeTimer.Check()) {
|
||||
|
||||
@@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "ucs.h"
|
||||
#include "queryserv.h"
|
||||
#include "world_store.h"
|
||||
#include "expedition.h"
|
||||
|
||||
extern ClientList client_list;
|
||||
extern GroupLFPList LFPGroupList;
|
||||
@@ -1355,6 +1356,44 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
cle->ProcessTellQueue();
|
||||
break;
|
||||
}
|
||||
case ServerOP_CZClientMessage:
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerCZClientMessage_Struct*>(pack->pBuffer);
|
||||
client_list.SendPacket(buf->character_name, pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_CZClientMessageString:
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerCZClientMessageString_Struct*>(pack->pBuffer);
|
||||
client_list.SendPacket(buf->character_name, pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ExpeditionCreate:
|
||||
case ServerOP_ExpeditionDeleted:
|
||||
case ServerOP_ExpeditionLeaderChanged:
|
||||
case ServerOP_ExpeditionLockout:
|
||||
case ServerOP_ExpeditionMemberChange:
|
||||
case ServerOP_ExpeditionMemberSwap:
|
||||
case ServerOP_ExpeditionMemberStatus:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ExpeditionGetOnlineMembers:
|
||||
{
|
||||
Expedition::GetOnlineMembers(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ExpeditionDzAddPlayer:
|
||||
{
|
||||
Expedition::AddPlayer(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ExpeditionDzMakeLeader:
|
||||
{
|
||||
Expedition::MakeLeader(pack);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LogInfo("Unknown ServerOPcode from zone {:#04x}, size [{}]", pack->opcode, pack->size);
|
||||
|
||||
Reference in New Issue
Block a user