Deleting an item now follows its ItemComponent delResIndex row in the
DeletionRestrictions table, the way the client's shared inventory code
decides it (LWOInventoryComponent_Common::CanRemoveFromInventory @
0x00ce0d20, CheckDeletionRestrictionIndex @ 0x00c94c20):
- missing, unrestricted, unknown-type or empty rows allow it;
- LOTS_INCLUDED: another item of any listed LOT must remain;
- LOTS_EXCLUDED: other items of every listed LOT must remain;
- ANY_RESTRICTION / ALL_RESTRICTIONS: any / all listed rows allow it;
- ZONE: only in the listed maps; ALWAYS_RESTRICTED: never.
Operators (GM level 9) may delete anything, as in the client. A refused
delete is logged and the item stays.
ItemComponent.minNumRequired is not used: the client never reads it, so
its meaning can't be verified.
Issue 960: the rocket (6416, row 8) and the classic rocket parts (rows 1-3)
have rows that keep at least one rocket or part, so the last rocket can
no longer be deleted and strand the player.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Unequipping an item uncasts its equip skills; ApplyBuffBehavior::UnCast
now removes the buff with bFromUnEquip set, as live did (2014 captures:
RemoveBuff for buffs 3, 4, 5, 50 and 61 always carried bFromUnEquip,
and those are exactly the cancel_on_unequip buffs in the CDClient).
The client only drops a buff for such a removal when it was added with
cancelOnUnEquip (LWOBuffComponent::RemoveBuffIcon @ 0x00cf99b0), so
BuffComponent::RemoveBuff does the same to stay in step with it. Also
corrects the bFromRemoveBehavior comment: the client does not ignore the
message, it only removes buffs added with cancelOnRemoveBuff.
Replaces the TODO in InventoryComponent::RemoveBuff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mapped from the 1.10.64 client and live captures (docs/BuildWorkflow.md).
Model placement (PropertyManagementComponent):
- A brick built model placed from the inventory spawned at the world origin
with no rotation and without PlaceModelResponse/PreCreate, and was saved
to properties_contents with ugc_id 0; it is now placed where the client
put it, keeps its UGID and blueprint and is saved with them.
- Picking up, putting away and taking apart a brick built model gave it to
MODELS_IN_BBB and then deleted it; every way off the property now puts it
in MODELS (carried when picked up), as live, with its blueprint config.
Taking a premade model apart no longer deletes it either.
- Placing and removing a model saves the property at once, so a crash or a
disconnect before PropertyEditorEnd does not lose it.
- DoneArrangingWithItem only answers when something new is picked (not when
leaving), with the subject as build area; SetBuildModeConfirmed's
warnVisitors matches live.
Brick by brick (BrickByBrick):
- BBBLoadItemRequest moves the model to MODELS_IN_BBB keeping its id and
fails cleanly when the player has no such model.
- MoveInventoryBatch moves bricks between BRICKS and BRICKS_IN_BBB (it was
not handled, so the client and server disagreed until a relog).
- BBBSaveRequest uses up the opened models, places the new ones through the
property, returns the bricks (or uses them with bbb_consume_bricks=1),
clears the autosave and sends RequeryPropertyModels. Every save makes new
ugc rows (is_optimized 0, so the UGC server processes them).
- Quick save: SetBBBAutosave is stored per character (bbb_autosave).
- UnUseBBBModel puts a model back on the property where it was when it came
from there, otherwise back in MODELS.
- Leaving brick mode without a save, a disconnect or a crash: the autosave
is rebuilt into models (RebuildBBBAutosaveMsg) or the opened models go
back to MODELS. MODELS_IN_BBB is saved with the character now and loads
into MODELS, BRICKS_IN_BBB into BRICKS.
Fixes#1632Fixes#159Fixes#1565
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server hardcoded each item set's passives by set ID. They now come from data:
- On-kill bonuses (Paradox imagination, Sentinel armor repair, Bat Lord heal) are the
set's DarkInspiration skills in ItemSetSkills. The client turns those into a status
effect that casts the behavior's action when the wearer kills something of a faction
in faction_list; the server now runs the same behavior on the smashed enemy, so the
amounts, faction check and extra effects (e.g. rank 3 Sorcerer team imagination) follow
the data. A behavior repeated in a higher tier does not stack.
- Low imagination / low armor skills are what the live equipmenttriggers item scripts
do. Items link to those scripts through their ScriptComponent; the script vars (skill,
items required, set, cooldown) only exist in the scripts, so they are mirrored in a
small table keyed by script name. The Sentinel scripts have no cooldown (was 11s).
- Knockback immunity while quickbuilding comes from the Immunity behavior's
immune_quickbuild_interrupts (the 5 item Assembly rank 2/3 set skill) instead of a
set ID list; ImmunityBehavior now pops its immunities when an equip skill is uncast.
Removes eItemSetPassiveAbilityID and InventoryComponent::HasAnyPassive (unused now).
Refs #691
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pet_names gets a pet_lot column (mysql 80, sqlite 63). The world writes
it whenever it saves a pet name, from the pet entity's LOT, and fills it
in for older rows when the owner loads into a world (from the pets the
game loads for that character, only where it is still missing).
The dashboard's pet name tables read pet_lot instead of scanning the
owner's character XML; pets without it yet show as Unknown.
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>
Converts the skill messages to NetGameMsgs in SkillMessages.{h,cpp}:
AddSkill and RemoveSkill (SendToClient, as before), EchoStartSkill,
EchoSyncSkill and DoClientProjectileImpact, and the received
SelectSkill, StartSkill, SyncSkill and RequestServerProjectileImpact.
The one-off StartSkill, EchoStartSkill, SyncSkill, EchoSyncSkill,
RequestServerProjectileImpact and DoClientProjectileImpact classes are
deleted; SkillComponent, BehaviorContext and InventoryComponent build
the structs, and the dashboard's message decoder reads them.
The received messages are registered in GameMessageHandler's map and
their switch cases are deleted; the handlers call SkillComponent as
before. The echoes still go to every client except the caster, through
the new NetGameMsg::BroadcastExcept. SelectSkill still accepts any
payload, since the old case read nothing. Handler logic is unchanged
(the SyncSkill case's unused hex dump of the payload is dropped).
No wire change. Verified byte for byte against frozen verbatim copies
of the old classes and functions over an input grid (every optional
field set and unset, empty, short and long behavior streams), received
messages compared with the old classes' read sequences and truncated
payloads rejected, the echo's broadcast-except destination compared
with the old send, hand computed golden bytes, round trips, and a
deliberate mutation made the tests fail. Messages that fail to
deserialize are now dropped instead of being handled half read.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Staff list contraband items on a new dashboard page (item search, reason, flag or flag and remove;
contraband_manage to edit, reports_view to see). World servers check every inventory when a
character loads and every item a player receives: each find is an economy flag of the new kind
Contraband, shown with the other flags and in the character's related data. Items marked for
removal are taken away, with a character snapshot kept first so they can be given back, an audit
entry and a mail or chat message telling the player why. Staff are skipped unless
contraband_ignore_staff is off. Worlds reload the list when it changes (RELOAD_CONTRABAND, added
at the end of ePlayerAction).
Fixes#1563
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Converts AddItemToInventoryClientSync, SetInventorySize,
RemoveItemFromInventory, ConsumeClientItem, UseItemResult,
UseItemRequirementsResponse, ResponseMoveItemBetweenInventoryTypes,
NotifyNotEnoughInvSpace, UpdateInventoryUi, MarkInventoryItemAsActive and
MoveInventoryBatch (11 old Send functions) and the received EquipInventory,
UnEquipInventory, RemoveItemFromInventory, MoveItemInInventory,
MoveItemBetweenInventoryTypes, RequestMoveItemBetweenInventoryTypes,
PushEquippedItemsState, PopEquippedItemsState, ClientItemConsumed,
UseNonEquipmentItem, SetConsumableItem, UpdateInventoryGroup and
UpdateInventoryGroupContents (13 handlers) to NetGameMsgs in
InventoryMessages.{h,cpp}. The received messages are registered in
GameMessageHandler's map and handled by InventoryComponent (new On* methods
holding the old handler logic verbatim); the old functions and switch cases
are deleted. AddItemToInventoryClientSync::SetItem fills the fields that
come from the Item.
No wire change and no change in recipients. Kept as DLU has always sent them
and documented: NotifyNotEnoughInvSpace goes out with the message ID of
VehicleNotifyFinishedRace, and RemoveItemFromInventory always sets the flag
of the fields DLU fills. The old SendMoveInventoryBatch was never called
and wrote one flag bit fewer than the client reads (it had no moveSubkey);
the struct follows the client's layout (1.10.64,
LWOInventoryComponent_Common::msgMoveInventoryBatch at 00ce1310) and has no
oracle. UnEquipInventory still ignores the trailing replacementObjectID the
client sends, as before.
Verified byte for byte against a frozen verbatim copy of the old functions
over an input grid (AddItemToInventoryClientSync with real Items, extra info
and bind flags), to one client and broadcast; received messages compared
with the old handlers' read sequences and every truncated payload rejected;
hand computed golden bytes; round trips; a deliberate width mutation made
the tests fail.
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>
* feat: debugger additions
Add type field for links in flash
Add warning level for dangerous buttons
fix uninitialzied memory with jetpack variable
remove a bunch of duplicated position push code
tested that the ui is still functional and components with multiple physics components have all their details visible.
tested that jetpack is initialized now
* remove amf3 header
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fixes
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* refactor: update behavior slot determination to use equipLocation instead of itemType
* fix: improve skill management in InventoryComponent to ensure correct client updates
* feat: enhance possession mechanics with skill set integration and improved message handling
* fix: restore SetPossessor in Mount() and scope IsRacing to vehicles
SetPossessor was missing from Mount(), breaking direct possessions via
PossessableComponent::OnUse which bypasses HandlePossession. IsRacing
now only set/cleared when the mount has HavokVehiclePhysicsComponent,
preventing non-vehicle possessions from incorrectly affecting the
distance-driven statistic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* change network settings from vector to LwoNameValue
* move settings on Entity to managed memory
* Migrate more members
* chore: remove pointer leakage from raw ldf pointers
* feedback
* fix ci
* 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)
* feat: re-write persistent object ID tracker
Features:
- Remove random objectIDs entirely
- Replace random objectIDs with persistentIDs
- Remove the need to contact the MASTER server for a persistent ID
- Add persistent ID logic to WorldServers that use transactions to guarantee unique IDs no matter when they are generated
- Default character xml version to be the most recent one
Fixes:
- Return optional from GetModel (and check for nullopt where it may exist)
- Regenerate inventory item ids on first login to be unique item IDs (fixes all those random IDs
Pet IDs and subkeys are left alone and are assumed to be reserved (checks are there to prevent this)
There is also duplicate check logic in place for properties and UGC/Models
* Update comment and log
* fix: sqlite transaction bug
* fix colliding temp item ids
temp items should not be saved. would cause issues between worlds as experienced before this commit
* brother
* use some better logic
* Implement spider boss msg script
tested that the message now shows up when hitting the survival spider entrance area
* add drag to start race feature
* Added feature grouping logic
* Add saving of brick buckets
* Add edge case check for max group count
* Use vector for storing groups
* Update InventoryComponent.cpp
* Update InventoryComponent.h
* Update InventoryComponent.h
* fix string log format
* Update GameMessages.cpp
* stubbing for saving item extra data
* add declaration to header
* modularize loading for all possible extra data
* move logic to Item
* remove extra map
* use string to access field name
* Update DEVGMCommands.cpp
* corrected column name
* constexpr array
include <array>
Revert "constexpr array"
This reverts commit 1492e8b1773ed5fbbe767c74466ca263178ecdd4.
Revert "include <array>"
This reverts commit 2b7a67e89ad673d420f496be97f9bc51fd2d5e59.
include <array>
constexpr array
---------
Co-authored-by: jadebenn <jonahbenn@yahoo.com>
resolves a memory leak in BrickDatabase, adds stability to character save doc.
Tested that saving manually via force-save, logout and /crash all saved my position and my removed banana as expected.
The doc was always deleted on character destruction and on any updates, so this is just a semantic change (and now we no longer have new'd tinyxml2::documents on the heap)
* SystemAddress and destructor
* move respawn logic to character comp
Tested that respawn pos and rot can be set as per previously by crossing a respawn point and smashing to see if I would respawn at the new place.
* Move loot cheat checking
* Remove GetParentUser overload
Tested completing missions
control behaviors
collecting life crate
completing a bunch of missions using macros
loading into worlds
brick-by-brick
placing models
digging the x spot in gnarled forest
can still ban and mute players
cheat detection is still doing its thing
flags are still set (checked with flag 45)
claim codes still work (created new char, checked the lego club mail was there)
* Move player constructor logic
Its now at the bottom of Entity constructor. Time to remove Player
* Remove Player class
Removes the Player class. Tested that I can still login and see another player in Venture Explorer and logging out a few times still works as well as smashing enemies
* store ptr
* Update SlashCommandHandler.cpp
* allow usage of NiPoint3 and NiQuaternion in constexpr context
* removed .cpp files entirely
* moving circular dependency circumvention stuff to an .inl file
* real world usage!!!!!
* reverting weird branch cross-pollination
* removing more weird branch cross-pollination
* remove comment
* added inverse header guard to inl file
* Update NiPoint3.inl
* trying different constructor syntax
* reorganize into .inl files for readability
* uncomment include
* moved non-constexpr definitions to cpp file
* moved static definitions back to inl files
* testing fix
* moved constants into seperate namespace
* Undo change in build-and-test.yml
* nodiscard
* Moving and organizing Player code
- Move code to CharacterComponent
- Remove extraneous interfaces
- Simplify some code greatly
- Change some types to return and take in const ref (only structs larger than 8 bytes benefit from this change.)
- Update code to use CharacterComponent for sending to zone instead of Player*.
* Moving and organizing Player code
- Move code to CharacterComponent
- Remove extraneous interfaces
- Simplify some code greatly
- Change some types to return and take in const ref (only structs larger than 8 bytes benefit from this change.)
- Update code to use CharacterComponent for sending to zone instead of Player*.
- Remove static storage container (static containers can be destroyed before exit/terminate handler executes)
* remove player cast
* Remove extra includes
* Logger: Rename logger to Logger from dLogger
* Logger: Add compile time filename
Fix include issues
Add writers
Add macros
Add macro to force compilation
* Logger: Replace calls with macros
Allows for filename and line number to be logged
* Logger: Add comments
and remove extra define
Logger: Replace with unique_ptr
also flush console at exit. regular file writer should be flushed on file close.
Logger: Remove constexpr on variable
* Logger: Simplify code
* Update Logger.cpp
* Re-write AOE behavior for new filter targets
Update Tacarc to use new filter targets
Added dev commands for skill and attack debugging
* Get all entities by detroyable
rather than controllable physics
Since destroyables are what can be hit
* Re-work filter targets to be 100% live accurate
reduce memory usage by only using one vector and removing invalid entries
get entities in the proximity rather than all entities with des comps in the instance, as was done in live
* remove debuging longs and remove oopsie
* address feedback
* make log more useful
* make filter more flat
* Add some more checks to filter targets
add pvp checks to isenemy
* fix typing
* Add filter target to TacArc and update filter target
* fix double declaration
* Some debugging logs
* Update TacArc reading
* make log clearer
* logs
* Update TacArcBehavior.cpp
* banana
* fix max targets
* remove extreanous parenthesesuuesdsds
* make behavior slot use a real type
---------
Co-authored-by: David Markowitz <EmosewaMC@gmail.com>
* Move EntityManager to Game namespace
* move initialization to later
Need to wait for dZoneManager to be initialized.
* Fix bugs
- Cannot delete from a RandomAccessIterator while in a range based for loop.
Touchup zone manager initialize
replace magic numbers with better named constants
replace magic zonecontrol id with a more readable hex alternative
condense stack variables
move initializers closer to their use
initialize entity manager with zone control
change initialize timings
If zone is not zero we expect to initialize the entity manager during zone manager initialization
Add constexpr for zone control LOT
* Add proper error handling
* revert vanity changes
* Update WorldServer.cpp
* Update dZoneManager.cpp