mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 09:06:46 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d12a5b1b1 | |||
| 182327b385 | |||
| aa0ca88d9d | |||
| 103a37e762 | |||
| 34f19489d0 | |||
| c001060429 | |||
| 89be55254e | |||
| 2da6190950 | |||
| d5e024cc02 |
@@ -1,3 +1,35 @@
|
|||||||
|
## [22.45.1] 2/29/2024
|
||||||
|
|
||||||
|
### Character Creation
|
||||||
|
|
||||||
|
* Improved Random Name Generator ([#4081](https://github.com/EQEmu/Server/pull/4081)) @catapultam-habeo 2024-02-27
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Fix Server Rules Documentation Generation ([#4125](https://github.com/EQEmu/Server/pull/4125)) @Kinglykrab 2024-02-26
|
||||||
|
* Remove unnecessary stoptimer logs ([#4128](https://github.com/EQEmu/Server/pull/4128)) @Kinglykrab 2024-02-28
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add `#forage` command ([#4133](https://github.com/EQEmu/Server/pull/4133)) @joligario 2024-02-29
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash issue during database dump ([#4127](https://github.com/EQEmu/Server/pull/4127)) @Akkadius 2024-02-29
|
||||||
|
|
||||||
|
### Crash Fix
|
||||||
|
|
||||||
|
* D20 crash if mitigation average resulted in 0 ([#4131](https://github.com/EQEmu/Server/pull/4131)) @nytmyr 2024-02-29
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix forage returning first result from table ([#4130](https://github.com/EQEmu/Server/pull/4130)) @nytmyr 2024-02-29
|
||||||
|
* Who /all displays incorrect guild name ([#4123](https://github.com/EQEmu/Server/pull/4123)) @neckkola 2024-02-25
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Pet Owner Methods to Perl/Lua ([#4115](https://github.com/EQEmu/Server/pull/4115)) @Kinglykrab 2024-02-25
|
||||||
|
|
||||||
## [22.45.0] 2/24/2024
|
## [22.45.0] 2/24/2024
|
||||||
|
|
||||||
### Beacon
|
### Beacon
|
||||||
|
|||||||
@@ -575,8 +575,13 @@ void DatabaseDumpService::RemoveSqlBackup()
|
|||||||
{
|
{
|
||||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||||
if (File::Exists(file)) {
|
if (File::Exists(file)) {
|
||||||
|
try {
|
||||||
std::filesystem::remove(file);
|
std::filesystem::remove(file);
|
||||||
}
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
LogError("std::filesystem::remove err [{}]", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RemoveCredentialsFile();
|
RemoveCredentialsFile();
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -48,10 +48,10 @@ RULE_BOOL(Character, DeathKeepLevel, false, "Players can not drop below 0% exper
|
|||||||
RULE_BOOL(Character, UseDeathExpLossMult, false, "Setting to control whether DeathExpLossMultiplier or the code default is used: (Level x Level / 18.0) x 12000")
|
RULE_BOOL(Character, UseDeathExpLossMult, false, "Setting to control whether DeathExpLossMultiplier or the code default is used: (Level x Level / 18.0) x 12000")
|
||||||
RULE_BOOL(Character, UseOldRaceRezEffects, false, "Older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore")
|
RULE_BOOL(Character, UseOldRaceRezEffects, false, "Older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore")
|
||||||
RULE_INT(Character, CorpseDecayTime, 604800000, "Time after which the corpse decays (milliseconds) DEFAULT: 604800000 (7 Days)")
|
RULE_INT(Character, CorpseDecayTime, 604800000, "Time after which the corpse decays (milliseconds) DEFAULT: 604800000 (7 Days)")
|
||||||
RULE_INT( Character, EmptyCorpseDecayTime, 10800000, "Time after which an empty corpse decays (milliseconds) DEFAULT: 10800000 (3 Hours)")
|
RULE_INT(Character, EmptyCorpseDecayTime, 10800000, "Time after which an empty corpse decays (milliseconds) DEFAULT: 10800000 (3 Hours)")
|
||||||
RULE_INT(Character, CorpseResTime, 10800000, "Time after which the corpse can no longer be resurrected (milliseconds) DEFAULT: 10800000 (3 Hours)")
|
RULE_INT(Character, CorpseResTime, 10800000, "Time after which the corpse can no longer be resurrected (milliseconds) DEFAULT: 10800000 (3 Hours)")
|
||||||
RULE_INT( Character, DuelCorpseResTime, 600000, "Time before cant res corpse after a duel (milliseconds) DEFAULT: 600000 (10 Minutes)")
|
RULE_INT(Character, DuelCorpseResTime, 600000, "Time before cant res corpse after a duel (milliseconds) DEFAULT: 600000 (10 Minutes)")
|
||||||
RULE_INT( Character, CorpseOwnerOnlineTime, 30000, "How often corpse will check if its owner is online DEFAULT: 30000 (30 Seconds)")
|
RULE_INT(Character, CorpseOwnerOnlineTime, 30000, "How often corpse will check if its owner is online DEFAULT: 30000 (30 Seconds)")
|
||||||
RULE_BOOL(Character, LeaveCorpses, true, "Setting whether you leave a corpse behind")
|
RULE_BOOL(Character, LeaveCorpses, true, "Setting whether you leave a corpse behind")
|
||||||
RULE_BOOL(Character, LeaveNakedCorpses, false, "Setting whether you leave a corpse without items")
|
RULE_BOOL(Character, LeaveNakedCorpses, false, "Setting whether you leave a corpse without items")
|
||||||
RULE_INT(Character, MaxDraggedCorpses, 2, "Maximum number of corpses you can drag at once")
|
RULE_INT(Character, MaxDraggedCorpses, 2, "Maximum number of corpses you can drag at once")
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Build variables
|
// Build variables
|
||||||
// these get injected during the build pipeline
|
// these get injected during the build pipeline
|
||||||
#define CURRENT_VERSION "22.45.0-dev" // always append -dev to the current version for custom-builds
|
#define CURRENT_VERSION "22.45.1-dev" // always append -dev to the current version for custom-builds
|
||||||
#define LOGIN_VERSION "0.8.0"
|
#define LOGIN_VERSION "0.8.0"
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eqemu-server",
|
"name": "eqemu-server",
|
||||||
"version": "22.45.0",
|
"version": "22.45.1",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EQEmu/Server.git"
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
|||||||
+48
-64
@@ -599,79 +599,63 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) {
|
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) {
|
||||||
// creates up to a 10 char name
|
char newName[17] = {0};
|
||||||
char vowels[18]="aeiouyaeiouaeioe";
|
bool unique = false;
|
||||||
char cons[48]="bcdfghjklmnpqrstvwxzybcdgklmnprstvwbcdgkpstrkd";
|
|
||||||
char rndname[17]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
while (!unique) {
|
||||||
char paircons[33]="ngrkndstshthphsktrdrbrgrfrclcr";
|
std::string cons = "bcdfghjklmnpqrstvwxyz";
|
||||||
int rndnum=emu_random.Int(0, 75),n=1;
|
std::string vows = "aeou";
|
||||||
bool dlc=false;
|
std::string allVows = "aeiou";
|
||||||
bool vwl=false;
|
std::vector<std::string> endPhon = {"a", "e", "i", "o", "u", "os", "as", "us", "is", "y", "an", "en", "in", "on", "un"};
|
||||||
bool dbl=false;
|
|
||||||
if (rndnum>63)
|
std::random_device rd;
|
||||||
{ // rndnum is 0 - 75 where 64-75 is cons pair, 17-63 is cons, 0-16 is vowel
|
std::mt19937 gen(rd());
|
||||||
rndnum=(rndnum-61)*2; // name can't start with "ng" "nd" or "rk"
|
|
||||||
rndname[0]=paircons[rndnum];
|
std::uniform_int_distribution<int> lenDist(5, 10);
|
||||||
rndname[1]=paircons[rndnum+1];
|
std::uniform_int_distribution<int> firstCharDist(0, 1);
|
||||||
n=2;
|
std::uniform_int_distribution<int> consDist(0, cons.size() - 1);
|
||||||
|
std::uniform_int_distribution<int> vowDist(0, vows.size() - 1);
|
||||||
|
std::uniform_int_distribution<int> allVowDist(0, allVows.size() - 1);
|
||||||
|
std::uniform_int_distribution<int> endPhonDist(0, endPhon.size() - 1);
|
||||||
|
|
||||||
|
int len = 0;
|
||||||
|
memset(newName, 0, sizeof(newName));
|
||||||
|
|
||||||
|
if (firstCharDist(gen) == 0) {
|
||||||
|
newName[len++] = vows[vowDist(gen)];
|
||||||
|
newName[len++] = cons[consDist(gen)];
|
||||||
|
} else {
|
||||||
|
newName[len++] = cons[consDist(gen)];
|
||||||
|
newName[len++] = allVows[allVowDist(gen)];
|
||||||
}
|
}
|
||||||
else if (rndnum>16)
|
|
||||||
{
|
newName[0] = toupper(newName[0]);
|
||||||
rndnum-=17;
|
|
||||||
rndname[0]=cons[rndnum];
|
while (len < lenDist(gen) - 1) {
|
||||||
}
|
if (len % 2 == 0) {
|
||||||
else
|
newName[len++] = cons[consDist(gen)];
|
||||||
{
|
} else {
|
||||||
rndname[0]=vowels[rndnum];
|
newName[len++] = allVows[allVowDist(gen)];
|
||||||
vwl=true;
|
|
||||||
}
|
|
||||||
int namlen=emu_random.Int(5, 10);
|
|
||||||
for (int i=n;i<namlen;i++)
|
|
||||||
{
|
|
||||||
dlc=false;
|
|
||||||
if (vwl) //last char was a vowel
|
|
||||||
{ // so pick a cons or cons pair
|
|
||||||
rndnum=emu_random.Int(0, 62);
|
|
||||||
if (rndnum>46)
|
|
||||||
{ // pick a cons pair
|
|
||||||
if (i>namlen-3) // last 2 chars in name?
|
|
||||||
{ // name can only end in cons pair "rk" "st" "sh" "th" "ph" "sk" "nd" or "ng"
|
|
||||||
rndnum=emu_random.Int(0, 7)*2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // pick any from the set
|
|
||||||
rndnum=(rndnum-47)*2;
|
|
||||||
}
|
|
||||||
rndname[i]=paircons[rndnum];
|
|
||||||
rndname[i+1]=paircons[rndnum+1];
|
|
||||||
dlc=true; // flag keeps second letter from being doubled below
|
|
||||||
i+=1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // select a single cons
|
|
||||||
rndname[i]=cons[rndnum];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ // select a vowel
|
std::string end = endPhon[endPhonDist(gen)];
|
||||||
rndname[i]=vowels[emu_random.Int(0, 16)];
|
for (char c : end) {
|
||||||
|
if (len < 10) newName[len++] = c;
|
||||||
}
|
}
|
||||||
vwl=!vwl;
|
|
||||||
if (!dbl && !dlc)
|
if (database.CheckNameFilter(newName)) {
|
||||||
{ // one chance at double letters in name
|
std::string query = StringFormat("SELECT `name` FROM `character_data` WHERE `name` = '%s'", newName);
|
||||||
if (!emu_random.Int(0, i+9)) // chances decrease towards end of name
|
auto res = database.QueryDatabase(query);
|
||||||
{
|
if (res.Success() && res.RowCount() == 0) {
|
||||||
rndname[i+1]=rndname[i];
|
unique = true;
|
||||||
dbl=true;
|
|
||||||
i+=1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rndname[0]=toupper(rndname[0]);
|
|
||||||
NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer;
|
NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer;
|
||||||
memset(ngs->name,0,64);
|
memset(ngs->name, 0, 64);
|
||||||
strcpy(ngs->name,rndname);
|
strcpy(ngs->name, newName);
|
||||||
|
|
||||||
QueuePacket(app);
|
QueuePacket(app);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+11
-1
@@ -230,13 +230,23 @@ void WorldGuildManager::ProcessZonePacket(ServerPacket *pack) {
|
|||||||
case ServerOP_GuildChannel:
|
case ServerOP_GuildChannel:
|
||||||
case ServerOP_GuildURL:
|
case ServerOP_GuildURL:
|
||||||
case ServerOP_GuildMemberRemove:
|
case ServerOP_GuildMemberRemove:
|
||||||
case ServerOP_GuildMemberAdd:
|
|
||||||
case ServerOP_GuildSendGuildList:
|
case ServerOP_GuildSendGuildList:
|
||||||
case ServerOP_GuildMembersList:
|
case ServerOP_GuildMembersList:
|
||||||
{
|
{
|
||||||
zoneserver_list.SendPacketToBootedZones(pack);
|
zoneserver_list.SendPacketToBootedZones(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_GuildMemberAdd:
|
||||||
|
{
|
||||||
|
auto in = (ServerOP_GuildMessage_Struct *)pack->pBuffer;
|
||||||
|
auto guild = GetGuildByGuildID(in->guild_id);
|
||||||
|
if (!guild) {
|
||||||
|
BaseGuildManager::RefreshGuild(in->guild_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
zoneserver_list.SendPacketToBootedZones(pack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LogGuilds("Unknown packet {:#04x} received from zone??", pack->opcode);
|
LogGuilds("Unknown packet {:#04x} received from zone??", pack->opcode);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+1
-1
@@ -1005,7 +1005,7 @@ double Mob::RollD20(int offense, int mitigation)
|
|||||||
auto atk_roll = zone->random.Roll0(offense + 5);
|
auto atk_roll = zone->random.Roll0(offense + 5);
|
||||||
auto def_roll = zone->random.Roll0(mitigation + 5);
|
auto def_roll = zone->random.Roll0(mitigation + 5);
|
||||||
|
|
||||||
int avg = (offense + mitigation + 10) / 2;
|
int avg = std::max(1, (offense + mitigation + 10) / 2);
|
||||||
int index = std::max(0, (atk_roll - def_roll) + (avg / 2));
|
int index = std::max(0, (atk_roll - def_roll) + (avg / 2));
|
||||||
|
|
||||||
index = EQ::Clamp((index * 20) / avg, 0, 19);
|
index = EQ::Clamp((index * 20) / avg, 0, 19);
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ int command_init(void)
|
|||||||
command_add("find", "Search command used to find various things", AccountStatus::Guide, command_find) ||
|
command_add("find", "Search command used to find various things", AccountStatus::Guide, command_find) ||
|
||||||
command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", AccountStatus::QuestTroupe, command_fixmob) ||
|
command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", AccountStatus::QuestTroupe, command_fixmob) ||
|
||||||
command_add("flagedit", "Edit zone flags on your target. Use #flagedit help for more info.", AccountStatus::GMAdmin, command_flagedit) ||
|
command_add("flagedit", "Edit zone flags on your target. Use #flagedit help for more info.", AccountStatus::GMAdmin, command_flagedit) ||
|
||||||
|
command_add("forage", "Forage an item", AccountStatus::QuestTroupe, command_forage) ||
|
||||||
command_add("gearup", "Developer tool to quickly equip yourself or your target", AccountStatus::GMMgmt, command_gearup) ||
|
command_add("gearup", "Developer tool to quickly equip yourself or your target", AccountStatus::GMMgmt, command_gearup) ||
|
||||||
command_add("giveitem", "[itemid] [charges] - Summon an item onto your target's cursor. Charges are optional.", AccountStatus::GMMgmt, command_giveitem) ||
|
command_add("giveitem", "[itemid] [charges] - Summon an item onto your target's cursor. Charges are optional.", AccountStatus::GMMgmt, command_giveitem) ||
|
||||||
command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) ||
|
command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) ||
|
||||||
@@ -824,6 +825,7 @@ void command_bot(Client *c, const Seperator *sep)
|
|||||||
#include "gm_commands/find.cpp"
|
#include "gm_commands/find.cpp"
|
||||||
#include "gm_commands/fixmob.cpp"
|
#include "gm_commands/fixmob.cpp"
|
||||||
#include "gm_commands/flagedit.cpp"
|
#include "gm_commands/flagedit.cpp"
|
||||||
|
#include "gm_commands/forage.cpp"
|
||||||
#include "gm_commands/gearup.cpp"
|
#include "gm_commands/gearup.cpp"
|
||||||
#include "gm_commands/giveitem.cpp"
|
#include "gm_commands/giveitem.cpp"
|
||||||
#include "gm_commands/givemoney.cpp"
|
#include "gm_commands/givemoney.cpp"
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ void command_feature(Client *c, const Seperator *sep);
|
|||||||
void command_find(Client *c, const Seperator *sep);
|
void command_find(Client *c, const Seperator *sep);
|
||||||
void command_fixmob(Client *c, const Seperator *sep);
|
void command_fixmob(Client *c, const Seperator *sep);
|
||||||
void command_flagedit(Client *c, const Seperator *sep);
|
void command_flagedit(Client *c, const Seperator *sep);
|
||||||
|
void command_forage(Client* c, const Seperator* sep);
|
||||||
void command_gearup(Client *c, const Seperator *sep);
|
void command_gearup(Client *c, const Seperator *sep);
|
||||||
void command_giveitem(Client *c, const Seperator *sep);
|
void command_giveitem(Client *c, const Seperator *sep);
|
||||||
void command_givemoney(Client *c, const Seperator *sep);
|
void command_givemoney(Client *c, const Seperator *sep);
|
||||||
|
|||||||
+1
-1
@@ -89,7 +89,7 @@ uint32 ZoneDatabase::LoadForage(uint32 zone_id, uint8 skill_level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
forage_items[count] = e.Itemid;
|
forage_items[count] = e.Itemid;
|
||||||
forage_chances[count] = e.chance;
|
forage_chances[count] = e.chance + current_chance;
|
||||||
|
|
||||||
current_chance = forage_chances[count];
|
current_chance = forage_chances[count];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "../client.h"
|
||||||
|
|
||||||
|
void command_forage(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
c->ForageItem(true);
|
||||||
|
}
|
||||||
@@ -752,11 +752,7 @@ void QuestManager::stoptimer(const std::string& timer_name)
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (auto e = QTimerList.begin(); e != QTimerList.end(); ++e) {
|
for (auto e = QTimerList.begin(); e != QTimerList.end(); ++e) {
|
||||||
LogInfo("Current [{}] Timer [{}]", e->name, timer_name);
|
|
||||||
|
|
||||||
if (e->mob && e->mob == owner && e->name == timer_name) {
|
if (e->mob && e->mob == owner && e->name == timer_name) {
|
||||||
LogInfo("Matched [{}] Timer [{}]", e->name, timer_name);
|
|
||||||
|
|
||||||
if (has_stop_event) {
|
if (has_stop_event) {
|
||||||
if (owner->IsClient()) {
|
if (owner->IsClient()) {
|
||||||
parse->EventPlayer(EVENT_TIMER_STOP, owner->CastToClient(), timer_name, 0);
|
parse->EventPlayer(EVENT_TIMER_STOP, owner->CastToClient(), timer_name, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user