Client-sent AMF (CONTROL_BEHAVIORS) was decoded without limits on the
associative part of arrays, on nesting depth, or on the total number of
values. Associative entries went into an unordered_map with the standard
unseeded string hash, so a client could pick colliding keys and make
insertion quadratic, and deeply nested arrays recursed until the stack
overflowed, crashing the world server.
- The associative map is now an ordered std::map (O(log n) whatever the
keys, deterministic serialization order).
- Each array allows at most 10,000 associative entries, the same as the
existing dense limit, which is now checked before anything is read.
- Arrays may nest at most 32 deep and one deserializer reads at most
100,000 values. Every limit throws, which the only caller already
catches and drops the message.
- Inserting a duplicate key keeps the last value and no longer returns a
reference to a value that was destroyed when the key already held null.
Verified with new unit tests for each limit (including a 100,000 deep
nesting that previously overflowed the stack) and the existing live
packet test, which still decodes.
Fixes#2035
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>
THIS CHANGES SERVER BEHAVIOUR (intentionally); no wire change.
The MissionDialogueOK handler (carried over verbatim from
GameMessages::HandleMissionDialogOK) dereferenced the responder without
a null check, so a client naming an object that doesn't exist crashed
the world server. It now logs and ignores the message; the script
callback is no longer called with a null player (that path always
ended in the crash).
Test: handling a MissionDialogueOK with an unknown responder crashes
without this change and passes with it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Converts OfferMission, NotifyMission, NotifyMissionTask, ResetMissions,
NotifyClientFlagChange and NotifyLevelRewards (sent with SendToClient:
the old functions never broadcast) and the received RespondToMission,
MissionDialogueOK, RequestLinkedMission, SetFlag and HasBeenCollected
to NetGameMsgs in MissionMessages.{h,cpp}. Callers are switched,
OfferMission's send-it-twice behaviour moves to MissionOfferComponent,
the received messages are registered in GameMessageHandler's map and
the old functions are deleted. Handlers are copied verbatim. The
byte-equality helper can now compare SendToClient messages.
No wire change and no change in recipients. Verified byte for byte
against a frozen verbatim copy of the old functions over an input grid
(including OfferMission's two packets), received messages compared with
the old handlers' read sequences and every truncated payload rejected,
hand computed golden bytes and round trips. Layouts confirmed against
the 1.10.64 client in Ghidra.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Converts the 12 racing / vehicle / modular assembly messages DLU sends
and the 8 it receives to NetGameMsgs in RacingMessages.{h,cpp}, adds
eRacingClientNotificationType for NotifyRacingClient's event type,
switches the callers (RacingControlComponent, CarBoostBehavior,
PossessorComponent, slash commands), registers the received messages
in GameMessageHandler's map and deletes the old functions. Handlers are
copied verbatim. Also moves the byte-equality test helpers into a
shared GameMessageTestUtils.h.
No wire change. Verified byte for byte against a frozen verbatim copy
of the old functions over an input grid, to one client and broadcast;
received messages compared with the old handlers' read sequences
(including all 16 optional-field combinations of
VehicleNotifyHitImaginationServer) and every truncated payload
rejected; hand computed golden bytes; round trips; a deliberate field
mutation made the tests fail. Layouts confirmed against the 1.10.64
client in Ghidra. Malformed received messages are
dropped (see the foundations commit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Converts ActivityEnter, ActivityExit, ActivityStart, ActivityStop,
ActivityPause, StartActivityTime, RequestActivityEnter,
RequestActivityExit and ShowActivityCountdown to NetGameMsgs in
ActivityMessages.{h,cpp}, switches their callers (racing, shooting
gallery, survival, waves, AG course, NT combat challenge) and deletes
the old GameMessages::Send* / HandleRequestActivityExit functions.
REQUEST_ACTIVITY_EXIT is registered in GameMessageHandler's map.
No wire change. Verified by comparing every struct byte for byte with a
frozen verbatim copy of the old functions (tests/.../Legacy) over a
grid of inputs, both to one client and as a broadcast (a temporary test
proved the copy matched production before it was deleted), plus hand
computed golden bytes, round trips and a deliberate field mutation that
made the tests fail. Layouts confirmed against the 1.10.64 client in
Ghidra. Only difference: a broadcast no longer makes
the extra Send(UNASSIGNED, false) that RakNet already rejected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
THIS CHANGES THE BYTES SENT TO THE CLIENT (intentionally).
UnSmash::Serialize wrote the "duration != 3.0f" flag but guarded the
value with "builderID != 3.0f" (a typo), so the 32-bit duration was
always written, even after a 0 flag. The LEGO Universe 1.10.64 client
(GameMessage::UnSmash::Serialize/Deserialize @ 00dc0e80/00dc0f50,
default 3.0f @ 017e66b4) writes it only when
duration != 3.0f. The client read the flag and ignored the trailing 32
bits, so this removes 4 junk bytes from default UnSmash messages;
messages with a non-default duration are unchanged.
Uses WriteOptional/ReadOptional and adds Deserialize. Verified with
hand computed golden bits for every flag combination and round trips.
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
* LXFML SPLITTING
Included test file
* move base to global namespace
* wip need to test
* update last fixes
* update world sending bbb to be more efficient
* Address feedback form Emo in doscord
* Make LXFML class for robust and add more tests to edge cases and malformed data
* get rid of the string copy and make the deep clone have a recursive limit
* cleanup tests
* fix test file locations
* fix file path
* KISS
* add cmakelists
* fix typos
* NL @ EOF
* tabs and split out to func
* naming standard
* merge ServerType and ServiceID enums
* rename eConnectionType to ServiceType in preparation for enum unification
* unify ServiceID and ServiceType enums
* shrink ServiceType to an 8-bit integer
* fix linux compilation error and update gamemsg test
* return to uint16_t
* Update dNet/AuthPackets.cpp
Use cast instead of padding
Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>
* Add default case to MasterServer.cpp
* move ref back to type
* Another formatting fix
* Fix comment to be more accurate
---------
Co-authored-by: jadebenn <9892985+jadebenn@users.noreply.github.com>
Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>
* change behavior id to LWOOBJID
Convert behavior ID to LWOOBJID length
missed header
fix sqlite field names
sqlite brother
* feat: add saving behaviors to the inventory
consolidate copied code
consolidate copied code
Update ModelComponent.cpp
remove ability to save loot behaviors
* Rewrite AMF and behavior logic to use smart pointers, references, and string_views over raw pointers and std::string&
* fix m_BehaviorID initialization
* Fix BlockDefinition member naming
* remove redundant reset()s
* Replace UB forward template declarations with header include
* remove unneeded comment
* remove non-const ref getters
* simplify default behavior id initialization
* Fix invalidated use of Getter to set a value
* Update AddStripMessage.cpp - change push_back to emplace_back
* fix pointer to ref conversion mistake (should not have directly grabbed from the other branch commit)
* deref
* VERY experimental testing of forward declaration of templates - probably will revert
* Revert changes (as expected)
* Update BlockDefinition.h - remove extraneous semicolons
* Update BlockDefinition.h - remove linebreak
* Update Amf3.h member naming scheme
* fix duplicated code
* const iterators
* const pointers
* reviving this branch
* update read switch cases
* Add MSVC optimization flags
* test moving flags to json
* Update CMakePresets.json
* testing
* trying more variations on the flags
* third test
* testing if these even have any effect
* ditto
* final(?) try for now
* ONE MORE TIME
* trying 'init' flags instead
* export the compile commands so I can see if they're having any effect
* move out g++ O2 flag
* add Linux debug preset
* update CMake presets
* edit macos presets
* try adding build types back to mac
* macos refuses to work :(
* try using compiler flags for mac instead
* fix typo in windows preset
* build reorganization and experimental clang support
* temporarily remove macos build for testing purposes
* updated cmake workflows
* unexclude toolchain dir
* update .gitignore
* fix build directory issue
* edit build script
* update cmake configs
* attempted docker fix
* try zero-initializinng this struct to solve docker issue
* try fixing macos build
* one last MacOS try for the night
* try disabling an apple-specific build rule
* more fiddling with mac test builds
* try and narrow down the macos build failure cause
* try stripping out all the custom macos test logic again
* I'm really just throwing everything to the wall and seeing what sticks
* more macos tinkering
* implib
* try manual link directory specification
* save me
* aaaaaaaaa
* paths paths paths
* Revert "paths paths paths"
This reverts commit 9a7d86aa6c.
* Revert "aaaaaaaaa"
This reverts commit 338279c396.
* Revert "save me"
This reverts commit bd73aa21a9.
* Revert "try manual link directory specification"
This reverts commit 0c2d40632e.
* Revert "implib"
This reverts commit d41349d6ed.
* Revert "more macos tinkering"
This reverts commit 829ec35b57.
* Revert "I'm really just throwing everything to the wall and seeing what sticks"
This reverts commit 1a05b027fe.
* Revert "try stripping out all the custom macos test logic again"
This reverts commit cc15a26ce8.
* Revert "try and narrow down the macos build failure cause"
This reverts commit 5fd86833fa.
* Revert "more fiddling with mac test builds"
This reverts commit 0f843c02c9.
* Revert "try disabling an apple-specific build rule"
This reverts commit 45ec66e976.
* back to debug messages
* see if this re-breaks mac
* are these messages actually somehow fixing the issue?
* was not actually fixed
* add debug messages (again)
* debug try 2
* change runtime output dir
* rename gcc to gnu
* expand cmake presets
* fix preset
* change defaults
* altered cmake configuration scripts
* disable /WX on MSVC
* update github actions
* update build presets
* change gnu and clang build directories to enable consistent artifact generation
* add RelWithDebInfo presets and move -Werror flag into presets.json
* use DLU_CONFIG_DIR envvar
* CMakePresets indentation
* temp fix for MSVC debug builds
* saving from a test works
* testing works
* Update SavingTests.cpp
* test dServer stuff
* tests
* use dummy database and add missing pure fns
* add more tests
* add more tests
* add rocket tests
* Update BuffComponent.h
* Update test_xml_data.xml
* Update SavingTests.cpp
* update
* nit
* GeneralUtils const-correctness and minor fixes
* use copy instead of reference for char iteration loops
* fix typo and reorganize some functions
* WIP, but working
* Scaffolding
* testing and making it compile again
* move all commands to functions
* renaming to compile
* fix failing tests
idk how these werent failing before. Seems to have been magic.
* move commandss into their namespace
make help command useful
fix mac error
TODO: remove the multiple not founds/ rework the structure to split into help and handling
* Just need to fill out the fields, but it's all there templated
* Add all aliases, register missing commands
* All help text
* remove test logs
* improvements
pass through added code for optimizations and cleanup as well as reduce the amount of scoping for readability and maintainability
* Update SlashCommandHandler.cpp
* only save command if it is a GM command
* simplify if checks
* remove broken delimiter
* Update SlashCommandHandler.cpp
* Update SlashCommandHandler.cpp
---------
Co-authored-by: David Markowitz <EmosewaMC@gmail.com>
* chore: supress warnings on external library headers and actually get rid of the last old-style casts
* remove commented out section I forgot
* update cmake required version to 3.25 unless we can find another way to do this
* update readme
* Update CMakeLists.txt
* fix: more include changes
* fix: remove dZoneManager from global include
* fix: dDatabase
* fix: dCommon
* fix: object libs
* fix: rebase
* fix: bcrypt
* wip: try simplified connector build
* fix: update dockerfile
* fix: mariadb C/C++ on apple
* feat: Move scripts to CMAKE_MODULE_PATH
* fix: dPropertyBehaviors
* fix: macos?
* fix: Dockerfile
* fix: macos?
* fix: macos?
* fix: macos?
* fix: macos?
* fix: macos?
* try: install_name_tool
* fix not building on unix
* fix include paths
* Remove code changes
Will fix in another PR.
* format pass
remove 2 more included directories.
remove commented out code
add status to messages
* comments and format
surround include directories with quotes
remove commented out code
remove debug messages
* Update CMakeLists.txt
---------
Co-authored-by: David Markowitz <EmosewaMC@gmail.com>
Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>
* 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
* Assorted pet improvements
* remove unecessary include
* updates to address some feedback
* fixed database code for testing
* Removed reference member (for now)
* Removed cmake flag
* chore: organize build flags
* Remove ambiguous include path
Don't be default incluyde bcrypt so you need to specify the folder. Allows pre-processor to find the correct file.
* Revert settings
* working
f
* add enum stringification functionality from third party source
* squashed commit
* Macros: Add test and improve speed
Space macros out
utilize cache locality
ensure no lost functionality
* moved stringify code to dCommon
* Rename #defines in stringify enum tests
* Revert "moved stringify code to dCommon"
This reverts commit 33fa5f8d2f.
* improve macro functionality
change function handle
formatting and function definition tweaks
* typo fixes
* moved code to dCommon/dEnums and tests to dCommonTests/dEnumsTests
* initial magic_enums alternate implementation of enum stringification
* deleted unused tests
* reverted compile flag oopsy and fixed output types
* fixed testing suite
* test formatting improvement
* formatting again :(
* added gm string to "aborting gm!" message
* Push my suggestion for CI tests.
* updated magic enum test
* fix test variable type
* added gm test
* making sure magic_enum is on a release branch
* tidying up console outputs
* re-implemented enum array access for performance
* now it is bugged :(
* nvm, working
* helping out the snowflake compilers
* changed return type too
* optimization too
* formatting too I guess because why not
* being even more painfully specific
* Update WorldServer.cpp to match emo's feedback
* Update MagicEnumTests.cpp to use srand(time(NULL))
* Update eGameMessageType.h - formatting
* Trying to fix the crash but can't actually compile the code to check on my own rn
* Update WorldServer.cpp - third try at this
* Update MagicEnumTests.cpp - use better macro definitions
* Update MagicEnumTests.cpp - c string comparison fix
* addressing all but the cmake feedback
* fixed cmake to the best of my very limited ability
* added tests to verify magic enum arrays are pre-sorted
* updated
---------
Co-authored-by: David Markowitz <EmosewaMC@gmail.com>
Co-authored-by: Jettford <mrjettbradford@gmail.com>
* feat: add configurable feature and versions
to allow for easily swithing it out to enable features in the client for funsies
tested that this doesn't break anything and added test
* cleanup
* Added cooldown handling
* Made most of the logs hidden outside of debug mode
* removed weird submodule
* kill this phantom submodule
* updated to reflect reviewed feedback
* Added IsCooldownImmune() method to DestroyableComponent
* friggin typo
* Implemented non-pending changes and added cooldown immunity functions to DestroyableComponentTests
* add trailing linebreak
* another typo :(
* flipped cooldown test order (not leaving immune)
* Clean up comment and add DestroyableComponent test
* Components: Make ComponentType inline
Prevents the next commits ODR violation
* Components: Add new components
* Entity: Add headers
inline script component ComponentType
* Components: Flip constructor argument order
Entity comes first always
* Entity: Add generic AddComponent
Allows for much easier adding of components and is error proof by not allowing the user to add more than 1 of a specific component type to an Entity.
* Entity: Migrate all component constructors
Move all to the new variadic templates AddComponent function to reduce clutter and ways the component map is modified.
The new function makes no assumptions. Component is assumed to not exist and is checked for with operator[]. This will construct a null component which will then be newed if the component didnt exist, or it will just get the current component if it does already exist. No new component will be allocated or constructed if the component already exists and the already existing pointer is returned instead.
* Entity: Add placement new
For the case where the component may already exist, use a placement new to construct the component again, it would be constructed again, but would not need to go through the allocator.
* Entity: Add comments on likely new code
* Tests: Fix tests
* Update Entity.cpp
* Update SGCannon.cpp
* Entity: call destructor when re-constructing
* Update Entity.cpp
Update Entity.cpp
---------
Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
* 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
* Make serialize actually virtual
yep
* Abstract to PhysicsComponent
Move shared functionality of all physics related classes to a base class.
Tested that there were no failed to unserialize errors when in main gameplay in Gnarled Forest or in a race.
Tested that 2 players were able to see each other in the above scenarios just fine as well.
* Update PhantomPhysicsComponent.cpp
* Add SimplePhysicsTest
* Add construction test
* Update SimplePhysicsComponentTests.cpp
* remove flags and fix override
* Update VendorComponent.h