Skip to content

Commit

Permalink
Merge branch 'master' into detached-uid
Browse files Browse the repository at this point in the history
  • Loading branch information
metalgearsloth authored Jan 29, 2025
2 parents 46ab308 + 5d77207 commit a8d4879
Show file tree
Hide file tree
Showing 79 changed files with 1,767 additions and 579 deletions.
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<PackageVersion Include="SpaceWizards.Sodium" Version="0.2.1" />
<PackageVersion Include="TerraFX.Interop.Windows" Version="10.0.26100.1" />
<PackageVersion Include="TerraFX.Interop.Xlib" Version="6.4.0" />
<PackageVersion Include="VorbisPizza" Version="1.4.2" />
<PackageVersion Include="VorbisPizza" Version="1.3.0" />
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
<PackageVersion Include="prometheus-net" Version="8.2.1" />
<PackageVersion Include="prometheus-net.DotNetRuntime" Version="4.4.0" />
Expand Down
2 changes: 1 addition & 1 deletion MSBuild/Robust.Engine.Version.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<!-- This file automatically reset by Tools/version.py -->
<PropertyGroup><Version>239.0.0</Version></PropertyGroup>
<PropertyGroup><Version>241.0.0</Version></PropertyGroup>
</Project>
Expand Down
93 changes: 92 additions & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ END TEMPLATE-->
### Breaking changes

* The order in which the client initialises networked entities has changed. It will now always apply component states, initialise, and start an entity's parent before processing any children. This might break anything that was relying on the old behaviour where all component states were applied before any entities were initialised & started.
* `IClydeViewport` overlay rendering methods now take in an `IRenderHandle` instead of a world/screen handle.
* The `OverlayDrawArgs` struct now has an internal constructor.

### New features

*None yet*
* Controls can now be manually restyled via `Control.InvalidateStyleSheet()` and `Control.DoStyleUpdate()`
* Added `IUserInterfaceManager.RenderControl()` for manually drawing controls.
* `OverlayDrawArgs` struct now has an `IRenderHandle` field such that overlays can use the new `RenderControl()` methods.

### Bugfixes

Expand All @@ -54,6 +58,93 @@ END TEMPLATE-->
*None yet*


## 241.0.0

### Breaking changes

* Remove DeferredClose from BUIs.

### New features

* Added `EntityManager.DirtyFields()`, which allows components with delta states to simultaneously mark several fields as dirty at the same time.
* Add `CloserUserUIs<T>` to close keys of a specific key.

### Bugfixes

* Fixed `RaisePredictiveEvent()` not properly re-raising events during prediction for event handlers that did not take an `EntitySessionEventArgs` argument.
* BUI openings are now deferred to avoid having slight desync between deferred closes and opens occurring in the same tick.


## 240.1.2


## 240.1.1

### Bugfixes

* Fixed one of the `IOverlayManager.RemoveOverlay` overrides not fully removing the overlay.


## 240.1.0

### New features

* Added an `AsNullable` extension method for converting an `Entity<T>` into an `Entity<T?>`

### Bugfixes

* Fixed an exception in `PhysicsSystem.DestroyContacts()` that could result in entities getting stuck with broken physics.

### Other

* `GamePrototypeLoadManager` will now send all uploaded prototypes to connecting players in a single `GamePrototypeLoadMessage`, as opposed to one message per upload.


## 240.0.1

### Bugfixes

* Fixed `SharedBroadphaseSystem.GetBroadphases()` not returning the map itself, which was causing physics to not work properly off-grid.


## 240.0.0

### Breaking changes

* `ComponentRegistry` no longer implements `ISerializationContext`
* Tickrate values are now `ushort`, allowing them to go up to 65535.

### New features

* Console completion options now have new flags for preventing suggestions from being escaped or quoted.
* Added `ILocalizationManager.HasCulture()`.
* Static `EntProtoId<T>` fields are now validated to exist.

### Bugfixes

* Fixed a state handling bug in replays, which was causing exceptions to be thrown when applying delta states.

### Other

* Reduced amount of `DynamicMethod`s used by serialization system. This should improve performance somewhat.

### Internal

* Avoided sorting overlays every render frame.
* Various clean up to grid fixture code/adding asserts.

## 239.0.1

### Bugfixes

* Fix logging of received packets with `net.packet` logging level.
* Downgrade `VorbisPizza` to fix audio playback for systems without AVX2 support.

### Other

* Improved performance of some Roslyn analyzers and source generators, which should significantly improve compile times and IDE performance.


## 239.0.0

### Breaking changes
Expand Down
114 changes: 114 additions & 0 deletions Robust.Analyzers.Tests/ByRefEventAnalyzerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using NUnit.Framework;
using VerifyCS =
Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier<Robust.Analyzers.ByRefEventAnalyzer, Microsoft.CodeAnalysis.Testing.DefaultVerifier>;

namespace Robust.Analyzers.Tests;

[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
[TestFixture, TestOf(typeof(ByRefEventAnalyzer))]
public sealed class ByRefEventAnalyzerTest
{
private const string EventBusDef = """
namespace Robust.Shared.GameObjects;
public readonly struct EntityUid;
public sealed class EntitySystem
{
public void RaiseLocalEvent<TEvent>(EntityUid uid, ref TEvent args, bool broadcast = false)
where TEvent : notnull { }
public void RaiseLocalEvent<TEvent>(EntityUid uid, TEvent args, bool broadcast = false)
where TEvent : notnull { }
}
public sealed class EntityEventBus
{
public void RaiseLocalEvent<TEvent>(EntityUid uid, ref TEvent args, bool broadcast = false)
where TEvent : notnull { }
public void RaiseLocalEvent<TEvent>(EntityUid uid, TEvent args, bool broadcast = false)
where TEvent : notnull { }
}
""";

private static Task Verifier(string code, params DiagnosticResult[] expected)
{
var test = new CSharpAnalyzerTest<ByRefEventAnalyzer, DefaultVerifier>()
{
TestState =
{
Sources = { code }
},
};

TestHelper.AddEmbeddedSources(
test.TestState,
"Robust.Shared.GameObjects.EventBusAttributes.cs"
);

test.TestState.Sources.Add(("EntityEventBus.cs", EventBusDef));

// ExpectedDiagnostics cannot be set, so we need to AddRange here...
test.TestState.ExpectedDiagnostics.AddRange(expected);

return test.RunAsync();
}

[Test]
public async Task TestSuccess()
{
const string code = """
using Robust.Shared.GameObjects;
[ByRefEvent]
public readonly struct RefEvent;
public readonly struct ValueEvent;
public static class Foo
{
public static void Bar(EntityEventBus bus)
{
bus.RaiseLocalEvent(default(EntityUid), new ValueEvent());
var refEv = new RefEvent();
bus.RaiseLocalEvent(default(EntityUid), ref refEv);
}
}
""";

await Verifier(code);
}

[Test]
public async Task TestWrong()
{
const string code = """
using Robust.Shared.GameObjects;
[ByRefEvent]
public readonly struct RefEvent;
public readonly struct ValueEvent;
public static class Foo
{
public static void Bar(EntityEventBus bus)
{
bus.RaiseLocalEvent(default(EntityUid), new RefEvent());
var valueEv = new ValueEvent();
bus.RaiseLocalEvent(default(EntityUid), ref valueEv);
}
}
""";

await Verifier(
code,
// /0/Test0.cs(11,49): error RA0015: Tried to raise a by-ref event 'RefEvent' by value
VerifyCS.Diagnostic(ByRefEventAnalyzer.ByRefEventRaisedByValueRule).WithSpan(11, 49, 11, 63).WithArguments("RefEvent"),
// /0/Test0.cs(13,49): error RA0016: Tried to raise a value event 'ValueEvent' by-ref
VerifyCS.Diagnostic(ByRefEventAnalyzer.ByValueEventRaisedByRefRule).WithSpan(13, 49, 13, 60).WithArguments("ValueEvent")
);
}
}
4 changes: 4 additions & 0 deletions Robust.Analyzers.Tests/ComponentPauseGeneratorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public sealed partial class FooComponent : IComponent
public partial class FooComponent
{
[RobustAutoGenerated]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
public sealed class FooComponent_AutoPauseSystem : EntitySystem
{
public override void Initialize()
Expand Down Expand Up @@ -106,6 +107,7 @@ public sealed partial class FooComponent : IComponent
public partial class FooComponent
{
[RobustAutoGenerated]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
public sealed class FooComponent_AutoPauseSystem : EntitySystem
{
public override void Initialize()
Expand Down Expand Up @@ -147,6 +149,7 @@ public sealed partial class FooComponent : IComponent
public partial class FooComponent
{
[RobustAutoGenerated]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
public sealed class FooComponent_AutoPauseSystem : EntitySystem
{
public override void Initialize()
Expand Down Expand Up @@ -188,6 +191,7 @@ public sealed partial class FooComponent : IComponent
public partial class FooComponent
{
[RobustAutoGenerated]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
public sealed class FooComponent_AutoPauseSystem : EntitySystem
{
public override void Initialize()
Expand Down
1 change: 1 addition & 0 deletions Robust.Analyzers.Tests/Robust.Analyzers.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<EmbeddedResource Include="..\Robust.Shared\Analyzers\PreferNonGenericVariantForAttribute.cs" LogicalName="Robust.Shared.Analyzers.PreferNonGenericVariantForAttribute.cs" LinkBase="Implementations" />
<EmbeddedResource Include="..\Robust.Shared\Analyzers\PreferOtherTypeAttribute.cs" LogicalName="Robust.Shared.Analyzers.PreferOtherTypeAttribute.cs" LinkBase="Implementations" />
<EmbeddedResource Include="..\Robust.Shared\IoC\DependencyAttribute.cs" LogicalName="Robust.Shared.IoC.DependencyAttribute.cs" LinkBase="Implementations" />
<EmbeddedResource Include="..\Robust.Shared\GameObjects\EventBusAttributes.cs" LogicalName="Robust.Shared.GameObjects.EventBusAttributes.cs" LinkBase="Implementations" />
</ItemGroup>

<PropertyGroup>
Expand Down
54 changes: 33 additions & 21 deletions Robust.Analyzers/ByRefEventAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
Expand All @@ -24,7 +24,7 @@ public sealed class ByRefEventAnalyzer : DiagnosticAnalyzer
"Make sure that methods subscribing to a ref event have the ref keyword for the event argument."
);

private static readonly DiagnosticDescriptor ByRefEventRaisedByValueRule = new(
public static readonly DiagnosticDescriptor ByRefEventRaisedByValueRule = new(
Diagnostics.IdByRefEventRaisedByValue,
"By-ref event raised by value",
"Tried to raise a by-ref event '{0}' by value",
Expand All @@ -34,7 +34,7 @@ public sealed class ByRefEventAnalyzer : DiagnosticAnalyzer
"Make sure to use the ref keyword when raising ref events."
);

private static readonly DiagnosticDescriptor ByValueEventRaisedByRefRule = new(
public static readonly DiagnosticDescriptor ByValueEventRaisedByRefRule = new(
Diagnostics.IdValueEventRaisedByRef,
"Value event raised by-ref",
"Tried to raise a value event '{0}' by-ref",
Expand All @@ -54,32 +54,44 @@ public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.EnableConcurrentExecution();
context.RegisterOperationAction(CheckEventRaise, OperationKind.Invocation);
context.RegisterCompilationStartAction(compilationContext =>
{
var raiseMethods = compilationContext.Compilation
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntitySystem")?
.GetMembers()
.Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method)
.Cast<IMethodSymbol>();

var busRaiseMethods = compilationContext.Compilation
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntityEventBus")?
.GetMembers()
.Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method)
.Cast<IMethodSymbol>();

if (raiseMethods == null)
return;

if (busRaiseMethods != null)
raiseMethods = raiseMethods.Concat(busRaiseMethods);

var raiseMethodsArray = raiseMethods.ToArray();

compilationContext.RegisterOperationAction(
ctx => CheckEventRaise(ctx, raiseMethodsArray),
OperationKind.Invocation);
});
}

private void CheckEventRaise(OperationAnalysisContext context)
private static void CheckEventRaise(
OperationAnalysisContext context,
IReadOnlyCollection<IMethodSymbol> raiseMethods)
{
if (context.Operation is not IInvocationOperation operation)
return;

var raiseMethods = context.Compilation
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntitySystem")?
.GetMembers()
.Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method)
.Cast<IMethodSymbol>();

var busRaiseMethods = context.Compilation
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntityEventBus")?
.GetMembers()
.Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method)
.Cast<IMethodSymbol>();

if (raiseMethods == null)
if (!operation.TargetMethod.Name.Contains("RaiseLocalEvent"))
return;

if (busRaiseMethods != null)
raiseMethods = raiseMethods.Concat(busRaiseMethods);

if (!raiseMethods.Any(m => m.Equals(operation.TargetMethod.OriginalDefinition, Default)))
{
// If you try to do this normally by concatenating like busRaiseMethods above
Expand Down
6 changes: 3 additions & 3 deletions Robust.Client/BaseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ private void TickRateChanged(int tickrate, in CVarChangeInfo info)
{
if (GameInfo != null)
{
GameInfo.TickRate = (byte) tickrate;
GameInfo.TickRate = (ushort) tickrate;
}

_timing.SetTickRateAt((byte) tickrate, info.TickChanged);
_timing.SetTickRateAt((ushort) tickrate, info.TickChanged);
_logger.Info($"Tickrate changed to: {tickrate} on tick {_timing.CurTick}");
}

Expand Down Expand Up @@ -395,6 +395,6 @@ public ServerInfo(string serverName)
/// </summary>
public int ServerMaxPlayers { get; set; }

public byte TickRate { get; internal set; }
public uint TickRate { get; internal set; }
}
}
Loading

0 comments on commit a8d4879

Please sign in to comment.