Skip to content

Commit

Permalink
added CSteamID serializer for ModularRPCs.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielWillett committed Oct 10, 2024
1 parent e87fb57 commit 1986202
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 109 deletions.
1 change: 1 addition & 0 deletions UncreatedWarfare.Tests/UncreatedWarfare.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="coverlet.collector" Version="3.0.2" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.7.1" NoWarn="NU1605"/>

<PackageReference Include="Autofac" Version="7.1.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.2.0" />
Expand Down
94 changes: 1 addition & 93 deletions UncreatedWarfare/Commands/_DebugCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.ExceptionServices;
using DanielWillett.ModularRpcs.Serialization;
using Uncreated.Warfare.Interaction.Commands;
using Uncreated.Warfare.Locations;
using Uncreated.Warfare.Players.Permissions;
using Uncreated.Warfare.StrategyMaps;
using Uncreated.Warfare.Translations;
using Uncreated.Warfare.Util;

#if DEBUG
Expand Down Expand Up @@ -135,99 +135,7 @@ public async UniTask ExecuteAsync(CancellationToken token)

#pragma warning disable IDE1006
#pragma warning disable IDE0051
private void glfromloc()
{
Context.AssertRanByPlayer();

Vector3 position = Context.Player.UnturnedPlayer.quests.isMarkerPlaced
? Context.Player.UnturnedPlayer.quests.markerPosition
: Context.Player.Position;

Context.ReplyString($"Found gl: {new GridLocation(in position)} from pos {position:F3}.");
}

private void gltoloc()
{
Context.AssertRanByPlayer();

if (!Context.TryGet(0, out string? str) || !GridLocation.TryParse(str, out GridLocation gl))
{
throw Context.SendCorrectUsage("/test gltoloc <grid location>");
}

Context.ReplyString($"Found center: {gl.Center:F3} from gl {gl}.");

EffectAsset? squadLeaderEmpty = Assets.find<EffectAsset>(new Guid("dc95d06e787e4a069518e0487645ed6b"));

if (squadLeaderEmpty == null)
throw Context.SendUnknownError();
EffectUtility.TriggerEffect(squadLeaderEmpty, Context.Player.Connection, gl.Center, true);
}

private void barricadecarto()
{
Context.AssertRanByPlayer();

if (!Context.TryGetBarricadeTarget(out BarricadeDrop? barricade))
{
throw Context.ReplyString("Look at barricade.");
}

if (!Context.TryGet(0, out float xOffset) || !Context.TryGet(1, out float yOffset) || !Context.TryGet(2, out float zOffset) || !Context.TryGet(3, out float xSize) || !Context.TryGet(4, out float ySize))
{
throw Context.SendCorrectUsage("/test barricadecarto <<look at barricade>> <offset: x y z> <size: x y>");
}

Vector3 offset = new Vector3(xOffset, yOffset, zOffset);
Vector2 size = new Vector2(xSize, ySize);

Matrix4x4 transformationMatrix = StrategyMap.ProjectWorldCoordsToMapTable(barricade.model, offset, size);

EffectAsset? squadLeaderEmpty = Assets.find<EffectAsset>(new Guid("dc95d06e787e4a069518e0487645ed6b"));

if (squadLeaderEmpty == null)
throw Context.SendUnknownError();

Vector3 position = Context.Player.UnturnedPlayer.quests.isMarkerPlaced
? Context.Player.UnturnedPlayer.quests.markerPosition
: Context.Player.Position;

Context.ReplyString($"Position: {position:F3}.");

Vector3 pt = transformationMatrix.MultiplyPoint3x4(position);

EffectUtility.TriggerEffect(squadLeaderEmpty, Context.Player.Connection, pt, true);

Context.ReplyString($"Found point: {pt:F3} and spawned effect from pos {position:F3}.");
}

private void carto()
{
Context.AssertRanByPlayer();

Vector3 pos = Context.Player.Position;
Context.ReplyString($"Location: {pos}.");

Vector3 worldToMap = CartographyUtility.WorldToMap.MultiplyPoint3x4(pos);
Vector2 denormalized = CartographyUtility.DenormalizeMapCoordinates(worldToMap);

Context.ReplyString($"Normalized: {worldToMap}, denormalized: {denormalized}, renormalized: {CartographyUtility.NormalizeMapCoordinates(denormalized)}.");

Context.ReplyString($"Converted back: {CartographyUtility.MapToWorld.MultiplyPoint3x4(worldToMap)}.");

ILogger<DebugCommand> logger = _serviceProvider.GetRequiredService<ILogger<DebugCommand>>();

logger.LogInformation("m2w: " + Environment.NewLine + CartographyUtility.WorldToMap.ToString("F3"));
logger.LogInformation("m2wt: " + CartographyUtility.WorldToMap.GetPosition().ToString("F3"));
logger.LogInformation("m2wr: " + CartographyUtility.WorldToMap.GetRotation().eulerAngles.ToString("F3"));
logger.LogInformation("m2ws: " + CartographyUtility.WorldToMap.lossyScale.ToString("F3"));
logger.LogInformation("w2m: " + Environment.NewLine + CartographyUtility.MapToWorld.ToString("F3"));
logger.LogInformation("w2mt: " + CartographyUtility.MapToWorld.GetPosition().ToString("F3"));
logger.LogInformation("w2mr: " + CartographyUtility.MapToWorld.GetRotation().eulerAngles.ToString("F3"));
logger.LogInformation("w2ms: " + CartographyUtility.MapToWorld.lossyScale.ToString("F3"));
logger.LogInformation("Img size: " + CartographyUtility.MapImageSize);
//logger.LogInformation("Cpt size: " + CartographyUtility.CaptureAreaSize.ToString("F3"));
}
#if false
private const string UsageGiveXp = "/test givexp <player> <amount> [team - required if offline]";
private async UniTask givexp(CancellationToken token)
Expand Down
12 changes: 4 additions & 8 deletions UncreatedWarfare/FOBs/FOBManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,11 @@ public void HandleEvent(ItemDropped e, IServiceProvider serviceProvider)

public void HandleEvent(MeleeHit e, IServiceProvider serviceProvider)
{
Console.WriteLine("punching");

if (e.Equipment?.asset?.GUID == null)
if (e.Equipment?.asset == null)
return;

Console.WriteLine("Got Equipment asset");

IAssetLink<ItemAsset>? entrenchingTool = _assetConfiguration.GetAssetLink<ItemAsset>("Items:EntrenchingTool");
if (entrenchingTool.GetAssetOrFail().GUID != e.Equipment.asset.GUID)

IAssetLink<ItemAsset> entrenchingTool = _assetConfiguration.GetAssetLink<ItemAsset>("Items:EntrenchingTool");
if (entrenchingTool.MatchAsset(e.Equipment.asset))
return;

RaycastInfo info = DamageTool.raycast(new Ray(e.Look.aim.position, e.Look.aim.forward), 2, RayMasks.BARRICADE, e.Player.UnturnedPlayer);
Expand Down
105 changes: 105 additions & 0 deletions UncreatedWarfare/Networking/Parsers/CSteamIDSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using DanielWillett.ModularRpcs.Annotations;
using DanielWillett.ModularRpcs.Configuration;
using DanielWillett.ModularRpcs.Exceptions;
using DanielWillett.ModularRpcs.Serialization;
using System;
using System.Buffers.Binary;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Uncreated.Warfare.Networking.Parsers;

/// <summary>
/// Binary serializer for <see cref="CSteamID"/> to use with Modular RPCs.
/// </summary>
[RpcParser(typeof(CSteamID))]
public class CSteamIDSerializer : BinaryTypeParser<CSteamID>
{
private static readonly MethodInfo SetErrorCodeOvf = typeof(RpcOverflowException)
.GetProperty(nameof(RpcOverflowException.ErrorCode), BindingFlags.Public | BindingFlags.Instance)!
.GetSetMethod(true);
private static readonly MethodInfo SetErrorCodeParse = typeof(RpcParseException)
.GetProperty(nameof(RpcParseException.ErrorCode), BindingFlags.Public | BindingFlags.Instance)!
.GetSetMethod(true);

public override bool IsVariableSize => false;
public override int MinimumSize => 8;
public override unsafe int WriteObject(CSteamID value, byte* bytes, uint maxSize)
{
if (maxSize < 8)
{
RpcOverflowException ex = new RpcOverflowException("The buffer overflowed while writing from the binary type parser: 'CSteamIDSerializer'.");
SetErrorCodeOvf.Invoke(ex, [ 1 ]);
throw ex;
}

if (BitConverter.IsLittleEndian)
{
Unsafe.WriteUnaligned(bytes, value);
}
else
{
Unsafe.WriteUnaligned(bytes, BinaryPrimitives.ReverseEndianness(value.m_SteamID));
}

return 8;
}

public override int WriteObject(CSteamID value, Stream stream)
{
if (BitConverter.IsLittleEndian)
{
stream.Write(MemoryMarshal.Cast<CSteamID, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1)));
}
else
{
Span<byte> span = stackalloc byte[8];
ulong rev = BinaryPrimitives.ReverseEndianness(value.m_SteamID);
MemoryMarshal.Write(span, ref rev);
}

return 8;
}

public override unsafe CSteamID ReadObject(byte* bytes, uint maxSize, out int bytesRead)
{
if (maxSize < 8)
{
RpcParseException ex = new RpcParseException("The RpcOverhead failed to parse a message because the buffer was too short while reading from the binary type parser: 'CSteamIDSerializer'.");
SetErrorCodeParse.Invoke(ex, [ 1 ]);
throw ex;
}

ulong value = Unsafe.ReadUnaligned<ulong>(bytes);

if (!BitConverter.IsLittleEndian)
value = BinaryPrimitives.ReverseEndianness(value);

bytesRead = 8;
return Unsafe.As<ulong, CSteamID>(ref value);
}

public override CSteamID ReadObject(Stream stream, out int bytesRead)
{
Span<byte> span = stackalloc byte[8];
int ct = stream.Read(span);
bytesRead = ct;
if (ct != 8)
{
RpcParseException ex = new RpcParseException("The RpcOverhead failed to parse a message because the stream ended too early while reading from the binary type parser: 'CSteamIDSerializer'.");
SetErrorCodeParse.Invoke(ex, [ 2 ]);
throw ex;
}

ulong value = MemoryMarshal.Read<ulong>(span);

if (!BitConverter.IsLittleEndian)
value = BinaryPrimitives.ReverseEndianness(value);

return Unsafe.As<ulong, CSteamID>(ref value);
}

public class Many(SerializationConfiguration config) : UnmanagedValueTypeBinaryArrayTypeParser<CSteamID>(config);
}
9 changes: 5 additions & 4 deletions UncreatedWarfare/UncreatedWarfare.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<PropertyGroup>

<VersionPrefix>4.0.0</VersionPrefix>
<VersionBuild>001</VersionBuild>
<VersionBuild>002</VersionBuild>
<VersionSuffix>prerelease$(VersionBuild)</VersionSuffix>

</PropertyGroup>
Expand Down Expand Up @@ -137,9 +137,9 @@
<PackageReference Include="DanielWillett.SpeedBytes" Version="[1.1.2,)" />
<PackageReference Include="DanielWillett.SpeedBytes.Unity" Version="[1.1.1,)" />
<PackageReference Include="DanielWillett.JavaPropertiesParser" Version="[1.0.0,)" />
<PackageReference Include="DanielWillett.ModularRPCs" Version="[1.0.0-prerelease02, 2)" />
<PackageReference Include="DanielWillett.ModularRPCs.Unity" Version="[1.0.0-prerelease02, 2)" />
<PackageReference Include="DanielWillett.ModularRPCs.WebSockets" Version="[1.0.0-prerelease02, 2)" />
<PackageReference Include="DanielWillett.ModularRPCs" Version="[1.0.0-prerelease04, 2)" />
<PackageReference Include="DanielWillett.ModularRPCs.Unity" Version="[1.0.0-prerelease03, 2)" />
<PackageReference Include="DanielWillett.ModularRPCs.WebSockets" Version="[1.0.0-prerelease03, 2)" />
<PackageReference Include="Uncreated.UI" Version="[1.0.0,)" />
<PackageReference Include="Stripe.net" Version="[43.4.0,)" />
<PackageReference Include="JetBrains.Annotations" Version="[2018.2.1,)" Aliases="JetBrains" />
Expand All @@ -156,6 +156,7 @@
<PackageReference Include="System.Text.Json" Version="4.7.1" NoWarn="NU1605" />

<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.7.1" NoWarn="NU1605" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.3" />
Expand Down
25 changes: 21 additions & 4 deletions UncreatedWarfare/WarfareModule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DanielWillett.ModularRpcs.DependencyInjection;
using DanielWillett.ModularRpcs.Serialization;
using DanielWillett.ReflectionTools;
using DanielWillett.ReflectionTools.IoC;
using Microsoft.EntityFrameworkCore;
Expand Down Expand Up @@ -50,6 +51,7 @@
using Uncreated.Warfare.Squads;
using Uncreated.Warfare.Squads.UI;
using Uncreated.Warfare.Steam;
using Uncreated.Warfare.StrategyMaps;
using Uncreated.Warfare.Teams;
using Uncreated.Warfare.Translations;
using Uncreated.Warfare.Translations.Languages;
Expand All @@ -59,7 +61,6 @@
using Uncreated.Warfare.Vehicles.Events;
using Uncreated.Warfare.Zones;
using Module = SDG.Framework.Modules.Module;
using Uncreated.Warfare.StrategyMaps;

namespace Uncreated.Warfare;
public sealed class WarfareModule : IModuleNexus
Expand Down Expand Up @@ -318,6 +319,12 @@ void IModuleNexus.shutdown()
private void ConfigureServices(ContainerBuilder bldr)
{
Assembly thisAsm = Assembly.GetExecutingAssembly();
Module thisModule = ModuleHook.modules.First(x => x.config.Name.Equals("Uncreated.Warfare", StringComparison.Ordinal) && x.assemblies.Contains(thisAsm));

// all module assemblies and plugins
Assembly[] relevantAssemblies = thisModule.assemblies
.Concat(_pluginLoader.Plugins.Select(x => x.LoadedAssembly))
.ToArray();

bldr.RegisterType<MapScheduler>()
.AsSelf().AsImplementedInterfaces()
Expand All @@ -340,14 +347,20 @@ private void ConfigureServices(ContainerBuilder bldr)
bldr.RegisterFromCollection(collection =>
{
collection.AddReflectionTools();
collection.AddModularRpcs(isServer: false, searchedAssemblies: [Assembly.GetExecutingAssembly()]);
collection.AddModularRpcs(
isServer: false,
(_, configuration, parsers, _) =>
{
parsers.RegisterParserAttributes(configuration, relevantAssemblies);
},
searchedAssemblies: relevantAssemblies
);
});

bldr.RegisterInstance(this)
.As<WarfareModule>()
.ExternallyOwned();

Module thisModule = ModuleHook.modules.First(x => x.config.Name.Equals("Uncreated.Warfare", StringComparison.Ordinal) && x.assemblies.Contains(thisAsm));
bldr.RegisterInstance(thisModule)
.As<Module>()
.ExternallyOwned();
Expand Down Expand Up @@ -1002,6 +1015,10 @@ private void UnloadModule()
return typeof(Vector3).Assembly;
}

const string compUnsafe = "System.Runtime.CompilerServices.Unsafe";
if (args.Name.StartsWith(compUnsafe, StringComparison.Ordinal))
return typeof(System.Runtime.CompilerServices.Unsafe).Assembly;

return null;
}
}
}

0 comments on commit 1986202

Please sign in to comment.