mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 08:21:28 +00:00
Implement tell queues
Default queue size 20 (World:TellQueueSize) This doe not play well with multiple sessions and a toon crashes and relogs Normal tells have issues as well.
This commit is contained in:
parent
3d6bb964df
commit
a2368b4ea7
@ -1,5 +1,12 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 09/18/2014==
|
||||||
|
demonstar55: Implement tell queues
|
||||||
|
Currently set to a limit of 20 by default (World:TellQueueSize) I was unable to hit the limit on live though (100+)
|
||||||
|
The required SQL nukes the old tell queue table, which may or may not be in your DB
|
||||||
|
Optional SQL adds the rule to the DB to allow easy of change
|
||||||
|
Note: this does not play well with multiple sessions with the same name on (crash and relog and have multiple sessions) but normal tells don't play well either
|
||||||
|
|
||||||
== 09/16/2014 ==
|
== 09/16/2014 ==
|
||||||
demonstar55: Implement spell formula 137 (BER AA Desperation)
|
demonstar55: Implement spell formula 137 (BER AA Desperation)
|
||||||
Uleat (NateDog): Fix for LoadBuffs() crash when a spell with a non-persistent Illusion effect was loaded.
|
Uleat (NateDog): Fix for LoadBuffs() crash when a spell with a non-persistent Illusion effect was loaded.
|
||||||
|
|||||||
@ -171,6 +171,7 @@ RULE_INT ( World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = R
|
|||||||
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
||||||
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
||||||
RULE_BOOL (World, IPLimitDisconnectAll, false)
|
RULE_BOOL (World, IPLimitDisconnectAll, false)
|
||||||
|
RULE_INT (World, TellQueueSize, 20)
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( Zone )
|
RULE_CATEGORY( Zone )
|
||||||
|
|||||||
@ -83,6 +83,7 @@
|
|||||||
#define ServerOP_QGlobalUpdate 0x0063
|
#define ServerOP_QGlobalUpdate 0x0063
|
||||||
#define ServerOP_QGlobalDelete 0x0064
|
#define ServerOP_QGlobalDelete 0x0064
|
||||||
#define ServerOP_DepopPlayerCorpse 0x0065
|
#define ServerOP_DepopPlayerCorpse 0x0065
|
||||||
|
#define ServerOP_RequestTellQueue 0x0066 // client asks for it's tell queues
|
||||||
|
|
||||||
#define ServerOP_RaidAdd 0x0100 //in use
|
#define ServerOP_RaidAdd 0x0100 //in use
|
||||||
#define ServerOP_RaidRemove 0x0101 //in use
|
#define ServerOP_RaidRemove 0x0101 //in use
|
||||||
@ -1237,6 +1238,10 @@ struct ReloadWorld_Struct{
|
|||||||
uint32 Option;
|
uint32 Option;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ServerRequestTellQueue_Struct {
|
||||||
|
char name[64];
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1
utils/sql/git/optional/2014_09_18_TellQueueRule.sql
Normal file
1
utils/sql/git/optional/2014_09_18_TellQueueRule.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'World:TellQueueSize', '20', 'Maximum tell queue size.');
|
||||||
1
utils/sql/git/required/2014_09_18_tellqueuesclean.sql
Normal file
1
utils/sql/git/required/2014_09_18_tellqueuesclean.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE `tellque`;
|
||||||
@ -93,6 +93,7 @@ ClientListEntry::~ClientListEntry() {
|
|||||||
Camp(); // updates zoneserver's numplayers
|
Camp(); // updates zoneserver's numplayers
|
||||||
client_list.RemoveCLEReferances(this);
|
client_list.RemoveCLEReferances(this);
|
||||||
}
|
}
|
||||||
|
tell_queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) {
|
void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) {
|
||||||
@ -233,6 +234,7 @@ void ClientListEntry::ClearVars(bool iAll) {
|
|||||||
pLFG = 0;
|
pLFG = 0;
|
||||||
gm = 0;
|
gm = 0;
|
||||||
pClientVersion = 0;
|
pClientVersion = 0;
|
||||||
|
tell_queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientListEntry::Camp(ZoneServer* iZS) {
|
void ClientListEntry::Camp(ZoneServer* iZS) {
|
||||||
@ -295,3 +297,21 @@ bool ClientListEntry::CheckAuth(uint32 id, const char* iKey, uint32 ip) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientListEntry::ProcessTellQueue()
|
||||||
|
{
|
||||||
|
if (!Server())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ServerPacket *pack;
|
||||||
|
auto it = tell_queue.begin();
|
||||||
|
while (it != tell_queue.end()) {
|
||||||
|
pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen((*it)->message) + 1);
|
||||||
|
memcpy(pack->pBuffer, *it, pack->size);
|
||||||
|
pack->Deflate();
|
||||||
|
Server()->SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
|
it = tell_queue.erase(it);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
#include "../common/md5.h"
|
#include "../common/md5.h"
|
||||||
//#include "../common/eq_packet_structs.h"
|
//#include "../common/eq_packet_structs.h"
|
||||||
#include "../common/servertalk.h"
|
#include "../common/servertalk.h"
|
||||||
|
#include "../common/rulesys.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
#define CLE_Status_Never -1
|
#define CLE_Status_Never -1
|
||||||
@ -80,6 +82,11 @@ public:
|
|||||||
inline const char* GetLFGComments() const { return pLFGComments; }
|
inline const char* GetLFGComments() const { return pLFGComments; }
|
||||||
inline uint8 GetClientVersion() { return pClientVersion; }
|
inline uint8 GetClientVersion() { return pClientVersion; }
|
||||||
|
|
||||||
|
inline bool TellQueueFull() const { return tell_queue.size() >= RuleI(World, TellQueueSize); }
|
||||||
|
inline bool TellQueueEmpty() const { return tell_queue.empty(); }
|
||||||
|
inline void PushToTellQueue(ServerChannelMessage_Struct *scm) { tell_queue.push_back(scm); }
|
||||||
|
void ProcessTellQueue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ClearVars(bool iAll = false);
|
void ClearVars(bool iAll = false);
|
||||||
|
|
||||||
@ -120,6 +127,9 @@ private:
|
|||||||
uint8 pLFGToLevel;
|
uint8 pLFGToLevel;
|
||||||
bool pLFGMatchFilter;
|
bool pLFGMatchFilter;
|
||||||
char pLFGComments[64];
|
char pLFGComments[64];
|
||||||
|
|
||||||
|
// Tell Queue -- really a vector :D
|
||||||
|
std::vector<ServerChannelMessage_Struct *> tell_queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*CLIENTENTRY_H_*/
|
#endif /*CLIENTENTRY_H_*/
|
||||||
|
|||||||
@ -441,41 +441,27 @@ bool ZoneServer::Process() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ClientListEntry* cle = client_list.FindCharacter(scm->deliverto);
|
ClientListEntry* cle = client_list.FindCharacter(scm->deliverto);
|
||||||
if (cle == 0 || cle->Online() < CLE_Status_Zoning || (cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) {
|
if (cle == 0 || cle->Online() < CLE_Status_Zoning ||
|
||||||
|
(cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) {
|
||||||
if (!scm->noreply)
|
if (!scm->noreply)
|
||||||
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "%s is not online at this time.", scm->to);
|
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0,
|
||||||
}
|
"%s is not online at this time.", scm->to);
|
||||||
else if (cle->Online() == CLE_Status_Zoning) {
|
} else if (cle->Online() == CLE_Status_Zoning) {
|
||||||
if (!scm->noreply)
|
if (!scm->noreply) {
|
||||||
{
|
if (cle->TellQueueFull()) {
|
||||||
time_t rawtime;
|
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0,
|
||||||
struct tm * timeinfo;
|
"%s's tell queue is full.", scm->to);
|
||||||
time ( &rawtime );
|
} else {
|
||||||
timeinfo = localtime ( &rawtime );
|
size_t struct_size = sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1;
|
||||||
char *telldate=asctime(timeinfo);
|
ServerChannelMessage_Struct *temp = (ServerChannelMessage_Struct *) new uchar[struct_size];
|
||||||
|
memset(temp, 0, struct_size); // just in case, was seeing some corrupt messages, but it shouldn't happen
|
||||||
std::string query = StringFormat("SELECT name FROM character_ WHERE name = '%s'",scm->deliverto);
|
memcpy(temp, scm, struct_size);
|
||||||
auto results = database.QueryDatabase(query);
|
temp->noreply = true;
|
||||||
if (!results.Success())
|
cle->PushToTellQueue(temp); // deallocation is handled in processing or deconstructor
|
||||||
break;
|
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0,
|
||||||
|
"Your message has been added to %s's queue.", scm->to);
|
||||||
if (results.RowCount() == 0) {
|
}
|
||||||
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "%s is not online at this time.", scm->to);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = StringFormat("INSERT INTO tellque "
|
|
||||||
"(Date, Receiver, Sender, Message) "
|
|
||||||
"VALUES('%s', '%s', '%s', '%s')",
|
|
||||||
telldate, scm->deliverto, scm->from, scm->message);
|
|
||||||
results = database.QueryDatabase(query);
|
|
||||||
if (results.Success())
|
|
||||||
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "Your message has been added to %s's queue.", scm->to);
|
|
||||||
else
|
|
||||||
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "%s is not online at this time.", scm->to);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to);
|
|
||||||
}
|
}
|
||||||
else if (cle->Server() == 0) {
|
else if (cle->Server() == 0) {
|
||||||
if (!scm->noreply)
|
if (!scm->noreply)
|
||||||
@ -1319,6 +1305,16 @@ bool ZoneServer::Process() {
|
|||||||
zoneserver_list.SendPacket(pack);
|
zoneserver_list.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_RequestTellQueue:
|
||||||
|
{
|
||||||
|
ServerRequestTellQueue_Struct* rtq = (ServerRequestTellQueue_Struct*) pack->pBuffer;
|
||||||
|
ClientListEntry *cle = client_list.FindCharacter(rtq->name);
|
||||||
|
if (!cle || cle->TellQueueEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
cle->ProcessTellQueue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
zlog(WORLD__ZONE_ERR,"Unknown ServerOPcode from zone 0x%04x, size %d",pack->opcode,pack->size);
|
zlog(WORLD__ZONE_ERR,"Unknown ServerOPcode from zone 0x%04x, size %d",pack->opcode,pack->size);
|
||||||
|
|||||||
@ -9834,6 +9834,8 @@ void Client::CompleteConnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
entity_list.RefreshClientXTargets(this);
|
entity_list.RefreshClientXTargets(this);
|
||||||
|
|
||||||
|
worldserver.RequestTellQueue(GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_KeyRing(const EQApplicationPacket *app)
|
void Client::Handle_OP_KeyRing(const EQApplicationPacket *app)
|
||||||
|
|||||||
@ -2180,3 +2180,19 @@ void WorldServer::HandleLFPMatches(ServerPacket *pack) {
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldServer::RequestTellQueue(const char *who)
|
||||||
|
{
|
||||||
|
if (!who)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ServerPacket* pack = new ServerPacket(ServerOP_RequestTellQueue, sizeof(ServerRequestTellQueue_Struct));
|
||||||
|
ServerRequestTellQueue_Struct* rtq = (ServerRequestTellQueue_Struct*) pack->pBuffer;
|
||||||
|
|
||||||
|
strn0cpy(rtq->name, who, sizeof(rtq->name));
|
||||||
|
|
||||||
|
SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,8 @@ public:
|
|||||||
void HandleLFGMatches(ServerPacket *pack);
|
void HandleLFGMatches(ServerPacket *pack);
|
||||||
void HandleLFPMatches(ServerPacket *pack);
|
void HandleLFPMatches(ServerPacket *pack);
|
||||||
|
|
||||||
|
void RequestTellQueue(const char *who);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void OnConnected();
|
virtual void OnConnected();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user