The other item sources live marked in AddItemToInventoryClientSync's extra
info, with the keys and values live sent:
- mission and achievement rewards: _Metric_Mission_ID_Int and source LOT 1,
the player (225 of 225 live rewards)
- activity rewards: _Metric_Activity_ID_Int and the activity object's LOT
- vendor purchases: the vendor's LOT and _Metric_Currency_Delta_Int, the coins
paid as a negative number (left out when the item costs no coins)
- mail attachments: _Metric_Mail_ID_Int64
- traded items: _Metric_Transaction_ID_Int64, the trade's ID
Loot::GiveLoot gains overloads that pass them on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live sent quickbuild completion loot (about 190 samples) and the dragon,
BONS, spider queen and Frakjaw chest and wishing well rewards with the
player who earned them as the DropClientLoot source and owner,
use_position true and the spawn position at the object. DLU used the object
as the source, so use_position was false.
DropActivityLoot now uses the player as the source by default. The growing
flowers and the VE mission console have no live samples and keep the
object as the source.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ActivityRewards coins were always read from CurrencyTable npcminlevel 1.
Live used the reward row's ChallengeRating as the npcminlevel, and level 1
when the currency index has no row for that level:
- FV foot races (ChallengeRating 4, index 1) gave 36 and 48 coins, which
only level 4 (30-50) fits; level 1 is 3-5.
- Frakjaw's chest (activity 58, ChallengeRating 6) gave 250 each to a team
of 2: its currency indices 123-126 only have a level 6 row (500), so DLU
gave nothing.
- Quickbuilds, wishing wells and chests have ChallengeRating 1; survival
and the shooting galleries have ratings with no row and keep level 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DLU sent a DropClientLoot for 0 coins with every drop whose coin range was
0, such as item-only smashables and scripted drops. None of the 3163 live
currency drops was for 0 coins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live sent a drop's currency DropClientLoot before its item drops in 1498 of
1502 live drop groups that had both. DLU sent the coins last.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live DropClientLoot (12,501 decoded): use_position is set only when a
player is the source (1,432, all activity rewards such as the dragon,
Frakjaw and BONS chests); drops from enemies, smashables and chests
leave it clear, so the client spawns the loot at the source object as
it sees it and falls back to spawn_position only if that object is
gone (LWODestroyableComponent::GetLootSpawnPos). Coins land where they
spawn (final = spawn in all 3,158 coin drops); items land 10 units
away (median 9.998, uniform direction) at spawn height. DLU always set
use_position and scattered everything 4.2 units away.
Inferred: the 10-unit rule for player-sourced items (live spread there
ranges 0-58 units, source unknown).
Check: kill enemies and smash crates: coins pop out of the object,
items fly about 10 units away; open an activity chest (e.g. after a
dragon or Frakjaw) and the loot still appears around you.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live filled SetCurrency's source fields per source type (16,816 decoded
live SetCurrency): pickups carry the position the client picked the
coins up at (the one in its PickupCurrency) and no source; mission,
achievement and activity rewards name the player (object and LOT 1);
vendor buys, sells and buybacks name the vendor and its LOT; trades
carry the trade ID; death, mail and everything else name nothing. No
live SetCurrency sets loot_type. DLU wrote a present source LOT of 0,
no object and a zero position for all of them.
The position is the one the client uses: for pickups it projects it to
the screen as the start of the coin counter animation
(LWOCharacterComponent::SetCurrency), so it started from the world
origin before. PickupCurrency now reads that position (the client
always sends it). The trade ID is an 8-byte object ID in the client;
DLU declared it 4 bytes, which only never broke because it was never
set.
Check: pick up coins and watch the coin counter animate from where the
coins were; buy and sell at a vendor, finish a mission and trade coins
with another player, and the coin total updates each time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every game message still written or read by hand is now a NetGameMsg with
Serialize and Deserialize, in per-domain files:
- MovementMessages: teleport, platforms (resync and its request), orient to
angle, node rotation lock, gravity scale, jetpack mode, control scheme,
respawn checkpoint, rails (set/start, ready, cancel, arrived), mount
inventory ID, dismount complete, possession ack, ghost reference override
and position, camera cycling (eCameraTargetCyclingMode moves here).
- ZoneMessages: player loaded (the old PLAYER_LOADED case), ready for
updates, player ready, restore to post load stats, server done loading,
invalid zone transfer list, zone summary display/dismissed, level
processing complete, object world state, and the localized announcement
WorldMigration wrote by hand.
- PlayerMessages: chat mode, GM level, LEGO score, currency, reputation,
GM invis, pickup currency, zone and player statistics, chat commands, bug
reports, verify ack.
- ObjectMessages: fire event client/server side, notify client
(zone) object, notify object, script network vars, failed preconditions,
terminate interaction, set name, request use, request server object info.
- QuickBuildMessages: notify state, enable, cancel.
- ActivityMessages gains match response/update/request, leaderboard request
and data, shooting gallery score/rotation/fire, activity state change.
- MissionMessages gains MissionDialogueCancelled (a no-op, as before).
The wire structs left in GameMessages.h move to their domains (tooltip and
emote to Effects, loot and item use to Inventory, model build to Building,
behavior sound to Property, skill sets to Skill) and gain the missing
direction. The dismount logic moves to PossessorComponent::OnDismountComplete.
Every inbound message is registered in the GameMessageHandler map; the
switch is gone, and GameMessages.cpp only holds the GameMsg/NetGameMsg base
code. Call sites build the structs (NotifyClientObject, TerminateInteraction,
Teleport, PlatformResync, FireEventClientSide, NotifyObject and
NotifyClientZoneObject get convenience constructors like PlayFXEffect).
Dead senders are dropped: SendSetShootingGalleryParams (no callers, field
order was a guess), SendTeamPickupItem (the struct already existed),
SendRequestActivitySummaryLeaderboardData (the struct covers it).
Verified with RemainingMessagesTests: every old Send* function is frozen
verbatim in Legacy/RemainingMessagesLegacy.h and compared byte for byte
(same bits, destination and broadcast flag) over grids of inputs; every old
Handle* read sequence is frozen as a Read* oracle and compared with the
struct's Deserialize; round trips, truncation and a golden packet.
PlayerLoaded (0x00dc36f0), SetGMLevel (0x00dd6230), MissionDialogueCancelled
(0x00d9cc10) and LocalizedAnnouncementServerToSingleClient (0x00f23c50)
were checked against the client. Behaviour notes: an inbound message that
fails to deserialize is dropped, so ParseChatMessage over MAX_MESSAGE_LENGTH
is dropped instead of truncated, and PLAYER_LOADED / READY_FOR_UPDATES /
MISSION_DIALOGUE_CANCELLED now read their (unused) client fields.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The NexusDashboard-parity dashboard (dDashboardServer) and everything built on it on the experimental branch:
accounts, characters, properties and moderation tools, permissions shared with in-game slash commands, economy
reports, World 3D and property 3D views with client scenery, scheduled events (features, vanity changes, live
events, announcements, restarts), vanity files and events, the CDClient browser, the message inspector with saved
captures, chat filter tools, community challenges, live ops, the AI moderator helper, and the server-side changes
they need.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
First step of moving hand written bitstream code to struct based
messages (see docs/PacketArchitecture.md). No wire changes.
- GameMsg is now only a server-internal event (delivered to handlers
registered with RegisterMsg); NetGameMsg is a wire message with
Send(sysAddr) (UNASSIGNED broadcasts), SendToClient(sysAddr) (one
client, never broadcasts), WritePacket, Serialize, Deserialize and
Handle. Mixing them up is now a compile error. NetGameMsgEvent<T> /
DeliverLocally carry a wire message to local handlers; loot drops,
pickup, the object debugger, GM invisibility and model RequestUse
use them. The GM invisibility message keeps its target, so its bytes
are unchanged.
- Behaviour change: GameMessageHandler logs and drops messages whose
Deserialize fails instead of handling them with default fields (the
4 messages already registered: RequestUse, RequestServerObjectInfo,
ShootingGalleryFire, PickupItem).
- LUBitStream (kept as on main) gets a virtual destructor (Mail deleted
derived packets through the base) and WritePacket, also used by
ChatPackets::SendRoutedMsg with identical bytes.
- BitStreamUtils::WriteOptional/ReadOptional for default-flag fields
and WriteLengthPrefixed/ReadLengthPrefixed for length prefixed
strings.
- Every message ID enumerator (MessageType::*, ServiceType, Mail's
wire enums) is pinned with static_asserts, so renumbering or removing
one fails to compile.
- Tests: dServerMock copies each sent packet (it kept a pointer to the
caller's destroyed BitStream); PacketTestUtils.h compares packets bit
for bit; helper tests use hand computed golden bytes and equality
with the hand written patterns they replace; compile-time checks
keep the wire/internal split in place.
- docs/PacketArchitecture.md: survey, target architecture,
conventions, verification method and migration plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: security vulnerabilities
Tested that all functions related to the touched files work
will test sqlite on a CI build
* fix failing test
* ai feedback
* add buffer size checking
* use c_str
* dont log session key
* Try this for a mac definition
* be quiet apple
tested the following are now functional
ag buff station
tiki torch
ve rocket part boxes
ns statue
property behavior
extra items from full inventory
hardcore drops (items and coins)
* Move away from constructor queries
Fix up other large tables to have proper backup lookups
Revert "idk im just dumb ig"
This reverts commit 5d5be5df53b8959b42b291613d7db749a65a3585.
idk im just dumb ig
* Fix slow components registry lookup
* add define for cdclient cache all
* Huge loot namespace rework
- Remove all excess memory usage
- do not cache components registry
- cache loot matrices on startup of the destroyable component
- convert loot singleton class to a namespace
- rework loot cdclient tables to operate closer to how someone would actually use them (basically doing the previous LootGenerator::LootGenerator caching but in those tables)
- Memory usage reduced by 10%+ across the board
* cache rebuild matrix
* Database: move reading to own function
Also change name of cache to PascalCase
* Database: Move common function rading
* Breakout rest of the enums from dcommonvars
so we don't have to deal with merge conflicts
ePlayerFlags is not a scoped enum, yet, due to it's complexity
* address feedback
* make player flag types consistent
* fix typo
* CDClient cleanup and optimization
- Use static function to get table name
- Remove unused GetName function
- Replace above function with a static GetTableName function
- Remove verbose comments
- Remove verbose initializers
- Remove need to specify table name when getting a table by name
- Remove unused typedef for mac and linux
* Re-add unused table
Convert tables to singletons
- Convert all CDClient tables to singletons
- Move Singleton.h to dCommon
- Reduce header clutter in CDClientManager
* breakout the component types into a scoped enum
tested that things are the same as they were before
* fix missed rename
* fix brick-by-brick name to be crafting
because that's what it is
Added support for Items to have a loot source attached to them when dropped or rolled. This fixes the issue where achievements would give the item before it appeared in the achievement window.