MsgMapStrServerHandshake was being sent as unordered, meaning that it could actually arrive on the client before the handshake-finished messages. Whoops.
* Dirty PVS chunk when visibility mask changes
* fix tests?
* aaaaaa
* maybe sorta finally fix tests
* directly return vis mask,
Also defaults to 1 only if visibility component does not exist.
* make sure everything has first bit set
* Don't disable access check outside FULL_RELEASE.
* Content allows all commands on +HOST now
* Client-side completions are filtered for perms and sorted.
This was an existing bug, but due to me moving more cleanup logic to game thread shutdown the window of opportunity for it to trigger just got much greater.
* Trying to get res:// and usr:// cookies to wrok
* Update CefGlue
* Bump CEF
* Seal types in WebView
Fixes warnings
* Move most of client cleanup to game thread.
This used to run in the windowing thread which broke CEF shutdown, most notably cookie saving.
* "flushcookies" command for CEF.
* Remove unecessary res:// code.
* Fix tests
* More request handler fixes.
* Good thing I don't have to care about commit quality in PRs like this.
* Cleave the ACZ code into two parts
* SSAZip - faster-performing than ZipArchive, very small codebase
* OnDemandFile to reduce RAM usage of SSAZip
* Modify OnDemandFile to be more amiable for replacing parts of ACManifest
* Make the ACZ Manifest code a lot less reliant on an "internal zip file" for memory usage reasons
* Finally allow disabling legacy client zip creation entirely
* ZIP is now only an ingestion format for ACZ, not actually served anymore
* We do a little renaming
* We do a little namespace adjustment
* We do a little ABOMINATION OF FILE MERGING
* Significantly optimise prediction resetting
Turns out just tracking dirty entities and not iterating 30k is much faster.
* cleaner
* Slightly better again
* review
* Fix
* boop
* rebiew
* A
This was like 1/3 of the frame spikes from PVS pop-in. The main benefit is just checking if the entity is anchored for grid traversal and the secondary was earlying-out handling component state if it's sent to nullspace.
* benchmark script
* more changes
* oopsie
* adjust workflow
* Put a concurrency limit on the benchmarks action
* Update run_benchmarks.py
Co-authored-by: Paul <ritter.paul1+git@googlemail.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
* RobustToolbox side of Redial API.
Please be aware that as far as I know testing this code is nigh-impossible until it ships.
* a smidge of paranoia
* paranoia on the paranoia please
* DetachParentToNull tweaks
The other parent change message already has the mapid and gridid updated when issuing the event.
We'll also guard the event by checking if they're already in nullspace.
* woops
It now includes the invalid hexcode argument.
Something in content kept getting these exceptions on prod and knowing the invalid argument would be very helpful when debugging these in the future.
* Deleting a map is now routed through MapComponent deletion.
* Remove map and grid deletions from map networking, just delete the entity if you want to remove the map.
* Moved the chunkSize property of created grids from the networked MapData to the MapGridComponent state.
* Remove unused IMapManager.DefaultMap property.
* Removed MapCreationTick field from MapManager.MapCollection.
* Removed _maps hashset field from MapManager.
* Removed CreatedMaps array from network MapData.
* MapGrid.ParentMapId is now derived from the bound TransformComponent, and isn't required in the MapGrid ctor.
Removed MapGrid.CreatedTick, it can be found on MapGridComponent.CreationTick.
* Remove a bunch of ApplyGameStatePre code duplication.
* Completely refactored CreateGrid.
* Adds AddComponentUninitialized to the ECS system. This allows you to access a component before it is initialized in a using block.
* Use AddComponentUninitialized to allocate a grid after the component is allocated.
* MapLoader now creates the grids after creating the map entities.
* Chunksize and TileSize properties are now actually read out of the map yaml.
TileSize has a public Setter.
* Minor cleanup.
* Moved grid allocation onto the MapGridComponent.
* Final Cleanup.
* Merge Fail.
* Fixed test, grid was getting deleted because it was empty.
* Remove DeletedChunkDatum from grid networking.
* ApplyMapGridState moved from map manager to the MapGridComponent.
- Implemented autoUI scaling, scaling supports down to 520 by 520 pixel screens(Idk why you'd even have this)
- UI scaling can be adjusted by overriding the window root class
* Obsoleted C# grid events from MapManager.GridCollection. Use the ECS EventBus events instead.
* Obsoleted C# events from MapManager.MapCollection. Use the ECS EventBus events instead.
If a shutdown was requested before the main loop had been started, it would only work if the reason was non-null. This is because `string? _shutdownReason` essentially acts as a shutdown request flag with its nullability.
* All IPhysShapes now expose a property to get the local AABB.
* Removed IMapChunk. It's internal, we only have 1 implementation in the engine, no need for abstraction, and removing it helps perf.
* Cleaned up issues in MapChunk file.
* Encapsulate _tiles access inside MapChunk.
* Remove IEnumerable<TileRef> from MapChunk.
* Remove CollidesWithChunk
* Move CalcWorldAABB and RegenerateCollision from MapChunk to MapGrid.
Remove MapChunk.GridId.
* Removed MapChunk.GetAllTiles
* Removed the terrible mocked unit tests.
* Moved the GetTileRef functions from MapChunk to MapGrid.
* Add an event raised on MapChunk when a tile is modified.
Completely remove the IMapGrid dependency from MapChunk.
* Fix bug where you cannot change the tile damage of a tile.
* Encapsulated existing _pausedMaps access in MapManager.Pause.
Added more unit tests.
* Moved the MapPaused flag from MapManager.Pause to MapComponent.
* Moved the MapPreInit flag from MapManager.Pause to MapComponent.
* Changed visibility so content can't access the flags directly.
* It's not the code that is wrong, it's the tests that are wrong!
* Removed completely obsolete bookkeeping event.
Adds the command buffer to the console.
adds wait <ticks> command to console.
Adds the `incmd` command to inject input commands directly into the simulation, bypassing the frontend.
Removes client side permission check for debug builds.
* Engine changes for more server-pushed lighting variables, but apparently this is a deprecated way of doing things anyway
* Removed two unecessary uses of virtual
* Clean up TeleportTo
* Change TeleportTo to allow teleporting to EntitiyUid
* Rename TeleportToPlayerCommand to TeleportToCommand
* Move duplicate parsing code to TryGetTransformFromUidOrUsername
Simulation input and Update() does not happen when prediction is disabled. Both of these can be re-opted in on a per-handler/system basis with a bool flag. Stuff like physics opts out of this now.
- Fix bug where MIDI renderers in other maps than the current map in IEyeManager would be silenced forever.
- Tracking an entity now sets the TrackingCoordinates to the entity's coordinates.
- MIDI renderers not in your same IEyeManager.CurrentMap or that have invalid coordinates will have their occlusion set to the max value, essentially becoming silenced. I feel like this is a much better solution than changing the volume, as things should be able to call Source.SetVolume without it being changed by positional audio shenanigans.
Added an option to defer field DI for RegisteredInstances until BuildGraph is called. This lets you register instances that contain dependency fields that are not instantiated yet.
* Console/SystemConsoleManager: Short-circuit console input handling when not interactive
* Console/SystemConsoleManager: Use a `Task` for reading input
Now with 100% less blocking (on the main thread, at least)
* Console/SystemConsoleManager: move command execution off the worker thread
* Shared/Utility: Define new FormattedMessage core types
* Shared/Utility: Move MarkupParser to a new namespace, update to new FormattedText
* Shared/Serialization: Temporary fix for FormattedMessageSerializer
* Scripting/ScriptInstanceShared: Move to new FormattedMessage.Builder
* Shared/Utility: Add a FormattedMessage loader to the .Builder
* Server/Scripting: Port SciptHost to FormattedMessage.Builder
* UserInterface/RichTextEntry: NOP out almost everything
not gonna bother fixing it until more groundwork is laid
* Shared/Utility: Expand Utility.Extensions a bit
strictly for pesonal reasons
* Client/UserInterface: Add the base TextLayout engine
* Client/Graphics: Add a Font Library manager
* Graphics/TextLayout: Finish up implementing the TextLayout engine
* Utility/FormattedMessage: Add yet another hack to keep the serializer in service
* Commands/Debug: Use FormattedMessage.Builder
* Console/Completions: Use FormattedMessage.Builder
* Utility/FormattedMessage: Add `AddMessage` methods
* Console/ScriptConsole: Use FormattedMessage.Builder
* Client/Log: Use FormattedMessage.Builder
* CustomControls/DebugConsole: Use FormattedMessage.Builder
* Controls/OutputPanel: Use FormattedMessage.Builder, NOP `Draw` pending rewrite
* Controls/RichTextLabel: Use FormattedMessage.Builder, NOP `Draw` pending rewrite
* UnitTesting: Update FormattedMessage/Markup Tests
They will NOT pass yet, but I don't care; it compiles.
* Utility/FormattedMessage: Fix some off-by-one Builder bugs
* Utility/FormattedMessage: Continue cleanup, test compliance
* Utility/FormattedMessage: Work around https://github.com/dotnet/roslyn/issues/57870
* Utility/FormattedMessage: Move ISectionable from TextLayout, implement it for FormattedMessage
* UserInterface/TextLayout: Add a `postcreate` function to set up new `TIn`s
Apparently Roslyn isn't big-brained enough to understand that a
closure of type `Func<T>` means that `var n = new(); return n;` requires
`new()` to return a `T`.
Ironically, it's significantly less cbt to add this than to convert
that big tuple in `Layout` in to a class or struct of some sort
(to initialize the `List<>`s).
* UserInterface/TextLayout: Throw if `Meta` isn't recognized
TODO warning go brrr
* Graphics/FontLibrary: Add a `DummyVariant`
* UserInterface/UITheme: Move to FontLibraries
* UserInterface/TextLayout: Move to an un-nested `ImmutableArray`
* UserInterface/RichTextEntry: Go ahead. Draw.
* Markup/Basic: Add extension & helpers for FormattedMessage.Builder
* Markup/Basic: Add `EscapeText` back in
A forgotten casualty of the great Markup separation of 2021
* Graphics/FontLibrary: Clean up bit magic, ensure that at least one font is picked
* Graphics/FontLibrary: Add diagnostics to the "no fonts" exception
* UserInterface/TextLayout: Scrap `Word`, return to `Offset`
* UserInterface/TextLayout: A whole bunch of hard-fought bugfixes
* Utility/FormattedMessage: Add a static, empty FormattedMessage
* Utility/FormattedMessage: Fix. Bugs.
* UserInterface/RichTextEntry: Bug fixin'
* UserInterface: CSS teim
* Markup/Basic: Add an optional "default" style to use
* Utility/FormattedMessage: I'm surprised I only made this mistake once.
* Log/DebugConsoleLogHandler: work around lack of a default style
* make adding entities in range optional
* Revert "make adding entities in range optional"
This reverts commit bd707b9f4e.
* remove AudioSystem filter modifications
* Add method to get worldpos and worldrot at the same time
Somewhat of a gain because it halves the number of GetComponent<TransformComponent> + _parent.IsValid() calls
* Remove redundant methods
* Also inverse
* Test
* Import
* Add benchmark
* Delete benchmark
SetLoop sets the amount of times to loop a song. If you set it to 1, it'll loop once, if you set it to -1, it'll loop infinitely. This should have been 0 from the start, so it doesn't loop when disabled.
* Optimise GetBroadphases
Only used in public APIs. Should be significantly faster as it doesn't iterate every fixture on a grid.
* Fix the staged stuff
A bad return statement meant that the associated grid was not being properly deleted.
This fix means the game won't effectively crash PVS if a grid entity is directly deleted.
* Add test pooling and global test setup
* WIP test pooling changes
* Make asynchronous tests the default again
* Finish fixing tests, make test threads background threads
* Un-pool tests with custom cvars
* Fix not changing FailureLogLevel cvar on instance return
* Fix error when overriding already overriden cvar
* Don't pool some physics integration tests
* Unpool engine tests, the technology just isn't there yet
* Remove explicit Pool = false from physics tests
* Change default pooling setting to false
* Didn't need this anyway
* Remove ConfigurationManager.ResetOverrides
* Bring back enum cvar override parsing
* Make integrationInstances name clearer > notPooledInstaces
Make clients ready and servers ready internal
* Add logging test instances
* Give more info on ran tests
* Show total clients and servers in test output
* Wipe LayerMap on SpriteComponent.AfterDeserialize
* Fix server not properly kicking clients
* Rider shut
* Make all test metrics report totals
* Format tests ran better
* Replace Console.WriteLine with TestContext.Out.WriteLine
* Fix two server test pooling info prints using total clients instead of total servers
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Robust.Client.CEF Renamed to Robust.Client.WebView since CEF should really be an implementation detail.
Content is no longer responsible for initializing and managing the module, this is done automatically by the engine.
WebView is initialized by declaring it in a manifest.yml file in the game resources. In the future the launcher will read this same file to manage WebView module versions.
CefManager has been made private and the content-visible API is now IWebViewManager.
* Fix resizing moving the window beyond its minimum size and causing it to move visually
* Do a NaN-check the SetSize when resizing
* Use float instead to avoid conversion
As per PJB3005's suggestion
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
* Make autogenerated XAML fields public instead of protected
* Make field always public, remove stray commented out code
* Remove encapsulation for previously protected XAML UI fields
* Make access level settable
* Set access to public for DebugConsole LineEdit
* Address reviews and add documentation
* Remove documentation
* Address reviews
* Reduce FindGridsIntersecting allocations
I love struct enumerators
* Do slightly smarter pooling in EntityViewCulling
Even more alloc reductions
* Forgot to re-add this pooling
* Fix missing chunks
- Exception tolerance added
- UID is now passed in the arguments
- Is able to remove protected components if needed.
- Actually calls `ComponentDependencyManager` to let it know the component has been removed.
* Don't generate physics contacts for non-predicted bodies
These are all just handled on the server anyway so it's a significant waste of performance on the client for busy scenes.
* Significantly optimise broadphase updates
Cache all of the broadphase data properly now and also save the cache for physics step to boot.
* Fix cross-map broadphases
* Remove unnecessary clear
* fix
* Fixes
* Numerous ray fixes
In short, if you specify a shared type as a friend, any inheriting types will also count as friends, automatically. This could be abused but... That's why "sealed" exists, r-r-right?
Shadows now seem to remain pretty stable up to the point where nothing is stable.
Sounds good to me.
Now, I know what you're going to say. "But, but, Kraken *fren*!"
*sighs* No. Kraken BAD. Kraken harm spesspeople.
This won't help too much because serialization is extremely alloc-heavy and it causes tons of GC pressure, so GC will drastically reduce the effectiveness of parallelization. Still helps a bit though.
When you tried to spawn an anchored entity, it wouldn't spawn it in the position you specified, as the entity is anchored...
Now, we forcibly disable anchoring just for moving the entity, and restore the old anchor state when we're done.
Yes, this is a bad solution. No, I don't regret it: We need to get our shit together and have a way to forcibly teleport/move entities that are anchored for things like this.
* Fright night
* Shitty bounds working
* No more fixture leak
* Optimise TryFindGridAt
Should be O(1) now instead of the previous O(n) for number of fixtures
* ambush
* Merge stuffies
* Merge to master
* Fixes I guess
* Fix client sync
* Fix grid deserialization
* Jank test
* Fix deferral shitfuckery
* Optimise and remove
* Fixes
* Just werk dam u
* Optimisations
* Bunch of fixes
* FINALLY IT'S DONE
* Fixes
* Fix
* Comment
* Change serialization reading to only do type checks once per type
* Optimize for sealed types in arrays
* Oops the context
* Fix ISelfSerialize node type and null values
* Add int read test
* Remove nullability from constructor and property of DeserializedValue
* Add clearing readers to serialization shutdown
* Fix struct populate default values
Remove some notnull constraints
* Replace robust gen with normal il generator
* The real lookup flags
* Don't get anchored entities for PVS query
* Finish that implementation
* Immediate anchoring changes
* Woops some anchoring slippy
* Fix stupidity
* More gradual
* Remove thread-unsafe stuff
In case anyone notices I'm stupid
* Some day I'll stash instead lol
* Fix thread issue
* Werk
* Cvar for range too
* Explanation
* More comments
* Fix merge
* Avoid unnecessary TransformComponent cast in PVS
Haven't profiled if it's faster but it supports EntityUid better so whenever we deprecate IEntity we would've had to do this anyway.
* Avoid unnecessary MapPosition call
LocalToChunkIndices already checks for this and saves the additional conversion from EC -> map -> EC again
* Doc fixes
Rather than having the methods on the shapes themselves (whenever we eventually get them as structs) I just put them on a shapemanager instead as it seemed cleaner?
* The real lookup flags
* Don't get anchored entities for PVS query
* Finish that implementation
* Immediate anchoring changes
* Woops some anchoring slippy
* Address review
Now we only use the dictionary for storing entities, similar to components.
This means creating/deleting entities while enumerating them will throw, but that's probably fine since GetEntities() is barely used nowadays, and we have QueueDelete().
* Add support for grid chunk removals
Also allows grids to be removed when they have no more chunks remaining.
* No more crashing pog
* Slightly better
* Minor optimisations and fix bounds
* Avoid creating new chunks for anchoring
* chucky
* comment
* Tests
* Remove some logs
* Remove another log
* Review
* Fix client-side physics bodies getting stuck awake
Wasn't a huge perf hit but it could leak a bit. Also there's a bunch of E/C stuff in here and I'll deal with it later.
* Fix broadphase leak
* Fix robust server sim
* PVS is now aware of entity anchoring.
Misc PVS perf improvements.
* Fix master merge
* Optimise chunks intersecting
* Ensure anchored entity chunks are always sent
* Remove silly pool by me
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
* Add short-circuit for TryDistance
90% of the uses probably have the same parent hence we can avoid the more expensive ToMap calls for these.
* InRange too
Don't need to check every chunk's bounds when you can just do dictionary lookups. Should be an okay bonus for PVS and grid rendering on larger grids. Didn't make tests yet because all of the existing ones are mocked and painful to change.
* Fix grid collisions
* Fix this silliness
* Add test for grid collisions
* Fix FlagSerializer not working with 1 << 31
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
* MapManager now uses accurate bounds for grids
Instead of using the old WorldBounds (which was dirty for multiple reasons) it goes through physics instead using the actual fixtures attached to the grid.
* Fix nuke
* Test time
* AABB tests
* feex
* how is this failing aaa
* feex tests
* slightly better
Co-authored-by: metalgearsloth <metalgearsloth@gmail.com>
* Add Friend classes to C# with the help of Analyzers and Attributes.
* Revert to netstandard2.0
* Use LINQ instead of ^1 for array
* Address review.
Oops, forgot to push.
* Fix containers that hold entities not on client
* Delete from ExpectedEntities when entity removed
* Fix ContainerSystem not registering on the server
* Move container state to entity system
Move client code to client
* Fix removal and clean up code
* Add test
* Add more checks to test
* Remove unneeded deletion event handler
When the child is deleted, if the entity does not exist on the client,
then HandleComponentState runs. If the entity does exist, then
HandleEntityInitialized would have run. Either way HandleEntityDeleted
is not needed.
* Renamed unexpected to removedExpected
The default value would be set to 0 as a placeholder from when the config var is first tracked as unregistered, which means that when we try to override it tries to parse it as an int always.
The issue is that currently moving around means any non-anchored entities have their positions updated to / from NaN. As you can imagine this is a performance nightmare for anything subscribing to it, especially considering it leads to the broadphase getting desynced for physics.
Realistically we need one of the alternatives Acruid has laid out because flooding the eventbus with NaNs will kill performance.
* Cache physics transforms internally
3 main points to cache them for:
1. Contact updates
2. Physics Islands solving
3. GetWorldManifold (though this is primarily for ss14).
Whenever multi-threading is done it will need adjustments to make sure no race conditions on accessing the transforms dictionary
* Also cache position and angle for GetWorldAABB
* Fix boogs
* woops
* ComponentNames are not sent over the network when components are created.
* Removed ComponentStates array from EntityState, now the state is stored directly inside the CompChange struct.
* Remove the unnecessary NetID property from ComponentState.
* Remove Component.NetworkSynchronizeExistence.
* Change GetNetComponents to return both the component and the component NetId.
* Remove public usages of the Component.NetID property.
* Adds the NetIDAttribute that can be applied to components.
* Removed Component.NetID.
* Revert changes to GetComponentState and how prediction works.
* Adds component netID automatic generation.
* Modifies ClientConsoleHost so that commands can be called before Initialize().
* Completely remove static NetIds.
* Renamed NetIDAttribute to NetworkedComponentAttribute.
* Fixing unit tests.
adds a typeserializer
adds null parser to read
adds another overload for deserializationresult.value
Co-authored-by: Paul <ritter.paul1+git@googlemail.com>
* Adds ServerOptions, improve GameControllerOptions, fix engine integration tests
* Do component auto-registration in engine integration tests by default
* Fix integration tests on content, register components ONLY if not contentstarted or options are null
* Add integration test for engine integration tests working correctly
* Move cvar overrides out of content and into engine.
FullState was getting updated before ResetPredictedEntities ran instead of after. So ResetPredictedEntities was applying data to stuff like containers that depends on entities that hadn't been made yet.
* Fix light pop-in
Doh
* Uniqueness
* Refactor to be less bad
* Better perf
* Fix perf problems
* Hide debug commands under preprocessor
Can't imagine anyone using this during live-game.
* CVars
Apparently? You need to dispose of the sequencer BEFORE the synth or a funny segfault will occur... T-Thanks libfluidsynth.
Also unregisters the sequencer clients before disposing, just for cleanliness.
* MapGridSystem for grid initialization
Doesn't seem to be a clean way to hook into grids being initialized (can't duplicate directed bus events and a few systems need to EnsureComponent) hence the event.
* Address reviews
This is because the parent was attached first, and then the Entity Coordinates are set, but position doesn't change because the parent is the same and the entity is anchored.
NOTE: I only fixed the EntityCoordinates overload. Unsure if this is even a problem with MapCoordinates.
It would do .EndsWidth(), so DropDownDebugConsole and DebugConsole would get confused.
It now properly checks for path separators and also will report an error if there are two candidate XAML files.
Also, fixed the AXN0003 diagnostic having the wrong name.
* Added unit tests for the new anchor system design.
* Amend ME!
* SnapGridComponent now anchors the entity when added or removed.
TransformComponent.Anchored properly replicates it's state to clients.
* Converted all SnapGridPositionChangedEvent subscriptions to AnchorStateChangedEvent.
Removed SnapGridPositionChangedEvent.
Obsoleted SnapGridComponent.
* Allows setting Transform.Anchored in prototypes.
* Changing tile to empty under anchored ents unanchors them.
* More unit testing.
* Migrated transform gamestate tests to RobustServerSimulation.
* Fixed nasty off-by-one error when sending a full server state.
* Adds lifetime stages to Component.
* More test fixing.
* Review changes.
* Implement subscription ordering into EventBus.
* Topological helpers, rest of code uses shared topological sort, fix bugs.
* Fix tests.
Didn't realize that multi-subscriptions are allowed on input handlers like that??
* Improve and use topological sort helpers more.
No weird-ass bug this time. There was also an issue where occasionally the AABB on the client would disappear if you had a bunch of objects and used showbb but I think it's fixed now.
1. Allow loading audio directly from a sample buffer
2. SetVolumeDirect that takes a 0 -> 1 scale similar to OpenAL's AL_GAIN.
3. Fix OpenAL threading bugs with logging by caching the sawmill.
* IComponentManager holds a reference to IComponentFactory.
* Directed events for a same <TComp, TEvent> can be duplicated, component references of a component are added to the entity's event tables.
* Fix tests.
* Improvements, duplicated subscriptions are no more
* Cache component factory for faster access
* when the
* Automatically unsubscribe event bus registrations in entity system shutdown.
* Fix incorrect unsubscription of local events, obsolete unsubscribe methods.
That's what we got tests for.
* = null instead of .Clear()
- Recipients is now of type `IEnumerable<ICommonSession>`.
- This way, people need to use the Filter API to modify the recipients, instead of being allowed to modify the underlying collection directly.
- Underlying collection is now a HashSet.
- We want no duplicates at all. This will ensure that while being quite performant.
- Removes `IFilter`.
- Let's face it, everyone is gonna end up using `Filter` instead as it has a much more convenient API, and nothing else will EVER implement `IFilter`. For this reason, I've just gone ahead and removed it. Every method used `Filter` already, anyway.
- Adds EntitySystem `RaiseNetworkEvent` overload that takes in a `Filter`.
- This deduplicates a lot of code that enumerated the recipients and raised a network event per each one.
- Made AddPlayersByPvs aware of `net.pvs` and `net.maxupdaterange`, has a range multiplier parameter.
- Now it will simply add all players to the filter if PVS is disabled, and add all players in range if it's enabled.
- The range multiplier parameter allows us to make the PVS filter a bit more permissive, and generally better. The range is doubled by default, as it was already before.
- Adds `AddInRange` method to filters.
- This is useful for the AudioSystem, and the PVS methods use it, too!
- Adds `RemoveByVisibility` method to filters.
- This will remove all recipients that don't have a visibility flag in their entity's EyeComponent from the filter.
- (This will be VERY useful for Ghost Pointing, for example)
- Adds `Clone` method to filters.
- This is useful in cases where methods take in a filter and want to modify it without modifying the original instance. (See AudioSystem)
* Add serialization write benchmark
* Add baseline test and rename AddNode to Add in mapping extensions
* Optimize serialization writing
* Make reader delegate private
* Unhardcode baseline test
* Removed SnapGridOffset, there is only center now.
* SnapGridComponent methods are now static.
* Removed SnapGridComponent.OnPositionChanged.
* Refactored static functions off SnapGridComponent to MapGrid.
Refactored away usages of SnapGridComponent.Position.
* Added Transform.Anchored for checking if an entity is a tile entity.
More refactoring for static MapGrid functions.
* Static snapgrid methods on MapGrid are no longer static.
* Removed IMapGrid.SnapSize, it is now always equal to the IMapGrid.TileSize.
* Add setter to ITransformComponent.Anchored.
Removed direct references to SnapGridComponent from content.
* Grid functions now deal with EntityUids instead of SnapGridComponents.
Began renaming public API functions from SnapGrid to Anchor.
* Add some unit tests.
* SnapGridComponent now anchors itself in startup, instead of Initialize (sending directed events in init is an error).
* Make serialization work with backing fields automatically
* Fix not taking priorities into account, make the test fail when that is the case
* Turn fieldDefs back into a list
* Format it better
* Remove GetInheritanceBehaviour, expose immutable array of base field definitions
* Refactors EntityManager to not do any networking.
ServerEntityManager and ClientEntityManager now do the networking instead.
* Rename property for "backwards compat."
* Remove comented out code in robust server simulation
* Refactors MapManager to not do any networking.
Now, ServerMapManager and ClientMapManager handle any networking.
* it's christmas in april!
* Remove comented line
* Remove useless seal
* Fix incorrect semicolon
* Event is no longer overriden, has a protected Invoke method instead
* Split entity lookups from entitymanager
* Helps if you subscribe dingus
* Handle map changes
* Stacks instead
* Make mapchanges use a queue because it's probably better
Moves likely only care about the latest position
* IoC what you did there
* IoC refactor
* Minor optimisations
* Apply feedback
* My IQ dropped 3 sizes that day
* Rest of acruid's feedback
* final_no_actual commit
* enlightenment?
* Liftoff
* final_commit_v2_actual
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
* Add Robust.Benchmarks and read string benchmark
* Separate serialization manager methods, use compiled lambdas to call manager read
4 us > 200 ns
* Add int and data definition with string benchmarks
* Make serialization population use expressions to create definitions
* Make benchmark classes internal and create seed data definition
* Add complex data definition read benchmark
* Create primitive serializers, remove primitive special case
| Method | Mean | Error | StdDev |
|----------------------- |------------:|----------:|----------:|
| ReadString | 227.1 ns | 4.47 ns | 5.65 ns |
| ReadInteger | 245.4 ns | 4.82 ns | 6.26 ns |
| ReadDataDefWithString | 804.7 ns | 15.27 ns | 16.34 ns |
| ReadSeedDataDefinition | 15,846.8 ns | 312.89 ns | 773.39 ns |
* Remove testing code
* Setup delegates during initialize
* Revert "Setup delegates during initialize"
This reverts commit 7ff4d4eaaa.
* Store delegates in a concurrent dictionary because I really cannot be arsed to generate them on initialize at this point
* Wrapped the parallel GetMail function in a try/catch.
Added a hack to the ViewCulling leave message that skips ents that don't exist.
Always send ALL map and grid entities to the client.
More info logging about adding/removing maps/grids.
* Will now still send required map critical entities even if client is not attached to an entity.
PvsEnabled and PvsRange are now writeable.
* Adds barbones culling.
* Visibility culling and recursive parent ent additions.
DebugEntityNetView improvements.
Visibility moved from session to eyecomponent.
* Multiple viewport support.
* Perf improvements.
* Removed old netbubble system from ServerEntityManager.
Supports old NaN system for entities leaving view.
Supports old SendFullMap optimization for anchored, non-updating Entities.
* Fixes size of netView box.
* Remove empty EntityManager.Update method.
Switching ViewCulling back to PLINQ.
Removes NetId methods from IEntity, content does not need to be messing with them.
Fixes bug in DeleteComponent where the ComponentDeleted event was not being raised if a component did not have a NetId.
* Added an entity lifetime levels property.
Added exception when recursively deleting an entity.
* Add a directed event 'EntityTerminatingEvent' for right before an entity is deleted.
* Added MapInit lifestage to entities.
retires DataFieldWithConstantAttribute & DataFieldWithFlagAttribute in favor of new customtypeserializers
adds prototypeidvalidation, just needs to be added to the corresponding fields
fixes some behaviour in yamllinter
* Added new ComponentEventBus, combined it with IEventBus.
* Removed all traces of IEntity from ComponentDependencies.
Removed IEntityManager dependency from ComponentManager.
* Added entity create/delete events to IEntityManager.
* ComponentEvents now use EntitySystemMessages instead of their custom ComponentEvent class.
* Component events are now just overloads of entity events.
* Removed obsolete EntitySystemMessage, now everything uses the base EntityEventArgs.
* Add a bool argument for if the message should be broadcast as well as directed.
Fix ordering and init issues of events in EntityManager.
* Changed names from Component/Entity events to Directed/Broadcast.
* Fix bugs and unit tests.
The idea was that these are Task.Run'd so don't influence performance. That was before we started threading the hell out of startup.
We're getting more stuff like YAML linting now which should hopefully be able to catch 99% of this. And louder because it was always just a warning before.
* AAAAAAAAAAAAA
* Organization
* Still doesnt work
* Formatting
* It works!!
* More changes to everything
* Beginning of changes to overlays
* Makes the overlay manager GUID based (also it was very messy, still messy but i fixed some of it)
* Stencils are easy
* Questionable changes to overlays
* Minor change to HLR
* Fixed duplicate overlays when calling some commands (Like showbb)
* Fixes misleading message
* Adds a variety of worldspaces for overlays to choose from
* Caching
* Address reviews
* Merging pains
* ah.
* ahhhhh
* minor overlaymanager changes
* Work
* fix
* Merge??
* Fixes null errors
* Force update
* Delete whatever the fuck this is?
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
1. Stop using NJsonSchema, it didn't do anything useful.
2. Use System.Text.Json instead of Newtonsoft.Json.
3. General cleanup of the code, using arrays instead of lists, etc...
* Physics worlds
* Paul's a good boy
* Build working
* Ingame and not lagging to hell
* Why didn't you commit ahhhhh
* Hard collisions working
* Solver parity
* Decent broadphase work done
* BroadPhase outline done
* BroadPhase working
* waiting for pvs
* Fix static PVS AABB
* Stop static bodies from awakening
* Optimise a bunch of stuff
* Even more broadphase stuff
* I'm fucking stupid
* Optimise fixture updates
* Collision solver start
* Building
* A is for Argumentative
* Fix contact caching island flags
* Circle shapes actually workeded
* Damping
* DS2 consumables only
* Slightly more stable
* Even slightlier more stablier
* VV your heart out
* Initial joint support
* 90% of joints I just wanted to push as I'd scream if I lost progress
* JOINT PURGATORY
* Joints barely functional lmao
* Okay these joints slightly more functional
* Remove station FrictionJoint
* Also that
* Some Box2D ports
* Cleanup mass
* Edge shape
* Active contacts
* Fix active contacts
* Optimise active contacts even more
* Boxes be stacking
* I would die for smug oh my fucking god
* In which everything is fixed
* Distance joints working LETS GO
* Remove frequency on distancejoint
* Fix some stuff and break joints
* Crashing fixed mehbeh
* ICollideSpecial and more resilience
* auto-clear
* showbb vera
* Slap that TODO in there
* Fix restartround crash
* Random fixes
* Fix fixture networking
* Add intersection method for broadphase
* Fix contacts
* Licenses done
* Optimisations
* Fix wall clips
* Config caching for island
* allocations optimisations
* Optimise casts
* Optimise events queue for physics
* Contact manager optimisations
* Optimise controllers
* Sloth joint or something idk
* Controller graph
* Remove content cvar
* Random cleanup
* Finally remove VirtualController
* Manifold structs again
* Optimise this absolute retardation
* Optimise
* fix license
* Cleanup physics interface
* AHHHHHHHHHHHHH
* Fix collisions again
* snivybus
* Fix potential nasty manifold bug
* Tests go snivy
* Disable prediction for now
* Spans
* Fix ShapeTypes
* fixes
* ch ch changeesss
* Kinematic idea
* Prevent static bodies from waking
* Pass WorldAABB to MoveEvent
* Fix collisions
* manifold structs fucking WOOORRKKKINNGGG
* Better pushing
* Fix merge ickies
* Optimise MoveEvents
* Use event for collisions performance
* Fix content tests
* Do not research tests
* Fix most conflicts
* Paul's trying to kill me
* Maybe collisions work idk
* Make us whole again
* Smug is also trying to kill me
* nani
* shitty collisions
* Settling
* Do not research collisions
* SHIP IT
* Fix joints
* PVS moment
* Fix other assert
* Fix locker collisions
* serializable sleeptime
* Aether2D contacts
* Physics is no longer crashing (and burning)
* Add to the TODO list
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
* oops
* fixes serialization il
* copytest
* typo & misc fixes
* 139 moment
* boxing
* mesa dum
* stuff
* goodbye bad friend
* last commit before the big (4) rewrite
* adds datanodes
* kills yamlobjserializer in favor of the new system
* adds more serializers, actually implements them & removes most of the last of the old system
* changed yamlfieldattribute namespace
* adds back iselfserialize
* refactors consts&flags
* renames everything to data(field/definition)
* adds afterserialization
* help
* dataclassgen
* fuggen help me mannen
* Fix most errors on content
* Fix engine errors except map loader
* maploader & misc fix
* misc fixes
* thing
* help
* refactors datanodes
* help me mannen
* Separate ITypeSerializer into reader and writer
* Convert all type serializers
* priority
* adds alot
* il fixes
* adds robustgen
* argh
* adds array & enum serialization
* fixes dataclasses
* adds vec2i / misc fixes
* fixes inheritance
* a very notcursed todo
* fixes some custom dataclasses
* push dis
* Remove data classes
* boutta box
* yes
* Add angle and regex serializer tests
* Make TypeSerializerTest abstract
* sets up ioc etc
* remove pushinheritance
* fixes
* Merge fixes, fix yaml hot reloading
* General fixes2
* Make enum serialization ignore case
* Fix the tag not being copied in data nodes
* Fix not properly serializing flag enums
* Fix component serialization on startup
* Implement ValueDataNode ToString
* Serialization IL fixes, fix return and string equality
* Remove async from prototype manager
* Make serializing unsupported node as enum exception more descriptive
* Fix serv3 tryread casting to serializer instead of reader
* Add constructor for invalid node type exception
* Temporary fix for SERV3: Turn populate delegate into regular code
* Fix not copying the data of non primitive types
* Fix not using the data definition found in copying
* Make ISerializationHooks require explicit implementations
* Add test for serialization inheritance
* Improve IsOverridenIn method
* Fix error message when a data definition is null
* Add method to cast a read value in Serv3Manager
* Rename IServ3Manager to ISerializationManager
* Rename usages of serv3manager, add generic copy method
* Fix IL copy method lookup
* Rename old usages of serv3manager
* Add ITypeCopier
* resistance is futile
* we will conquer this codebase
* Add copy method to all serializers
* Make primitive mismatch error message more descriptive
* bing bong im going to freacking heck
* oopsie moment
* hello are you interested in my wares
* does generic serializers under new architecture
* Convert every non generic serializer to the new format, general fixes
* Update usgaes of generic serializers, cleanup
* does some pushinheritance logic
* finishes pushinheritance FRAMEWORK
* shed
* Add box2, color and component registry serializer tests
* Create more deserialized types and store prototypes with their deserialized results
* Fixes and serializer updates
* Add serialization manager extensions
* adds pushinheritance
* Update all prototypes to have a parent and have consistent id/parent properties
* Fix grammar component serialization
* Add generic serializer tests
* thonk
* Add array serializer test
* Replace logger warning calls with exceptions
* fixes
* Move redundant methods to serialization manager extensions, cleanup
* Add array serialization
* fixes context
* more fixes
* argh
* inheritance
* this should do it
* fixes
* adds copiers & fixes some stuff
* copiers use context v1
* finishing copy context
* more context fixes
* Test fixes
* funky maps
* Fix server user interface component serialization
* Fix value tuple serialization
* Add copying for value types and arrays. Fix copy internal for primitives, enums and strings
* fixes
* fixes more stuff
* yes
* Make abstract/interface skips debugs instead of warnings
* Fix typo
* Make some dictionaries readonly
* Add checks for the serialization manager initializing and already being initialized
* Add base type required and usage for MeansDataDefinition and ImplicitDataDefinitionForInheritorsAttribute
* copy by ref
* Fix exception wording
* Update data field required summary with the new forbidden docs
* Use extension in map loader
* wanna erp
* Change serializing to not use il temporarily
* Make writing work with nullable types
* pushing
* check
* cuddling slaps HARD
* Add serialization priority test
* important fix
* a serialization thing
* serializer moment
* Add validation for some type serializers
* adds context
* moar context
* fixes
* Do the thing for appearance
* yoo lmao
* push haha pp
* Temporarily make copy delegate regular c# code
* Create deserialized component registry to handle not inheriting conflicting references
* YAML LINTER BABY
* ayes
* Fix sprite component norot not being default true like in latest master
* Remove redundant todos
* Add summary doc to every ISerializationManager method
* icon fixes
* Add skip hook argument to readers and copiers
* Merge fixes
* Fix ordering of arguments in read and copy reflection call
* Fix user interface components deserialization
* pew pew
* i am going to HECK
* Add MustUseReturnValue to copy-over methods
* Make serialization log calls use the same sawmill
* gamin
* Fix doc errors in ISerializationManager.cs
* goodbye brave soldier
* fixes
* WIP merge fixes and entity serialization
* aaaaaaaaaaaaaaa
* aaaaaaaaaaaaaaa
* adds inheritancebehaviour
* test/datafield fixes
* forgot that one
* adds more verbose validation
* This fixes the YAML hot reloading
* Replace yield break with Enumerable.Empty
* adds copiers
* aaaaaaaaaaaaa
* array fix
priority fix
misc fixes
* fix(?)
* fix.
* funny map serialization (wip)
* funny map serialization (wip)
* Add TODO
* adds proper info the validation
* Make yaml linter 5 times faster (~80% less execution time)
* Improves the error message for missing fields in the linter
* Include component name in unknown component type error node
* adds alwaysrelevant usa
* fixes mapsaving
* moved surpressor to analyzers proj
* warning cleanup & moves surpressor
* removes old msbuild targets
* Revert "Make yaml linter 5 times faster (~80% less execution time)"
This reverts commit 2ee4cc2c26.
* Add serialization to RobustServerSimulation and mock reflection methods
Fixes container tests
* Fix nullability warnings
* Improve yaml linter message feedback
* oops moment
* Add IEquatable, IComparable, ToString and operators to DataPosition
Rename it to NodeMark
Make it a readonly struct
* Remove try catch from enum parsing
* Make dependency management in serialization less bad
* Make dependencies an argument instead of a property on the serialization manager
* Clean up type serializers
* Improve validation messages and resourc epath checking
* Fix sprite error message
* reached perfection
Co-authored-by: Paul <ritter.paul1+git@googlemail.com>
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
Co-authored-by: Vera Aguilera Puerto <zddm@outlook.es>
* Adds the SoundSystem static proxy class for the AudioSystem.
Added a shared IAudioSystem interface for the future.
* Moved ConnectedClient property from IPlayerSession down to ICommonSession.
* Connected up the SoundSystem to the client/server AudioSystems.
* Converted client calls over to the new system.
* Marked the old serverside functions to play sound obsolete, use the new ones from the IAudioSystem.
* Added ISharedPlayerManager to the IoC registration.
* Added a basic server simulation framework for help with tests.
* Moved as much as possible to Robust.Shared/Containers.
Moved ContainerSlot from content to engine.
* Moved ClientContainer to shared.
* Merged client/server ContainerManagerComponents into a single shared version.
* ContainerManagerComponent is now implicitly registered with the attributes.
* Migrated to 2021 serialization technology.
* Existing Unit Tests work.
* More tests coverage.
Fixed bug with transferring items between containers.
* Container Type info is now sent over the network.
* Merge client/server container systems.
* Code cleanup.
* Attempted to fix dictionary serialization.
Logs warning when trying to check if an unknown GridId is paused.
* Remove OldCode.
* Physics worlds
* Paul's a good boy
* Build working
* Ingame and not lagging to hell
* Why didn't you commit ahhhhh
* Hard collisions working
* Solver parity
* Decent broadphase work done
* BroadPhase outline done
* BroadPhase working
* waiting for pvs
* Fix static PVS AABB
* Stop static bodies from awakening
* Optimise a bunch of stuff
* Even more broadphase stuff
* I'm fucking stupid
* Optimise fixture updates
* Collision solver start
* Building
* A is for Argumentative
* Fix contact caching island flags
* Circle shapes actually workeded
* Damping
* DS2 consumables only
* Slightly more stable
* Even slightlier more stablier
* VV your heart out
* Initial joint support
* 90% of joints I just wanted to push as I'd scream if I lost progress
* JOINT PURGATORY
* Joints barely functional lmao
* Okay these joints slightly more functional
* Remove station FrictionJoint
* Also that
* Some Box2D ports
* Cleanup mass
* Edge shape
* Active contacts
* Fix active contacts
* Optimise active contacts even more
* Boxes be stacking
* I would die for smug oh my fucking god
* In which everything is fixed
* Distance joints working LETS GO
* Remove frequency on distancejoint
* Fix some stuff and break joints
* Crashing fixed mehbeh
* ICollideSpecial and more resilience
* auto-clear
* showbb vera
* Slap that TODO in there
* Fix restartround crash
* Random fixes
* Fix fixture networking
* Add intersection method for broadphase
* Fix contacts
* Licenses done
* Optimisations
* Fix wall clips
* Config caching for island
* allocations optimisations
* Optimise casts
* Optimise events queue for physics
* Contact manager optimisations
* Optimise controllers
* Sloth joint or something idk
* Controller graph
* Remove content cvar
* Random cleanup
* Finally remove VirtualController
* Manifold structs again
* Optimise this absolute retardation
* Optimise
* fix license
* Cleanup physics interface
* AHHHHHHHHHHHHH
* Fix collisions again
* snivybus
* Fix potential nasty manifold bug
* Tests go snivy
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
* Removed IBaseSession, pushed all members down to ICommonSession.
* Pulled all members of client IPlayerSession into ICommonSession.
Marked client IPlayerSession as obsolete, use the base ICommonSession.
* Restricted setter access for properties in ICommonSession, only engine should be setting them.
* Fixed ping implementation on server.
* Moved AttachedEntityUid to ICommonSession.
* Added a shared IPlayerManager and pulled some common properties down to it.
* Added a shared player Filter class that holds a set of recipients in a networked call. Very useful for selecting recipients in a shared context.
* Added support for erasing rectangular areas
* Apply suggestions from code review
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
* Switched sending start coordinate + end coordinate to sending start coordinate + rect selection size for preventing different parented positions, general code improvements
* Rewritten certain code part so the checks pass
* Added unshaded shader to rect erasing
* Tweaked alpha of erasing rectangle for better visualizing
Co-authored-by: Manel Navola <ManelNavola@users.noreply.github.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
*Allow content to define localization functions.
* Add rldloc command to reload localizations.
* Doc comments
* Error handling
* Parallelize loading of localization files, since I can only assume we'll have a lot eventually.
* Type system stuff to allow content to pass custom data types into fluent.
* Code cleanup.
This makes Direction no longer follow a cartesian trig circle but oh well. Also helper methods to work with this.
Math tests currently fail, pushing this so Acruid can see about fixing SpriteComponent.
* Added documentation to Clyde on the sprite rendering calls.
* Added a rotation debug entity.
* Non-directional RSIs and raw textures are now rotated properly.
* Directional RSIs and Sprite Smoothing work.
* Remove the Directional flag usages.
* Supports layers with different numbers of directions.
* Fixes window rendering.
* Implement hot reloading for entity prototypes
* Implement automatic prototype hot-reloading
* Merge fixes
* Add yaml hot reloading and a message to notify the client
* Add reloading only changed files, remove cooldown, add retries and remove IPrototype
* Remove reload command
* Make the client listen for reloads instead and only when focused
* Fix errors
* Only queue a reload when the queue has items in it
* Make fails after 10 retries log instead of throw if reloading
Co-authored-by: Jackson Lewis <inquisitivepenguin@protonmail.com>
* Moved IPauseManager from server to shared.
* Moved ITimerManager from Timers to Timing.
* Added missing IConsoleHost to server/client RegisterIoC. Tests work again.
1. Add XAML namespaces https://spacestation14.io with Avalonia hacks.
2. Make markup extensions work with Avalonia hacks.
3. Add LocExtension for localized strings.
4. Add Vector2 parsing type converter to XAML compilation.
5. Make SS14Window better thanks to these improvements.
* #272 no arrow, actually change id on channel changer
* #272 ability to apply style class to child
* #272 try methods for selecting items in OptionButton.cs
* #272 allow escaping right angle bracket in formatted message
* #272 ability to detect when local player is set / unset
* #272 make RemoveModal public since PushModal is as well, so modals can be removed on-demand if needed rather than relying on a click elsewhere
* #272 revert
* Add SerializedType attribute to serialize types without the !type tag
* Fix nulls in tests
* Fix null in tests maybe
* Return to type tags
* Fix imports
* Removed the Interfaces folder.
* All objects inside the GameObjects subfolders are now in the GameObjects namespace.
* Added a Resharper DotSettings file to mark the GameObjects subfolders as not providing namespaces.
* Simplified Robust.client.Graphics namespace.
* Automated remove redundant using statements.
Lidgren NetTime.Now is now synchronized to IGameTiming.RealTime.
NetChannel is now a nested class of NetManager.
Add IGameTiming.ServerTime, INetChannel.RemoteTimeOffset, INetChannel.RemoteTime
* Renamed shared ICommand to IConsoleCommand.
* Lots of refactoring into a shared context.
* Removed ICommonSession from server concmd Execute.
* Added argStr parameter to concmd execute.
* The execute function of client concmds now returns void, use the new shell.RemoteExecuteCommand function to forward commands.
# Conflicts:
# Robust.Client/Console/Commands/Debug.cs
* Finally move shells and commands into shared.
* Console commands can now be registered directly without a class in a shared context.
* Pulled up ConsoleHost and Console shell into a shared context.
* Pulled up half the functions of ConsoleHost into a shared context.
* Repair rebase damage.
* Make LoadConsoleCommands function not remove any previously registered commands.
* Remove the main viewport.
* Re-add main viewport in a different place
* Move screen/map translation into ViewportContainer
* Support for viewport resolution
* Fix postfx, add WorldToScreen to Viewport
* Remove useless cast
* Some cleanup.
* Fix incorrect worldBounds when rendering viewports
* nullability
Co-authored-by: 20kdc <asdd2808@gmail.com>
* Add TryCastValue to CollectionExtensions.cs
* Change TryCastValue to be more generic
* Add notnull constraing for TKey to TryCastValue
Co-authored-by: Julian Giebel <j.giebel@netrocks.info>
Someone please performance-test this, but I think the fragment shader code simplifications speak for themselves.
Radrark found the "line in polar coordinates" equation I needed and a diagram that explained the variables.
That equation was essentially the missing piece to the whole thing.
1. Set timeBeginPeriod(3) on the server to reduce scheduler latency in the lidgren thread.
2. Add 16ms of guaranteed lag bias to client prediction calculations to account for scheduler latency.
Both of these changes are to account for how the windows scheduler seems to handle time periods in related to socket polls. See this Discord conversation for why, details down below as well: https://discord.com/channels/310555209753690112/770682801607278632/798309250291204107
Basically Windows has this thing called time periods which determines the precision of sleep operations and such. By default it's like 16ms so a sleep will only be accurate to within 16ms.
Problem: Lidgren polls the socket with a timeout of 1ms.
The way Windows seems to handle this is that:
1. if a message comes into the socket, the poll immediately ends and Lidgren can handle it.
2. If nothing comes in, it takes the whole 16ms time period to actually process stuff.
Oh yeah, and Lidgren's thread needs to keep pumping at a steady rate or else it *won't flush its send queue*. On Windows it seems to normally pump at 65/125 Hz. On Linux it goes like 950 Hz as intended.
Now, the worst part is that (1) causes Lidgren's latency calculation to always read 0 (over localhost) instead of the 30~ms it SHOULD BE (assuming client and server localhost).
That 30ms of unaccounted delay worst caseis enough to cause prediction undershoot and have messages arrive too late. Yikes.
So, to fix this...
On the server we just decrease the tick period and call it a day. Screw your battery life players don't have local servers running anyways.
On the client we bias the prediction calculations to account for this "unmeasurable" lag.
Of course, all this can be configured via CVars.
2021-01-12 02:43:15 +01:00
1745 changed files with 131215 additions and 44039 deletions
Robust Toolbox is an engine primarily being developed for [Space Station 14](https://github.com/space-wizards/space-station-14), although we're working on making it usable for both [singleplayer](https://github.com/space-wizards/RobustToolboxTemplateSingleplayer) and [multiplayer](https://github.com/space-wizards/RobustToolboxTemplate) projects.
Robust Toolbox is a client/server backend for [Space Station 14](https://github.com/space-wizards/space-station-14).
Use the [content repo](https://github.com/space-wizards/space-station-14) for actual development, even if you're modifying the engine itself.
### *This repository is the *engine* section of SS14. This is the base engine all SS14 servers will be built on. As such, it does not start on its own: it needs the [content repo](https://github.com/space-wizards/space-station-14). Use said repo for actual development, even if you're modifying the engine itself. Think of Robust Toolbox as BYOND in the context of Spacestation 13.*
The IRC is setup to relay back and forth to the Discord server so [IRC nerds](https://xkcd.com/1782/) will not be left out.
## Documentation
We have various technical documentation articles on the [HackMD Wiki](https://hackmd.io/@ss14/docs/%2F%40ss14%2Ftechnical-documentation-overview).
The [wiki](https://docs.spacestation14.io/) has documentation on SS14s content, engine, game design and more. We also have lots of resources for new contributors to the project.
## Contributing
@@ -27,8 +18,8 @@ We are happy to accept contributions from anybody. Get in Discord or IRC if you
## Building
**In practice, you usually don't build this repository directly.**
This repository is the **engine** part of SS14. It's the base engine all SS14 servers will be built on. As such, it does not start on its own: it needs the [content repo](https://github.com/space-wizards/space-station-14). Think of Robust Toolbox as BYOND in the context of Spacestation 13.
## Legal Info
See `legal.md` for licenses and copyright.
See [legal.md](https://github.com/space-wizards/RobustToolbox/blob/master/legal.md) for licenses and copyright.
cmd-parse-failure-integer = {$arg} is not a valid integer.
cmd-parse-failure-float = {$arg} is not a valid float.
cmd-parse-failure-bool = {$arg} is not a valid bool.
## 'help' command
cmd-help-desc = Display general help or help text for a specific command
cmd-help-help = Usage: help [command name]
When no command name is provided, displays general-purpose help text. If a command name is provided, displays help text for that command.
cmd-help-no-args = To display help for a specific command, write 'help <command>'. To list all available commands, write 'list'. To search for commands, use 'list <filter>'.
cmd-help-unknown = Unknown command: { $command }
cmd-help-top = { $command } - { $description }
cmd-help-invalid-args = Invalid amount of arguments.
cmd-help-arg-cmdname = [command name]
## 'cvar' command
cmd-cvar-desc = Gets or sets a CVar.
cmd-cvar-help = Usage: cvar <name | ?> [value]
If a value is passed, the value is parsed and stored as the new value of the CVar.
If not, the current value of the CVar is displayed.
Use 'cvar ?' to get a list of all registered CVars.
cmd-cvar-invalid-args = Must provide exactly one or two arguments.
cmd-cvar-not-registered = CVar '{ $cvar }' is not registered. Use 'cvar ?' to get a list of all registered CVars.
cmd-cvar-parse-error = Input value is in incorrect format for type { $type }
cmd-cvar-compl-list = List available CVars
cmd-cvar-arg-name = <name | ?>
cmd-cvar-value-hidden = <value hidden>
## 'list' command
cmd-list-desc = Lists available commands, with optional search filter
cmd-list-help = Usage: list [filter]
Lists all available commands. If an argument is provided, it will be used to filter commands by name.
cmd-list-heading = SIDE NAME DESC{"\u000A"}-------------------------{"\u000A"}
Executes a command on the server. This is necessary if a command with the same name exists on the client, as simply running the command would run the client command first.
## 'gc' command
cmd-gc-desc = Run the GC (Garbage Collector)
cmd-gc-help = Usage: gc [generation]
Uses GC.Collect() to execute the Garbage Collector.
If an argument is provided, it is parsed as a GC generation number and GC.Collect(int) is used.
Use the 'gfc' command to do an LOH-compacting full GC.
cmd-gc-failed-parse = Failed to parse argument.
cmd-gc-arg-generation = [generation]
## 'gcf' command
cmd-gcf-desc = Run the GC, fully, compacting LOH and everything.
cmd-gcf-help = Usage: gcf
Does a full GC.Collect(2, GCCollectionMode.Forced, true, true) while also compacting LOH.
This will probably lock up for hundreds of milliseconds, be warned.
## 'gc_mode' command
cmd-gc_mode-desc = Change/Read the GC Latency mode
cmd-gc_mode-help = Usage: gc_mode [type]
If no argument is provided, returns the current GC latency mode.
If an argument is passed, it is parsed as GCLatencyMode and set as the GC latency mode.
cmd-gc_mode-current = current gc latency mode: { $prevMode }
public void TestTypeNobodyCanRead(TypeNobodyCanRead obj)
{
// None of these accesses should be allowed.
var copy = Data;
var copy2 = this.Data;
var copy3 = obj.Data;
copy = Data;
copy = this.Data;
copy = obj.Data;
var copy4 = Data.MyField;
var copy5 = this.Data.MyField;
var copy6 = obj.Data.MyField;
if (Data == copy) {}
if (this.Data == copy) {}
if (obj.Data == copy) {}
if(Data.MyField == 0) {}
if(this.Data.MyField == 0) {}
if(obj.Data.MyField == 0) {}
// All of these accesses should be fine.
var copy7 = Data2;
var copy8 = this.Data2;
var copy9 = obj.Data2;
copy = Data2;
copy = this.Data2;
copy = obj.Data2;
var copy10 = Data2.MyField;
var copy11 = this.Data2.MyField;
var copy12 = obj.Data2.MyField;
if (Data2 == copy) {}
if (this.Data2 == copy) {}
if (obj.Data2 == copy) {}
if(Data2.MyField == 0) {}
if(this.Data2.MyField == 0) {}
if(obj.Data2.MyField == 0) {}
}
}
[Access(typeof(FriendlyClass),
Self = AccessPermissions.Read,
Friend = AccessPermissions.Read,
Other = AccessPermissions.Read)]
public sealed class MemberNobodyCanRead
{
[Access(typeof(FriendlyClass),
Self = AccessPermissions.None,
Friend = AccessPermissions.None,
Other = AccessPermissions.None)]
public MyData Data = default;
public MyData Data2 = default;
public void TestMemberNobodyCanRead(TypeNobodyCanRead obj)
{
// None of these accesses should be allowed.
var copy = Data;
var copy2 = this.Data;
var copy3 = obj.Data;
copy = Data;
copy = this.Data;
copy = obj.Data;
var copy4 = Data.MyField;
var copy5 = this.Data.MyField;
var copy6 = obj.Data.MyField;
if (Data == copy) {}
if (this.Data == copy) {}
if (obj.Data == copy) {}
if(Data.MyField == 0) {}
if(this.Data.MyField == 0) {}
if(obj.Data.MyField == 0) {}
// All of these accesses should be fine.
var copy7 = Data2;
var copy8 = this.Data2;
var copy9 = obj.Data2;
copy = Data2;
copy = this.Data2;
copy = obj.Data2;
var copy10 = Data2.MyField;
var copy11 = this.Data2.MyField;
var copy12 = obj.Data2.MyField;
if (Data2 == copy) {}
if (this.Data2 == copy) {}
if (obj.Data2 == copy) {}
if(Data2.MyField == 0) {}
if(this.Data2.MyField == 0) {}
if(obj.Data2.MyField == 0) {}
}
}
public sealed class FriendlyClass
{
public void TestTypeNobodyCanRead(TypeNobodyCanRead obj)
{
// We shouldn't be able to access any of these, even if we're a friend..
var copy = obj.Data;
copy = obj.Data;
var copy2 = obj.Data.MyField;
copy2 = obj.Data.MyField;
if (obj.Data == copy) {}
if(obj.Data.MyField == 0) {}
// We should be allowed to access all of these, we're friends!
var copy3 = obj.Data2;
copy = obj.Data2;
var copy4 = obj.Data2.MyField;
copy4 = obj.Data2.MyField;
if(obj.Data2 == copy) {}
if(obj.Data2.MyField == 0) {}
}
public void TestMemberNobodyCanRead(MemberNobodyCanRead obj)
{
// We shouldn't be able to access any of these, even if we're a friend..
var copy = obj.Data;
copy = obj.Data;
var copy2 = obj.Data.MyField;
copy2 = obj.Data.MyField;
if (obj.Data == copy) {}
if(obj.Data.MyField == 0) {}
// We should be allowed to access all of these, we're friends!
var copy3 = obj.Data2;
copy = obj.Data2;
var copy4 = obj.Data2.MyField;
copy4 = obj.Data2.MyField;
if(obj.Data2 == copy) {}
if(obj.Data2.MyField == 0) {}
}
}
public sealed class OtherClass
{
public void TestTypeNobodyCanRead(TypeNobodyCanRead obj)
{
// We shouldn't be able to access any of these, as 'other types' can't..
var copy = obj.Data;
copy = obj.Data;
var copy2 = obj.Data.MyField;
copy2 = obj.Data.MyField;
if (obj.Data == copy) {}
if(obj.Data.MyField == 0) {}
// We should be allowed to access all of these, they let others read it!
var copy3 = obj.Data2;
copy = obj.Data2;
var copy4 = obj.Data2.MyField;
copy4 = obj.Data2.MyField;
if(obj.Data2 == copy) {}
if(obj.Data2.MyField == 0) {}
}
public void TestMemberNobodyCanRead(MemberNobodyCanRead obj)
{
// We shouldn't be able to access any of these, as 'other types' can't..
var copy = obj.Data;
copy = obj.Data;
var copy2 = obj.Data.MyField;
copy2 = obj.Data.MyField;
if (obj.Data == copy) {}
if(obj.Data.MyField == 0) {}
// We should be allowed to access all of these, they let others read it!
var copy3 = obj.Data2;
copy = obj.Data2;
var copy4 = obj.Data2.MyField;
copy4 = obj.Data2.MyField;
if(obj.Data2 == copy) {}
if(obj.Data2.MyField == 0) {}
}
}";
awaitVerifier(code,
// AUTO-GENERATED DIAGNOSTICS BELOW //
// /0/Test0.cs(35,20): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(36,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(37,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(39,16): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(40,16): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(41,16): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(43,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(44,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(45,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(47,13): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(48,13): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(49,13): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(51,12): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(52,12): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(53,12): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(95,20): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(96,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(97,21): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(99,16): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(100,16): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(101,16): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(103,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(104,21): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(105,21): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(107,13): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(108,13): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(109,13): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(111,12): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(112,12): error RA0002: Tried to perform a 'Read' same-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(113,12): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(143,20): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(144,16): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(146,21): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(147,17): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(149,13): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(150,12): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(166,20): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(167,16): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(169,21): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(170,17): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(172,13): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(173,12): error RA0002: Tried to perform a 'Read' friend-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(192,20): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(193,16): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(195,21): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(196,17): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(198,13): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(199,12): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'TypeNobodyCanRead', despite having no access. Type Permissions: ---------
// /0/Test0.cs(215,20): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(216,16): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(218,21): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(219,17): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(221,13): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
// /0/Test0.cs(222,12): error RA0002: Tried to perform a 'Read' other-type access to member 'Data' in type 'MemberNobodyCanRead', despite having no access. Member Permissions: ---------
public void TestTypeNobodyCanWrite(TypeNobodyCanWrite obj)
{
// None of these accesses should be allowed.
Data = default;
this.Data = default;
obj.Data = default;
Data.MyField = 0;
this.Data.MyField = 0;
obj.Data.MyField = 0;
// All of these accesses should be fine.
Data2 = default;
this.Data2 = default;
obj.Data2 = default;
Data2.MyField = 0;
this.Data2.MyField = 0;
obj.Data2.MyField = 0;
}
}
[Access(typeof(FriendlyClass),
Self = AccessPermissions.Write,
Friend = AccessPermissions.Write,
Other = AccessPermissions.Write)]
public sealed class MemberNobodyCanWrite
{
[Access(typeof(FriendlyClass),
Self = AccessPermissions.None,
Friend = AccessPermissions.None,
Other = AccessPermissions.None)]
public MyData Data = default;
public MyData Data2 = default;
public void TestMemberNobodyCanWrite(TypeNobodyCanWrite obj)
{
// None of these accesses should be allowed.
Data = default;
this.Data = default;
obj.Data = default;
Data.MyField = 0;
this.Data.MyField = 0;
obj.Data.MyField = 0;
// All of these accesses should be fine.
Data2 = default;
this.Data2 = default;
obj.Data2 = default;
Data2.MyField = 0;
this.Data2.MyField = 0;
obj.Data2.MyField = 0;
}
}
public sealed class FriendlyClass
{
public void TestTypeNobodyCanWrite(TypeNobodyCanWrite obj)
{
// We shouldn't be able to access any of these, even if we're a friend..
obj.Data = default;
obj.Data.MyField = 0;
// We should be allowed to access all of these, we're friends!
obj.Data2 = default;
obj.Data2.MyField = 0;
}
public void TestMemberNobodyCanWrite(MemberNobodyCanWrite obj)
{
// We shouldn't be able to access any of these, even if we're a friend..
obj.Data = default;
obj.Data.MyField = 0;
// We should be allowed to access all of these, we're friends!
obj.Data2 = default;
obj.Data2.MyField = 0;
}
}
public sealed class OtherClass
{
public void TestTypeNobodyCanWrite(TypeNobodyCanWrite obj)
{
// We shouldn't be able to access any of these, as 'other types' can't..
obj.Data = default;
obj.Data.MyField = 0;
// We should be allowed to access all of these, they let others write!
obj.Data2 = default;
obj.Data2.MyField = 0;
}
public void TestMemberNobodyCanWrite(MemberNobodyCanWrite obj)
{
// We shouldn't be able to access any of these, as 'other types' can't..
obj.Data = default;
obj.Data.MyField = 0;
// We should be allowed to access all of these, they let others write!
obj.Data2 = default;
obj.Data2.MyField = 0;
}
}";
awaitVerifier(code,
// AUTO-GENERATED DIAGNOSTICS BELOW //
// /0/Test0.cs(34,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(35,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(36,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(38,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(39,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(40,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(70,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
// /0/Test0.cs(71,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
// /0/Test0.cs(72,9): error RA0002: Tried to perform a 'Write' other-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(74,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
// /0/Test0.cs(75,9): error RA0002: Tried to perform a 'Write' same-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
// /0/Test0.cs(76,9): error RA0002: Tried to perform a 'Write' other-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(94,9): error RA0002: Tried to perform a 'Write' friend-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(95,9): error RA0002: Tried to perform a 'Write' friend-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(105,9): error RA0002: Tried to perform a 'Write' friend-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
// /0/Test0.cs(106,9): error RA0002: Tried to perform a 'Write' friend-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
// /0/Test0.cs(119,9): error RA0002: Tried to perform a 'Write' other-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(120,9): error RA0002: Tried to perform a 'Write' other-type access to member 'Data' in type 'TypeNobodyCanWrite', despite having no access. Type Permissions: ---------
// /0/Test0.cs(130,9): error RA0002: Tried to perform a 'Write' other-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
// /0/Test0.cs(131,9): error RA0002: Tried to perform a 'Write' other-type access to member 'Data' in type 'MemberNobodyCanWrite', despite having no access. Member Permissions: ---------
public void TestTypeNobodyCanExecute(TypeNobodyCanExecute obj)
{
// None of these accesses should be allowed.
MyMethod();
this.MyMethod();
obj.MyMethod();
Data.MyMethod();
this.Data.MyMethod();
obj.Data.MyMethod();
Data.MyField.ToString();
this.Data.MyField.ToString();
obj.Data.MyField.ToString();
// All of these accesses should be fine.
MyMethod2();
this.MyMethod2();
obj.MyMethod2();
Data2.MyMethod();
this.Data2.MyMethod();
obj.Data2.MyMethod();
Data2.MyField.ToString();
this.Data2.ToString();
obj.Data2.ToString();
}
}
[Access(typeof(FriendlyClass),
Self = AccessPermissions.Execute,
Friend = AccessPermissions.Execute,
Other = AccessPermissions.Execute)]
public sealed class MemberNobodyCanExecute
{
[Access(typeof(FriendlyClass),
Self = AccessPermissions.None,
Friend = AccessPermissions.None,
Other = AccessPermissions.None)]
public MyData Data = default;
public MyData Data2 = default;
[Access(typeof(FriendlyClass),
Self = AccessPermissions.None,
Friend = AccessPermissions.None,
Other = AccessPermissions.None)]
public void MyMethod() {}
public void MyMethod2() {}
public void TestMemberNobodyCanExecute(TypeNobodyCanExecute obj)
{
// None of these accesses should be allowed.
MyMethod();
this.MyMethod();
obj.MyMethod();
Data.MyMethod();
this.Data.MyMethod();
obj.Data.MyMethod();
Data.MyField.ToString();
this.Data.MyField.ToString();
obj.Data.MyField.ToString();
// All of these accesses should be fine.
MyMethod2();
this.MyMethod2();
obj.MyMethod2();
Data2.MyMethod();
this.Data2.MyMethod();
obj.Data2.MyMethod();
Data2.MyField.ToString();
this.Data2.ToString();
obj.Data2.ToString();
}
}
public sealed class FriendlyClass
{
public void TestTypeNobodyCanExecute(TypeNobodyCanExecute obj)
{
// We shouldn't be able to access any of these, even if we're a friend..
obj.MyMethod();
obj.Data.MyMethod();
obj.Data.MyField.ToString();
// We should be allowed to access all of these, we're friends!
obj.MyMethod2();
obj.Data2.MyMethod();
obj.Data2.MyField.ToString();
}
public void TestMemberNobodyCanExecute(MemberNobodyCanExecute obj)
{
// We shouldn't be able to access any of these, even if we're a friend..
obj.MyMethod();
obj.Data.MyMethod();
obj.Data.MyField.ToString();
// We should be allowed to access all of these, we're friends!
obj.MyMethod2();
obj.Data2.MyMethod();
obj.Data2.MyField.ToString();
}
}
public sealed class OtherClass
{
public void TestTypeNobodyCanExecute(TypeNobodyCanExecute obj)
{
// We shouldn't be able to access any of these, as 'other types' can't..
obj.MyMethod();
obj.Data.MyMethod();
obj.Data.MyField.ToString();
// We should be allowed to access all of these, they let others Execute!
obj.MyMethod2();
obj.Data2.MyMethod();
obj.Data2.MyField.ToString();
}
public void TestMemberNobodyCanExecute(MemberNobodyCanExecute obj)
{
// We shouldn't be able to access any of these, as 'other types' can't..
obj.MyMethod();
obj.Data.MyMethod();
obj.Data.MyField.ToString();
// We should be allowed to access all of these, they let others Execute!
obj.MyMethod2();
obj.Data2.MyMethod();
obj.Data2.MyField.ToString();
}
}";
awaitVerifier(code,
// AUTO-GENERATED DIAGNOSTICS BELOW //
// /0/Test0.cs(44,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'MyMethod' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(45,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'MyMethod' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(46,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'MyMethod' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(48,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(49,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(50,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(52,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(53,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(54,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(96,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'MyMethod' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(97,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'MyMethod' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(98,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'MyMethod' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(100,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(101,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(102,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(104,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(105,9): error RA0002: Tried to perform an 'Execute' same-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(106,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(128,9): error RA0002: Tried to perform an 'Execute' friend-type access to member 'MyMethod' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(129,9): error RA0002: Tried to perform an 'Execute' friend-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(130,9): error RA0002: Tried to perform an 'Execute' friend-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(141,9): error RA0002: Tried to perform an 'Execute' friend-type access to member 'MyMethod' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(142,9): error RA0002: Tried to perform an 'Execute' friend-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(143,9): error RA0002: Tried to perform an 'Execute' friend-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(157,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'MyMethod' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(158,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(159,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'Data' in type 'TypeNobodyCanExecute', despite having no access. Type Permissions: ---------
// /0/Test0.cs(170,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'MyMethod' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(171,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
// /0/Test0.cs(172,9): error RA0002: Tried to perform an 'Execute' other-type access to member 'Data' in type 'MemberNobodyCanExecute', despite having no access. Member Permissions: ---------
"Accessing Task<T>.Result is dangerous and can cause deadlocks in some contexts. If you understand how this works and are certain that you aren't causing a deadlock here, mute this error with #pragma.",
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.