mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-23 04:18:41 +00:00
Compare commits
7 Commits
v1.1.2-rc1
...
v1.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 9733f04c9c | |||
| 7140a2054f | |||
| 1049e48aca | |||
| 33b79a3588 | |||
| f82699c39b | |||
| 15eaf4e6d1 | |||
| 7621882b4e |
@@ -1,8 +1,15 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 09/20/2014 ==
|
||||||
|
demonstar55: Fix crash in SendEnterWorld on illegally long names
|
||||||
|
demonstar55: The client only lets you enter 15 characters for your name (UF at least)
|
||||||
|
demonstar55: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false
|
||||||
|
KLS: #suspend and #ban now have required messages to record the reason for the ban/suspension.
|
||||||
|
|
||||||
== 09/19/2014 ==
|
== 09/19/2014 ==
|
||||||
demonstar55: Added Client::Tell_StringID (used in tell queue messages)
|
demonstar55: Added Client::Tell_StringID (used in tell queue messages)
|
||||||
demonstar55: Tell queues (and offline) messages now show correctly
|
demonstar55: Tell queues (and offline) messages now show correctly
|
||||||
|
demonstar55: Fix starting with capital check
|
||||||
|
|
||||||
== 09/18/2014==
|
== 09/18/2014==
|
||||||
demonstar55: Implement tell queues
|
demonstar55: Implement tell queues
|
||||||
|
|||||||
+2
-2
@@ -659,7 +659,7 @@ the name "name" or zero if no character with that name was found
|
|||||||
Zero will also be returned if there is a database error.
|
Zero will also be returned if there is a database error.
|
||||||
*/
|
*/
|
||||||
uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
|
uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
|
||||||
std::string query = StringFormat("SELECT account_id, id FROM character_ WHERE name='%s'", charname);
|
std::string query = StringFormat("SELECT account_id, id FROM character_ WHERE name='%s'", EscapeString(charname).c_str());
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
@@ -1140,7 +1140,7 @@ bool Database::CheckNameFilter(const char* name, bool surname)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// the minimum 4 is enforced by the client too
|
// the minimum 4 is enforced by the client too
|
||||||
if(!name || strlen(name) < 4 || strlen(name) > 64)
|
if(!name || strlen(name) < 4 || strlen(name) > 15)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ RULE_INT ( Spells, AI_PursueDetrimentalChance, 90) // Chance while chasing targe
|
|||||||
RULE_INT ( Spells, AI_IdleNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random)
|
RULE_INT ( Spells, AI_IdleNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random)
|
||||||
RULE_INT ( Spells, AI_IdleNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
|
RULE_INT ( Spells, AI_IdleNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
|
||||||
RULE_INT ( Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a beneficial spell on self or others.
|
RULE_INT ( Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a beneficial spell on self or others.
|
||||||
|
RULE_BOOL ( Spells, SHDProcIDOffByOne, true) // pre June 2009 SHD spell procs were off by 1, they stopped doing this in June 2009 (so UF+ spell files need this false)
|
||||||
|
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:SHDProcIDOffByOne', 'true', 'SHD procs are off by 1. Set true for pre-UF spell files, false for UF+.');
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `account` ADD COLUMN `ban_reason` TEXT NULL DEFAULT NULL AFTER `expansion`, ADD COLUMN `suspend_reason` TEXT NULL DEFAULT NULL AFTER `ban_reason`;
|
||||||
+9
-15
@@ -130,7 +130,7 @@ void Client::SendLogServer()
|
|||||||
|
|
||||||
void Client::SendEnterWorld(std::string name)
|
void Client::SendEnterWorld(std::string name)
|
||||||
{
|
{
|
||||||
char char_name[32]= { 0 };
|
char char_name[64] = { 0 };
|
||||||
if (pZoning && database.GetLiveChar(GetAccountID(), char_name)) {
|
if (pZoning && database.GetLiveChar(GetAccountID(), char_name)) {
|
||||||
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
|
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
|
||||||
eqs->Close();
|
eqs->Close();
|
||||||
@@ -471,8 +471,8 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
|
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
|
||||||
|
{
|
||||||
if (GetAccountID() == 0) {
|
if (GetAccountID() == 0) {
|
||||||
clog(WORLD__CLIENT_ERR,"Name approval request with no logged in account");
|
clog(WORLD__CLIENT_ERR,"Name approval request with no logged in account");
|
||||||
return false;
|
return false;
|
||||||
@@ -490,27 +490,21 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
|
|||||||
outapp->pBuffer = new uchar[1];
|
outapp->pBuffer = new uchar[1];
|
||||||
outapp->size = 1;
|
outapp->size = 1;
|
||||||
|
|
||||||
bool valid;
|
bool valid = false;
|
||||||
if(!database.CheckNameFilter(char_name)) {
|
if (!database.CheckNameFilter(char_name))
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
else if (islower(char_name[0]))
|
||||||
else if(char_name[0] < 'A' && char_name[0] > 'Z') {
|
|
||||||
//name must begin with an upper-case letter.
|
//name must begin with an upper-case letter.
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
else if (database.ReserveName(GetAccountID(), char_name))
|
||||||
else if (database.ReserveName(GetAccountID(), char_name)) {
|
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
|
||||||
else {
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
outapp->pBuffer[0] = valid ? 1 : 0;
|
outapp->pBuffer[0] = valid ? 1 : 0;
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
if(!valid) {
|
if (!valid)
|
||||||
memset(char_name, 0, sizeof(char_name));
|
memset(char_name, 0, sizeof(char_name));
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+67
-43
@@ -6258,36 +6258,49 @@ void command_stun(Client *c, const Seperator *sep)
|
|||||||
c->Message(0, "Usage: #stun [duration]");
|
c->Message(0, "Usage: #stun [duration]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void command_ban(Client *c, const Seperator *sep)
|
void command_ban(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char *query = 0;
|
char *query = 0;
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if(sep->arg[1][0] == 0)
|
if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0)
|
||||||
{
|
{
|
||||||
c->Message(0, "Usage: #ban [charname]");
|
c->Message(0, "Usage: #ban <charname> <message>");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
database.RunQuery(query, MakeAnyLenString(&query, "SELECT account_id from character_ where name = '%s'", sep->arg[1]), errbuf, &result);
|
auto account_id = database.GetAccountIDByChar(sep->arg[1]);
|
||||||
if(query)
|
|
||||||
{
|
std::string message;
|
||||||
safe_delete_array(query);
|
int i = 2;
|
||||||
|
while(1) {
|
||||||
|
if(sep->arg[i][0] == 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mysql_num_rows(result))
|
if(message.length() > 0) {
|
||||||
{
|
message.push_back(' ');
|
||||||
row = mysql_fetch_row(result);
|
}
|
||||||
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE account set status = -2 where id = %i", atoi(row[0])), errbuf, 0);
|
|
||||||
c->Message(13,"Account number %i with the character %s has been banned.", atoi(row[0]), sep->arg[1]);
|
|
||||||
|
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_FlagUpdate, 6);
|
message += sep->arg[i];
|
||||||
*((uint32*) pack->pBuffer) = atoi(row[0]);
|
++i;
|
||||||
*((int16*) &pack->pBuffer[4]) = -2;
|
}
|
||||||
worldserver.SendPacket(pack);
|
|
||||||
safe_delete(pack);
|
if(message.length() == 0) {
|
||||||
|
c->Message(0, "Usage: #ban <charname> <message>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(account_id > 0)
|
||||||
|
{
|
||||||
|
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE account set status = -2, ban_reason = '%s' where id = %i", EscapeString(message).c_str(), account_id), errbuf, 0);
|
||||||
|
c->Message(13, "Account number %i with the character %s has been banned with message: \"%s\"", account_id, sep->arg[1], message.c_str());
|
||||||
|
|
||||||
|
ServerPacket pack(ServerOP_FlagUpdate, 6);
|
||||||
|
*((uint32*)&pack.pBuffer[0]) = account_id;
|
||||||
|
*((int16*)&pack.pBuffer[4]) = -2;
|
||||||
|
worldserver.SendPacket(&pack);
|
||||||
|
|
||||||
Client *client = nullptr;
|
Client *client = nullptr;
|
||||||
client = entity_list.GetClientByName(sep->arg[1]);
|
client = entity_list.GetClientByName(sep->arg[1]);
|
||||||
@@ -6297,27 +6310,22 @@ void command_ban(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
ServerPacket pack(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
||||||
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer;
|
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*)pack.pBuffer;
|
||||||
strcpy(skp->adminname, c->GetName());
|
strcpy(skp->adminname, c->GetName());
|
||||||
strcpy(skp->name, sep->arg[1]);
|
strcpy(skp->name, sep->arg[1]);
|
||||||
skp->adminrank = c->Admin();
|
skp->adminrank = c->Admin();
|
||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(&pack);
|
||||||
safe_delete(pack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c->Message(13, "Character does not exist.");
|
c->Message(13, "Character does not exist.");
|
||||||
}
|
}
|
||||||
if(query)
|
|
||||||
{
|
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void command_suspend(Client *c, const Seperator *sep)
|
void command_suspend(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
@@ -6325,7 +6333,7 @@ void command_suspend(Client *c, const Seperator *sep)
|
|||||||
char *query = nullptr;
|
char *query = nullptr;
|
||||||
|
|
||||||
if((sep->arg[1][0] == 0) || (sep->arg[2][0] == 0))
|
if((sep->arg[1][0] == 0) || (sep->arg[2][0] == 0))
|
||||||
c->Message(0, "Usage: #suspend <charname> <days> (Specify 0 days to lift the suspension immediately)");
|
c->Message(0, "Usage: #suspend <charname> <days>(Specify 0 days to lift the suspension immediately) <message>");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int Duration = atoi(sep->arg[2]);
|
int Duration = atoi(sep->arg[2]);
|
||||||
@@ -6333,20 +6341,38 @@ void command_suspend(Client *c, const Seperator *sep)
|
|||||||
if(Duration < 0)
|
if(Duration < 0)
|
||||||
Duration = 0;
|
Duration = 0;
|
||||||
|
|
||||||
char *EscName = new char[strlen(sep->arg[1]) * 2 + 1];
|
std::string message;
|
||||||
|
if(Duration > 0) {
|
||||||
|
int i = 3;
|
||||||
|
while(1) {
|
||||||
|
if(sep->arg[i][0] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
database.DoEscapeString(EscName, sep->arg[1], strlen(sep->arg[1]));
|
if(message.length() > 0) {
|
||||||
|
message.push_back(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
message += sep->arg[i];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.length() == 0) {
|
||||||
|
c->Message(0, "Usage: #suspend <charname> <days>(Specify 0 days to lift the suspension immediately) <message>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int AccountID;
|
int AccountID;
|
||||||
|
|
||||||
if((AccountID = database.GetAccountIDByChar(EscName)) > 0)
|
if((AccountID = database.GetAccountIDByChar(sep->arg[1])) > 0)
|
||||||
{
|
{
|
||||||
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE `account` SET `suspendeduntil` = DATE_ADD(NOW(), INTERVAL %i DAY)"
|
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE `account` SET `suspendeduntil` = DATE_ADD(NOW(), INTERVAL %i DAY), "
|
||||||
" WHERE `id` = %i", Duration, AccountID), errbuf, 0);
|
"suspend_reason = '%s' WHERE `id` = %i", Duration, EscapeString(message).c_str(), AccountID), errbuf, 0);
|
||||||
|
|
||||||
if(Duration)
|
if(Duration)
|
||||||
c->Message(13,"Account number %i with the character %s has been temporarily suspended for %i day(s).", AccountID, sep->arg[1],
|
c->Message(13, "Account number %i with the character %s has been temporarily suspended for %i day(s) with the message: \"%s\"", AccountID, sep->arg[1],
|
||||||
Duration);
|
Duration, message.c_str());
|
||||||
else
|
else
|
||||||
c->Message(13, "Account number %i with the character %s is no longer suspended.", AccountID, sep->arg[1]);
|
c->Message(13, "Account number %i with the character %s is no longer suspended.", AccountID, sep->arg[1]);
|
||||||
|
|
||||||
@@ -6358,22 +6384,20 @@ void command_suspend(Client *c, const Seperator *sep)
|
|||||||
BannedClient->WorldKick();
|
BannedClient->WorldKick();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
ServerPacket pack(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
||||||
ServerKickPlayer_Struct* sks = (ServerKickPlayer_Struct*) pack->pBuffer;
|
ServerKickPlayer_Struct* sks = (ServerKickPlayer_Struct*)pack.pBuffer;
|
||||||
|
|
||||||
strn0cpy(sks->adminname, c->GetName(), sizeof(sks->adminname));
|
strn0cpy(sks->adminname, c->GetName(), sizeof(sks->adminname));
|
||||||
strn0cpy(sks->name, sep->arg[1], sizeof(sks->name));
|
strn0cpy(sks->name, sep->arg[1], sizeof(sks->name));
|
||||||
sks->adminrank = c->Admin();
|
sks->adminrank = c->Admin();
|
||||||
|
|
||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(&pack);
|
||||||
|
|
||||||
safe_delete(pack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
else {
|
||||||
c->Message(13, "Character does not exist.");
|
c->Message(13, "Character does not exist.");
|
||||||
|
}
|
||||||
safe_delete_array(EscName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -5598,28 +5598,29 @@ void Mob::CheckNumHitsRemaining(uint8 type, uint32 buff_slot, uint16 spell_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//for some stupid reason SK procs return theirs one base off...
|
//for some stupid reason SK procs return theirs one base off...
|
||||||
uint16 Mob::GetProcID(uint16 spell_id, uint8 effect_index) {
|
uint16 Mob::GetProcID(uint16 spell_id, uint8 effect_index)
|
||||||
|
{
|
||||||
|
if (!RuleB(Spells, SHDProcIDOffByOne)) // UF+ spell files
|
||||||
|
return spells[spell_id].base[effect_index];
|
||||||
|
|
||||||
|
// We should actually just be checking if the mob is SHD, but to not force
|
||||||
|
// custom servers to create new spells, we will still do this
|
||||||
bool sk = false;
|
bool sk = false;
|
||||||
bool other = false;
|
bool other = false;
|
||||||
for(int x = 0; x < 16; x++)
|
for (int x = 0; x < 16; x++) {
|
||||||
{
|
|
||||||
if (x == 4) {
|
if (x == 4) {
|
||||||
if (spells[spell_id].classes[4] < 255)
|
if (spells[spell_id].classes[4] < 255)
|
||||||
sk = true;
|
sk = true;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
if (spells[spell_id].classes[x] < 255)
|
if (spells[spell_id].classes[x] < 255)
|
||||||
other = true;
|
other = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sk && !other)
|
if (sk && !other)
|
||||||
{
|
return spells[spell_id].base[effect_index] + 1;
|
||||||
return(spells[spell_id].base[effect_index] + 1);
|
else
|
||||||
}
|
return spells[spell_id].base[effect_index];
|
||||||
else{
|
|
||||||
return(spells[spell_id].base[effect_index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::TryDivineSave()
|
bool Mob::TryDivineSave()
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ void WorldServer::Process() {
|
|||||||
else if (scm->queued == 2) // tell queue was full
|
else if (scm->queued == 2) // tell queue was full
|
||||||
client->Tell_StringID(QUEUE_TELL_FULL, scm->to, scm->message);
|
client->Tell_StringID(QUEUE_TELL_FULL, scm->to, scm->message);
|
||||||
else if (scm->queued == 3) // person was offline
|
else if (scm->queued == 3) // person was offline
|
||||||
client->Message_StringID(MT_TellEcho, TOLD_NOT_ONLINE);
|
client->Message_StringID(MT_TellEcho, TOLD_NOT_ONLINE, scm->to);
|
||||||
else // normal stuff
|
else // normal stuff
|
||||||
client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, scm->language, scm->message);
|
client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, scm->language, scm->message);
|
||||||
if (!scm->noreply && scm->chan_num != 2) { //dont echo on group chat
|
if (!scm->noreply && scm->chan_num != 2) { //dont echo on group chat
|
||||||
|
|||||||
Reference in New Issue
Block a user