2019

Where all the cool new stuff goes

10/5/2019

Uleat

Bot AI and Command Changes

  • Added two new 'Owner Option' features:

    1. altcombat - enabled, bots aggro based on owner's attack state; disabled, pet-like behavior

    2. autodefend - enabled, bots defend owner on aggro; disabled, no action taken

  • Renamed bot command ^hold to ^suspend (same action and counter to ^release)

  • Repurposed bot command ^hold to override all attack actions

  • Reworked ^guard to allow all 'normal' actions and for bots to return to their guard spots when idle

  • Bot command ^attack should now work as intended - with noted exceptions above

  • Revamped bot command ^pull:

    1. Pulling bot will travel to entity, gain aggro, then return to home position

    2. Aggro is attained through the use of the low-damage spell 'Throw Stone'

    3. Pulling candidacy is currently determined by a 4-tier ranking system

9/30/2019

Akkadius

Login Server Changes

  • Auto convert insecure world server admin passwords during the world authentication process

  • Add CLI support for updating world admin account world-admin:update --username=* --password=*

9/19/2019

Kinglykrab

Fixed Maximum Status value in entity_list.QueueClientsStatus.

  • Maximum Status of 250 was causing status levels 251 to 254 to be excluded from the queue.

9/17/2019

Akkadius

Login Server Overhaul

There's a few weeks of solid work wrapped in this update, you can review the changes in this pull request if you wish

Login Server Highlights

  • Database schema includes all new tables, to migrate see migration reference below

  • All new config file JSON format login.json found in ./loginserver/login_util/login.json

  • Now has an embedded Web API on port 6000 by default, details can be found at Loginserver API

  • Now has a rich embedded CLI interface, details found at Login CLI Interface

  • Now uses Scrypt for encryption which you can learn more about here

  • Now automatically updates weak encryption methods during client login to the latest encryption method (Scrypt) in use on the fly

  • Now properly supports string escaping in all database calls

  • Now no longer requires you to specify a Local LAN subnet in the config to detect LAN world servers and LAN player connections. The server now can intelligently detect RFC1918 local LAN subnets in the requests to properly mark both World Server connections and Player connections appropriately (Plug-N-Play)

  • A production and stage/testing server of the same long name / short name pair can now live together as long as one world is registered

  • Code is heavily cleaned up, many parts not perfect but far far improved

  • Many many bug fixes, stability improvements

  • Improvements made to world -> loginserver and loginserver -> world reconnects through keep-alive. If a world is disconnected it will properly picked up by world and vise versa. Which also allows the chance for the process to reconnect sooner because it knows it had a connection die instead of waiting for it to be told

  • Improvements made to world -> zone and zone -> world disconnects through keep-alive for example on Linux if world had been killed, it would not gracefully reconnect to all zone processes and vise versa

Migrating a Legacy Login Server

To migrate your Legacy login server, follow this guide Migrating your Legacy Loginserver

Log System Enhancements

  • The popular C++ library FMT is now powering most of our logging FMT Library

  • Migrated thousands of log calls to use now simplified log aliases, the most recent up to date list can be found here

The main reason for these changes is that it simplifies the use of logging by developers, it also makes it far easier to create logging statements because we no longer need to look up printf codes to match variable types going into logging calls as our FMT library that we are using will detect the types at runtime

Using the category log aliases also heavily simplifies the amount of verbosity that goes into simply typing the log statements to begin with

We have *Detail* level aliases, but we are trying to keep from using detail in categorized logging, if you are using detail you probably either need to use another specialized category. The only time detail should ever really be used is if it is incredibly spammy to the rest of the logging in the same category

Old Logging Style
New Logging Style
New Log Aliases
Log(Logs::General, Logs::ZoneServer, "Connecting to MySQL... ");
Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf);
Log(Logs::Detail, Logs::Spells, "Bard song %d started: slot %d, target id %d", bardsong, bardsong_slot, bardsong_target_id);
Log(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", hit.damage_done);
LogInfo("Connecting to MySQL... ");
LogError("Failed to connect to database: Error: {}", errbuf);
LogSpells("Bard song [{}] started: slot [{}], target id [{}]", bardsong, (int) bardsong_slot, bardsong_target_id);
LogCombat("Final damage after all reductions: [{}]", hit.damage_done);
LogEmergency
LogAlert
LogCritical
LogError
LogWarning
LogNotice
LogInfo
LogDebug
LogAA
LogAADetail
LogAI
LogAIDetail
LogAggro
LogAggroDetail
LogAttack
LogAttackDetail
LogPacketClientServer
LogPacketClientServerDetail
LogCombat
LogCombatDetail
LogCommands
LogCommandsDetail
LogCrash
LogCrashDetail
LogDoors
LogDoorsDetail
LogGuilds
LogGuildsDetail
LogInventory
LogInventoryDetail
LogLauncher
LogLauncherDetail
LogNetcode
LogNetcodeDetail
LogNormal
LogNormalDetail
LogObject
LogObjectDetail
LogPathing
LogPathingDetail
LogQSServer
LogQSServerDetail
LogQuests
LogQuestsDetail
LogRules
LogRulesDetail
LogSkills
LogSkillsDetail
LogSpawns
LogSpawnsDetail
LogSpells
LogSpellsDetail
LogTCPConnection
LogTCPConnectionDetail
LogTasks
LogTasksDetail
LogTradeskills
LogTradeskillsDetail
LogTrading
LogTradingDetail
LogTribute
LogTributeDetail
LogMySQLError
LogMySQLErrorDetail
LogMySQLQuery
LogMySQLQueryDetail
LogMercenaries
LogMercenariesDetail
LogQuestDebug
LogQuestDebugDetail
LogLoginserver
LogLoginserverDetail
LogClientLogin
LogClientLoginDetail
LogHeadlessClient
LogHeadlessClientDetail
LogHPUpdate
LogHPUpdateDetail
LogFixZ
LogFixZDetail
LogFood
LogFoodDetail
LogTraps
LogTrapsDetail
LogNPCRoamBox
LogNPCRoamBoxDetail
LogNPCScaling
LogNPCScalingDetail
LogMobAppearance
LogMobAppearanceDetail
LogStatus
LogStatusDetail

RFC5424 Log Categories

RFC5424 Log Categories have been introduced, they are meant to simplify the use of common logging scenarios that don't require specific categories

LogEmergency
LogAlert
LogCritical
LogError
LogWarning
LogNotice
LogInfo
LogDebug

When using any of these macros, logging output will append the process name before the message itself, thus deprecating process specific categories

Example

[WorldServer] [Info] Purging expired data buckets
[WorldServer] [Info] Loading zones
[WorldServer] [Info] Clearing groups
[WorldServer] [Info] Clearing raids
[WorldServer] [Info] Clearing inventory snapshots
[WorldServer] [Info] Loading items
[WorldServer] [Info] Loading skill caps
[WorldServer] [Info] Loading guilds
[LoginServer] [Warning] Remote address was null, defaulting to stream address 127.0.0.1

9/4/2019

Uleat

Added code to restore rule notes to their original values

9/2/2019

Uleat

Added code to inject new rules into the 'default' ruleset and remove orphaned rules from all rulesets

  • New rules are only added using the 'default' ruleset - Other rulesets will need to be added manually or through in-game updates

  • Rule notes are now loaded into the system's hard-coded entries and will now propagate properly into database updates

  • Defunct rules will have their orphaned entries removed from the 'rule_values' table for the all rulesets

8/30/2019

Uleat

Added code to inject new commands and remove orphaned commands from both command systems

  • New commands are added with their status ('access') set to the server default value - no aliases are defined

  • Defunct commands will have their orhpaned entries removed from the command settings table for each system

8/16/2019

Akkadius

Simplified Roambox Usage and Improve Roambox AI

Improved roam-box AI

New Roambox GM Commands

  • Implemented command #roambox set [move_delay]

  • Implemented command #roambox remove

New Roambox Quest API Calls

$npc->SetSimpleRoamBox(box_size, [move_distance], [move_delay]);
NPC:SetSimpleRoamBox(box_size, [move_distance], [move_delay]);

New GM Commands!

  • Spawngroup data now hot reloads on #repop

  • Command #npceditmass now lists column options when one isn't properly specified

  • Implemented command #spawneditmass [search] [option] with options [respawn_time] currently implemented

8/11/2019

Akkadius

Bulk Editing GM Commands! #npceditmass

Added bulk edit command #npceditmass [column-to-search] [column-search-value] [change-column] [change-value]

#findzone Enhancements!

  • Modified #findzone to include clickable saylinks to both regular zone (if able) and private gmzone instances

  • Added command #findzone [expansion-number] expansion to show zones via expansion

8/6/2019

Akkadius Optimizations to movement updates to eliminate ghosting possibilities in larger zones

7/22/2019

Uleat

Windows Build Work

Added script `vcxproj_dependencies.py` a script to help determine conflicting project dependencies (alpha-stage)

7/10/2019

Akkadius

NPC Flymode Changes - Commands and DB Changes

  • Add #npcedit flymode [0 = ground, 1 = flying, 2 = levitate, 3 = water, 4 = floating]

  • Added "flymode" to npc_types database table

7/3/2019

Akkadius/KLS

Packet Compress, CPU, Position Update Optimizations

  • Optimizations to packet updates introduced back into the source post network code overhaul

  • Optimizations made to position update packets by sending updates far less frequently when not in line with zone:max_movement_update_range

  • Optimizations made to position updates in respect to the much higher resolution of navmesh path finding that we were using. We have cut down on the resolution of path finding / updating so that we reduce the CPU overhead of path*finding and subsequent client update packets that get generated this action

  • Optimization made by adjusting ZLIB compression rate that was accidentally set to a compression level of 4 a long time ago

Added #netstats Command

  • Added #netstats admin command to troubleshoot connection issues in detail

Zone Process now Has an Embedded Websocket Server

Websocket server is now available in zone and is bound to the same UDP port that the zoneserver listens on

  • Currently implemented websocket API calls at the zone level

    • get_packet_statistics

    • get_opcode_list

    • get_npc_list_detail

    • get_door_list_detail

    • get_corpse_list_detail

    • get_object_list_detail

    • get_mob_list_detail

    • get_client_list_detail

    • get_zone_attributes

    • get_logsys_categories

    • set_logging_level

EQEmu Server Build Changes - Using Submodules

6/24/2019

Uleat

Reworked BotDatabase Into a Functional Add-On for ZoneDatabase

  • Eliminated the database connection associated with class BotDatabase

  • All behaviors remain the same with the exception of the calling object

  • To invoke a BotDatabase function, use database.botdb rather than botdb

3/1/2019

Noudess

Major Faction Conversion to Use Real Client Data

Pull request #802 New min/max personal faction per faction. Use of actual client mods for race/class/deity.

This PR involves major changes to your database and server operators quests

The clients recently exposed raw data included

  • Min/Max personal faction for each faction

  • Actual faction id the client uses for each faction

  • Actual mods that come into play when a PC cons an opponent that determine your overall con to that faction

Approach

The approach I took resulted in minimal change to the code base. I did alter the code to enforce the new validated min/max from the client. This min/max applies to personally earned faction. So if a faction has a min of 0 and a max of 2000, that means your personally earned value can never go below 0 or over 2000. The actual con, will, however often do so because of class/race/deity modifications. I also changed the con ranges, per Mackal's data that was proven to be accurate

Faction

Value

Ally

1100+

Warmly

750 to 1099

Kindly

500 to 749

Amiable

100 to 499

Indifferent

0 to 99

Apprehensive

-1 to -100

Dubious

-101 to -500

Threateningly

-501 to -750

Ready to Attack

-751

The above means that dubious is a much smaller range now. For that reason the scripts modify any custom faction base values to put them in the same range, hopefully as the creators of the custom factions intended.

Also to be noted as characters that have a faction between -501 and -700 wont be dubious anymore, they will be threateningly. This is expected with the new ranges, but might take players by surprise as the old ranges we used were more liberal but were incorrect.

The database is changed extensively, but really only content. We're translating faction_list to use the clients ids. As such every place a faction_is is used, namely (see below) are being converted

  • faction_list

  • faction_list_mod

  • npc_faction (primary_faction field only)

  • npc_faction_entries (faction_id field only)

  • faction_values

Quests will also automatically be adjusted. This MUST be done after the PR sql and before starting the server. This is automated by eqemu_server.pl (or starting world)

Be assured, custom factions that you may have created, or obsolete or duplicate factions in our original faction_list, that you may have used, will be preserved. Anything that does not map directly is being moved to the 5000 range in faction_list and any references are corrected to point there.

A great example of this is Ebon Mask and Hall of the Ebon Mask. Many PEQ DB style servers have both of these. Some have used one, some the other. We map Ebon Mask to the clients Ebon mask and the Hall of the Ebon Mask gets moved to the 5000 range, and all its references are preserved. However, if you would like to make proper use of client mobs to Ebon mask, or other factions that have duplicitous entries, I recommend you manually move to using the correct one. In that way all of the new raw data mapped in from the client into faction_list_mod will get used instead of what your db had before these values were known.

In my experience converting 4 different server's data, there are only about 20 factions moved into the 5000 range.

This PR has only 1 new, permanent table faction_base_data, which is taken right from the client. The base field is left in case you want to mod your server, but we are very sure that the client doesn't use a base. It uses global mods to race or class for this as you'll see in the new faction_list_mod

The PR makes many backup tables, and two mapping tables that are used during the conversion process to fix quests. This table was hand created by analysis. This table serves no purpose after conversion except an audit trail if we see any issues.

I will release a new PR that will clean up all these backups and temporary tables in about a month.

2/7/2019

Uleat

Merc and Bots Now Use the Same Stance Standard

  • Both classes will now use the same stance standard

  • Pushed stance types up to EQEmu::constants

2/4/2019

Uleat

Added GM-Command "profanity"

  • This is a server-based tool for redacting any language that an admin deems as profanity (socially unacceptable within their community)

  • Five options are available under this command

    • list shows the current list of banned words

    • clears the current list of banned words

    • add adds to the banned word list

    • del deletes from the banned word list

    • reload forces a reload of the banned word list

  • All actions are immediate and a world broadcast refreshes other active zones

  • The system is in stand-by when the list is empty..just add a word to the list to begin censorship

  • Redaction only occurs on genuine occurrences of any banned word

    • Banned words are replaced with a series of '' characters

    • Compounded words are ignored to avoid issues with allowed words containing a banned substring

    • If 'test' is banned, 'testing' will not be banned .. it must be added separately

  • Extreme care should be exercised when adding words to the banned list

    • Quest failures and limited social interactions may alienate players if they become inhibiting

    • System commands are allowed to be processed before redaction occurs in the 'say' channel

  • A longer list requires more clock cycles to process - so, try to keep them to the most offensible occurrences

  • Fix for bots ceasing combat when their 'follow me' mob dies

    • Bots will revert to their client leash owner (bot owner or client group leader) when their FollowID() mob is no longer valid

    • Combat will no longer be interrupted in these cases

    • Does not apply to bot owner death

1/26/2019

Uleat

Fix for class Bot not honoring NPCType data reference

  • Fixes bots not moving on spawn/grouping issue

  • Report any issues with non movement-related behavior

1/24/2019

Uleat

Extended Server SpellBook Entries to RoF2 Standard...

...and added per-client restriction of spell id max

  • Bumped server spellbook entry capacity to 720 spells

  • Server keeps all 'learned' spells as found

    • Access is limited by the clients' limitations of spellbook capacities and max spell ids

    • This is done to avoid losing spells by switching from newer clients to older ones

    • Existing behavior is kept in place for illegal access conditions

  • Each client is still restricted to its spellbook capacity (400, 480, 480, 720, 720, 720 - respectively)

  • Each client is restricted to its max supported spell id (9999, 15999, 23000, 28000, 45000, 45000 respectively)

  • Please report any abnormal behavior so it may be addressed

  • Removed server-side checksum of player profile..wasted calculation since it's performed again in all translators

1/20/2019

Uleat

Added "spells" Entry to EQDictionary

Akkadius

Extended GM-Command #goto, New #who, #gmzone Commands

  • [Command] Extended #goto via #goto [playername]

    • This will work cross zone, cross instance, in zone etc.

    • It works on top of the original #goto (target) and #goto x y z

  • [Command] Implemented server side #who

    • Searches can be filtered by

      • Account Name

      • Base Class Name

      • Guild Name

      • IP

      • Player Name

      • Race Name

      • Zone Short Name

    • Features a clickable (Goto) saylink that will bring you directly to a player regardless of

      whether or not they are in an instance

  • [Command] Implemented: #gmzone [zone_short_name] [zone_version=0] [identifier=gmzone]

    • Zones to a private GM instance

Fixes to NPC's Ghosting at Zone Entrances

Fix issue where NPC's clip into the world and the client interprets them at coordinates 0,0,0

This issue would show itself when NPC's would bunch up by a zone-in

1/15/2019

Uleat

Activated Per-Expansion Support for Active Inventory Slot Addressing

  • Server honors expansions that alter bank size and power source, general9 and general10 slots

  • Server honors gm flag behaviors for the active inventory slots of each client

1/11/2019

Uleat

Modified Rules System to Ignore All Runtime Modifications...

of 'World:ExpansionSettings' and 'World:UseClientBasedExpansionSettings' fields.

  • These fields are no longer allowed to be changed during server runtime through the command system

  • Major synchronization issues between server and clients result when these fields are altered in-game

  • It is not recommended to update these fields via sql queries while the server is in operation

  • Failure to observe these warnings will result in abhorant behavior and loss of items

  • Modify these fields during server operation at your own risk!

1/4/2019

Akkadius

Global base scaling data has been updated in new database binary revision

1/1/2019

Akkadius

New DevTool Commands, Categories, Logging and Scaling

  • Logging: Added new logging category MobAppearance

  • DevTools Proximity show of NPC now shows a "Path finding" circle around the proximity nodes to more clearly display

  • Scaling Global base scaling data now refreshes from the database on #repop

  • Commands Implemented command #killallnpcs [npc_name] for testing, leave blank for all attackable NPC's

NPC and Player Textures

  • Textures that have been changed with #wearchange / #wc or any wearchange quest script call will now stick for new clients entering a zone

  • Weapon models for NPCs changed using wearchange will stick as well during combat and when new clients enter the zone

  • The above changes allow for customization of a zone and NPC's without needing static data configured on npc_types table data and allows for much more customization options

Implemented Ornamentation Quest API Calls

Perl
Lua
$client->SetPrimaryWeaponOrnamentation(uint32 model_id);
$client->SetSecondaryWeaponOrnamentation(uint32 model_id);
client:SetPrimaryWeaponOrnamentation(uint32 model_id);
client:SetSecondaryWeaponOrnamentation(uint32 model_id);

Both of these API calls persist an ornamentation to the weapon in the inventory table and will load both in character select and cross zone