From 693e90bff1a312ac4d8d2b2dd1192c16f05c2f5b Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sun, 27 Nov 2022 17:51:18 +0000 Subject: [PATCH] [ci skip] Add braces around single-statement bodies --- VpSharp/src/Application.cs | 10 ++- VpSharp/src/ColorF.cs | 23 +++++-- VpSharp/src/Entities/VirtualParadiseAvatar.cs | 34 +++++++--- .../Entities/VirtualParadiseModelObject.cs | 2 + .../VirtualParadiseModelObjectBuilder.cs | 21 +++++- VpSharp/src/Entities/VirtualParadiseObject.cs | 44 +++++++++++-- .../VirtualParadiseParticleEmitterObject.cs | 8 +++ .../src/Entities/VirtualParadisePathObject.cs | 4 ++ VpSharp/src/Entities/VirtualParadiseUser.cs | 14 +++- VpSharp/src/Entities/VirtualParadiseWorld.cs | 12 +++- VpSharp/src/Extensions/SpanExtensions.cs | 16 +++++ .../Attributes/ValueConverterAttribute.cs | 6 ++ VpSharp/src/Internal/Connection.cs | 36 ++++++++-- .../src/Internal/ObjectReferenceCounter.cs | 5 ++ .../Internal/ValueConverters/UriConverter.cs | 2 + .../ValueConverters/Vector2Converter.cs | 4 ++ .../ValueConverters/Vector3Converter.cs | 4 ++ .../Vector3ToColorConverter.cs | 4 ++ .../ValueConverters/Vector3dConverter.cs | 4 ++ .../Vector4ToColorConverter.cs | 4 ++ .../Vector4ToVector3Converter.cs | 4 ++ .../VectorToNthComponentConverter.cs | 6 ++ .../ValueConverters/WorldSettingsConverter.cs | 30 +++++++++ VpSharp/src/InviteRequest.cs | 30 +++++++-- VpSharp/src/JoinRequest.cs | 29 +++++++-- VpSharp/src/Scene/FluentActionComponent.cs | 11 +++- VpSharp/src/Vector3d.cs | 8 +++ VpSharp/src/VirtualParadiseClient.Native.cs | 2 + .../VirtualParadiseClient.NativeCallbacks.cs | 2 + .../src/VirtualParadiseClient.NativeEvents.cs | 24 ++++++- VpSharp/src/VirtualParadiseClient.Objects.cs | 17 ++++- VpSharp/src/VirtualParadiseClient.Users.cs | 9 ++- VpSharp/src/VirtualParadiseClient.Worlds.cs | 10 ++- VpSharp/src/VirtualParadiseClient.cs | 65 +++++++++++++++---- VpSharp/src/VirtualParadiseConfiguration.cs | 7 +- VpSharp/src/WorldSettingsBuilder.cs | 4 ++ 36 files changed, 445 insertions(+), 70 deletions(-) diff --git a/VpSharp/src/Application.cs b/VpSharp/src/Application.cs index e9b4b75..e249b56 100644 --- a/VpSharp/src/Application.cs +++ b/VpSharp/src/Application.cs @@ -14,8 +14,14 @@ public sealed class Application { Name = name ?? throw new ArgumentNullException(nameof(name)); - if (string.IsNullOrWhiteSpace(version)) Version = null; - else Version = version; + if (string.IsNullOrWhiteSpace(version)) + { + Version = null; + } + else + { + Version = version; + } } /// diff --git a/VpSharp/src/ColorF.cs b/VpSharp/src/ColorF.cs index a78f1ad..333ac95 100644 --- a/VpSharp/src/ColorF.cs +++ b/VpSharp/src/ColorF.cs @@ -116,10 +116,25 @@ public readonly struct ColorF : IEquatable /// public static ColorF FromArgb(float a, float r, float g, float b) { - if (a is < 0 or > 1) throw ThrowHelper.ZeroThroughOneException(nameof(a)); - if (r is < 0 or > 1) throw ThrowHelper.ZeroThroughOneException(nameof(r)); - if (g is < 0 or > 1) throw ThrowHelper.ZeroThroughOneException(nameof(g)); - if (b is < 0 or > 1) throw ThrowHelper.ZeroThroughOneException(nameof(b)); + if (a is < 0 or > 1) + { + throw ThrowHelper.ZeroThroughOneException(nameof(a)); + } + + if (r is < 0 or > 1) + { + throw ThrowHelper.ZeroThroughOneException(nameof(r)); + } + + if (g is < 0 or > 1) + { + throw ThrowHelper.ZeroThroughOneException(nameof(g)); + } + + if (b is < 0 or > 1) + { + throw ThrowHelper.ZeroThroughOneException(nameof(b)); + } return new ColorF(a, r, g, b); } diff --git a/VpSharp/src/Entities/VirtualParadiseAvatar.cs b/VpSharp/src/Entities/VirtualParadiseAvatar.cs index b8639a1..4e3b312 100644 --- a/VpSharp/src/Entities/VirtualParadiseAvatar.cs +++ b/VpSharp/src/Entities/VirtualParadiseAvatar.cs @@ -1,4 +1,4 @@ -using System.Numerics; +using System.Numerics; using VpSharp.Extensions; using VpSharp.Internal; using VpSharp.Internal.NativeAttributes; @@ -98,8 +98,16 @@ public sealed class VirtualParadiseAvatar : IEquatable /// public bool Equals(VirtualParadiseAvatar? other) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + return Session == other.Session && User.Equals(other.User); } @@ -130,7 +138,9 @@ public sealed class VirtualParadiseAvatar : IEquatable { // ReSharper disable once InconsistentlySynchronizedField if (this == _client.CurrentAvatar) + { return Task.FromException(ThrowHelper.CannotUseSelfException()); + } clickPoint ??= Location.Position; (double x, double y, double z) = clickPoint.Value; @@ -143,9 +153,11 @@ public sealed class VirtualParadiseAvatar : IEquatable vp_double_set(handle, FloatAttribute.ClickHitY, y); vp_double_set(handle, FloatAttribute.ClickHitZ, z); - var reason = (ReasonCode) vp_avatar_click(handle, Session); + var reason = (ReasonCode)vp_avatar_click(handle, Session); if (reason == ReasonCode.NotInWorld) + { return Task.FromException(ThrowHelper.NotInWorldException()); + } } return Task.CompletedTask; @@ -164,7 +176,9 @@ public sealed class VirtualParadiseAvatar : IEquatable // ReSharper disable once InconsistentlySynchronizedField if (this == _client.CurrentAvatar) + { return Task.FromException(ThrowHelper.CannotUseSelfException()); + } lock (_client.Lock) { @@ -248,21 +262,25 @@ public sealed class VirtualParadiseAvatar : IEquatable vp_double_set(handle, FloatAttribute.MyPitch, pitch); vp_double_set(handle, FloatAttribute.MyYaw, yaw); - var reason = (ReasonCode) vp_state_change(handle); + var reason = (ReasonCode)vp_state_change(handle); if (reason == ReasonCode.NotInWorld) + { ThrowHelper.ThrowNotInWorldException(); + } } } else { lock (_client.Lock) { - (float x, float y, float z) = (Vector3) position; - (float pitch, float yaw, float _) = (Vector3) rotation.ToEulerAngles(false); + (float x, float y, float z) = (Vector3)position; + (float pitch, float yaw, float _) = (Vector3)rotation.ToEulerAngles(false); - var reason = (ReasonCode) vp_teleport_avatar(handle, Session, world, x, y, z, yaw, pitch); + var reason = (ReasonCode)vp_teleport_avatar(handle, Session, world, x, y, z, yaw, pitch); if (reason == ReasonCode.NotInWorld) + { ThrowHelper.ThrowNotInWorldException(); + } } } diff --git a/VpSharp/src/Entities/VirtualParadiseModelObject.cs b/VpSharp/src/Entities/VirtualParadiseModelObject.cs index 1e24569..1890e5a 100644 --- a/VpSharp/src/Entities/VirtualParadiseModelObject.cs +++ b/VpSharp/src/Entities/VirtualParadiseModelObject.cs @@ -65,7 +65,9 @@ public class VirtualParadiseModelObject : VirtualParadiseObject protected internal override void ExtractFromOther(VirtualParadiseObject virtualParadiseObject) { if (virtualParadiseObject is not VirtualParadiseModelObject model) + { return; + } Action = model.Action; Description = model.Description; diff --git a/VpSharp/src/Entities/VirtualParadiseModelObjectBuilder.cs b/VpSharp/src/Entities/VirtualParadiseModelObjectBuilder.cs index bfa8e03..d1508a6 100644 --- a/VpSharp/src/Entities/VirtualParadiseModelObjectBuilder.cs +++ b/VpSharp/src/Entities/VirtualParadiseModelObjectBuilder.cs @@ -107,9 +107,20 @@ public sealed class VirtualParadiseModelObjectBuilder : VirtualParadiseObjectBui { IntPtr handle = Client.NativeInstanceHandle; - if (Action is { } action) vp_string_set(handle, StringAttribute.ObjectAction, action); - if (Description is { } description) vp_string_set(handle, StringAttribute.ObjectDescription, description); - if (Model is { } model) vp_string_set(handle, StringAttribute.ObjectModel, model); + if (Action is { } action) + { + vp_string_set(handle, StringAttribute.ObjectAction, action); + } + + if (Description is { } description) + { + vp_string_set(handle, StringAttribute.ObjectDescription, description); + } + + if (Model is { } model) + { + vp_string_set(handle, StringAttribute.ObjectModel, model); + } if (Position is { } position) { @@ -147,7 +158,9 @@ public sealed class VirtualParadiseModelObjectBuilder : VirtualParadiseObjectBui if (ModificationTimestamp is { } modificationTimestamp) { if (Mode != ObjectBuilderMode.Load) + { throw new InvalidOperationException("Modification timestamp can only be assigned during an object load."); + } vp_int_set(handle, IntegerAttribute.ObjectTime, (int) modificationTimestamp.ToUnixTimeSeconds()); } @@ -155,7 +168,9 @@ public sealed class VirtualParadiseModelObjectBuilder : VirtualParadiseObjectBui if (Owner is { } owner) { if (Mode != ObjectBuilderMode.Load) + { throw new InvalidOperationException("Owner can only be assigned during an object load."); + } vp_int_set(handle, IntegerAttribute.ObjectUserId, owner.Id); } diff --git a/VpSharp/src/Entities/VirtualParadiseObject.cs b/VpSharp/src/Entities/VirtualParadiseObject.cs index 35f79d4..82a0b19 100644 --- a/VpSharp/src/Entities/VirtualParadiseObject.cs +++ b/VpSharp/src/Entities/VirtualParadiseObject.cs @@ -77,13 +77,21 @@ public abstract class VirtualParadiseObject : IEquatable ValueTask SendBegin() { - lock (Client.Lock) vp_object_bump_begin(Client.NativeInstanceHandle, Id, session); + lock (Client.Lock) + { + vp_object_bump_begin(Client.NativeInstanceHandle, Id, session); + } + return ValueTask.CompletedTask; } ValueTask SendEnd() { - lock (Client.Lock) vp_object_bump_end(Client.NativeInstanceHandle, Id, session); + lock (Client.Lock) + { + vp_object_bump_end(Client.NativeInstanceHandle, Id, session); + } + return ValueTask.CompletedTask; } @@ -115,7 +123,9 @@ public abstract class VirtualParadiseObject : IEquatable public Task ClickAsync(Vector3d? position = null, VirtualParadiseAvatar? target = null) { if (target == Client.CurrentAvatar) + { ThrowHelper.ThrowCannotUseSelfException(); + } lock (Client.Lock) { @@ -159,17 +169,37 @@ public abstract class VirtualParadiseObject : IEquatable /// if the two objects are equal; otherwise, . public bool Equals(VirtualParadiseObject? other) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + return Location.World.Equals(other.Location.World) && Id == other.Id; } /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + return Equals((VirtualParadiseObject) obj); } diff --git a/VpSharp/src/Entities/VirtualParadiseParticleEmitterObject.cs b/VpSharp/src/Entities/VirtualParadiseParticleEmitterObject.cs index 9ed272e..a9a38df 100644 --- a/VpSharp/src/Entities/VirtualParadiseParticleEmitterObject.cs +++ b/VpSharp/src/Entities/VirtualParadiseParticleEmitterObject.cs @@ -209,7 +209,9 @@ public sealed class VirtualParadiseParticleEmitterObject : VirtualParadiseObject protected internal override void ExtractFromOther(VirtualParadiseObject virtualParadiseObject) { if (virtualParadiseObject is not VirtualParadiseParticleEmitterObject emitter) + { return; + } const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; PropertyInfo[] properties = typeof(VirtualParadiseParticleEmitterObject).GetProperties(bindingFlags); @@ -217,7 +219,9 @@ public sealed class VirtualParadiseParticleEmitterObject : VirtualParadiseObject foreach (PropertyInfo property in properties) { if (property.GetCustomAttribute() is null) + { continue; + } property.SetValue(this, property.GetValue(emitter)); } @@ -235,7 +239,9 @@ public sealed class VirtualParadiseParticleEmitterObject : VirtualParadiseObject { var serializationKeyAttribute = property.GetCustomAttribute(); if (serializationKeyAttribute is null) + { continue; + } keymap.Add(serializationKeyAttribute.Key, property); @@ -244,7 +250,9 @@ public sealed class VirtualParadiseParticleEmitterObject : VirtualParadiseObject { Type converterType = converterAttribute.ConverterType; if (Activator.CreateInstance(converterType) is ValueConverter converter) + { converterMap.Add(serializationKeyAttribute.Key, converter); + } } } #pragma warning restore 612 diff --git a/VpSharp/src/Entities/VirtualParadisePathObject.cs b/VpSharp/src/Entities/VirtualParadisePathObject.cs index 061f044..50f7a15 100644 --- a/VpSharp/src/Entities/VirtualParadisePathObject.cs +++ b/VpSharp/src/Entities/VirtualParadisePathObject.cs @@ -26,7 +26,9 @@ public sealed class VirtualParadisePathObject : VirtualParadiseObject protected internal override void ExtractFromOther(VirtualParadiseObject virtualParadiseObject) { if (virtualParadiseObject is not VirtualParadisePathObject path) + { return; + } Path = (VirtualParadisePath)path.Path.Clone(); } @@ -55,7 +57,9 @@ public sealed class VirtualParadisePathObject : VirtualParadiseObject buffer.Clear(); if (version != 1) + { throw new NotSupportedException($"Unsupported path version {version}"); + } // path name var name = string.Empty; diff --git a/VpSharp/src/Entities/VirtualParadiseUser.cs b/VpSharp/src/Entities/VirtualParadiseUser.cs index 974c317..966193e 100644 --- a/VpSharp/src/Entities/VirtualParadiseUser.cs +++ b/VpSharp/src/Entities/VirtualParadiseUser.cs @@ -93,8 +93,16 @@ public sealed class VirtualParadiseUser : IEquatable /// public bool Equals(VirtualParadiseUser? other) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + return Id == other.Id; } @@ -214,7 +222,9 @@ public sealed class VirtualParadiseUser : IEquatable location = new Location(world, position, rotation); if (!suppressTeleport) + { await avatar.TeleportAsync(location.Value); + } } JoinResponse response = reason switch diff --git a/VpSharp/src/Entities/VirtualParadiseWorld.cs b/VpSharp/src/Entities/VirtualParadiseWorld.cs index e7ee72b..3151b32 100644 --- a/VpSharp/src/Entities/VirtualParadiseWorld.cs +++ b/VpSharp/src/Entities/VirtualParadiseWorld.cs @@ -89,8 +89,16 @@ public sealed class VirtualParadiseWorld : IEquatable /// public bool Equals(VirtualParadiseWorld? other) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + return IsNowhere == other.IsNowhere && Name == other.Name; } diff --git a/VpSharp/src/Extensions/SpanExtensions.cs b/VpSharp/src/Extensions/SpanExtensions.cs index ae1af4c..05971ef 100644 --- a/VpSharp/src/Extensions/SpanExtensions.cs +++ b/VpSharp/src/Extensions/SpanExtensions.cs @@ -70,11 +70,15 @@ internal static class SpanExtensions { buffer.Append(current); if (index < value.Length - 1) + { continue; + } } if (current != ' ') + { continue; + } ReadOnlySpan span = buffer.AsSpan(); var floatValue = span.ToSingle(); @@ -111,11 +115,15 @@ internal static class SpanExtensions { buffer.Append(current); if (index < value.Length - 1) + { continue; + } } if (current != ' ') + { continue; + } ReadOnlySpan span = buffer.AsSpan(); var floatValue = span.ToSingle(); @@ -155,11 +163,15 @@ internal static class SpanExtensions { buffer.Append(current); if (index < value.Length - 1) + { continue; + } } if (current != ' ') + { continue; + } ReadOnlySpan span = buffer.AsSpan(); var floatValue = span.ToDouble(); @@ -200,11 +212,15 @@ internal static class SpanExtensions { buffer.Append(current); if (index < value.Length - 1) + { continue; + } } if (current != ' ') + { continue; + } ReadOnlySpan span = buffer.AsSpan(); var floatValue = span.ToSingle(); diff --git a/VpSharp/src/Internal/Attributes/ValueConverterAttribute.cs b/VpSharp/src/Internal/Attributes/ValueConverterAttribute.cs index d027b4a..2f1e94f 100644 --- a/VpSharp/src/Internal/Attributes/ValueConverterAttribute.cs +++ b/VpSharp/src/Internal/Attributes/ValueConverterAttribute.cs @@ -17,13 +17,19 @@ internal sealed class ValueConverterAttribute : Attribute public ValueConverterAttribute(Type converterType, params object?[]? args) { if (converterType is null) + { throw new ArgumentNullException(nameof(converterType)); + } if (converterType.IsAbstract) + { throw new ArgumentException("Cannot use abstract converter."); + } if (!converterType.IsSubclassOf(typeof(ValueConverter))) + { throw new ArgumentException($"Converter does not inherit {typeof(ValueConverter)}"); + } ConverterType = converterType; Args = args; diff --git a/VpSharp/src/Internal/Connection.cs b/VpSharp/src/Internal/Connection.cs index 77849d8..121321e 100644 --- a/VpSharp/src/Internal/Connection.cs +++ b/VpSharp/src/Internal/Connection.cs @@ -60,7 +60,11 @@ internal class Connection GCHandle handle = GCHandle.FromIntPtr(ptr); var connection = handle.Target as Connection; string host = Marshal.PtrToStringAnsi(hostPtr); - if (connection is not null) return connection.Connect(host, port); + if (connection is not null) + { + return connection.Connect(host, port); + } + return 0; } @@ -83,7 +87,10 @@ internal class Connection private void HandleTimeout() { - if (_timer != null) Notify(NetworkNotification.Timeout, 0); + if (_timer != null) + { + Notify(NetworkNotification.Timeout, 0); + } } private static void HandleTimeout(object state) @@ -96,13 +103,18 @@ internal class Connection lock (_lockObject) { if (_vpConnection != IntPtr.Zero) + { Native.vp_net_notify(_vpConnection, (int) notification, rc); + } } } public int Receive(IntPtr data, uint length) { - if (_readyBuffers.Count == 0) return (int) NetworkReturnCode.WouldBlock; + if (_readyBuffers.Count == 0) + { + return (int) NetworkReturnCode.WouldBlock; + } var spaceLeft = (int) length; IntPtr destination = data; @@ -134,7 +146,11 @@ internal class Connection private static void ReceiveCallback(IAsyncResult ar) { - if (ar.AsyncState is not Connection connection) return; + if (ar.AsyncState is not Connection connection) + { + return; + } + int bytesRead; try @@ -176,14 +192,18 @@ internal class Connection } } else + { connection.Notify(NetworkNotification.Disconnect, 0); + } } } public static int ReceiveNative(IntPtr ptr, IntPtr data, uint length) { if (GCHandle.FromIntPtr(ptr).Target is Connection connection) + { return connection.Receive(data, length); + } return 0; } @@ -205,7 +225,9 @@ internal class Connection public static int SendNative(IntPtr ptr, IntPtr data, uint length) { if (GCHandle.FromIntPtr(ptr).Target is Connection connection) + { return connection.Send(data, length); + } return 0; } @@ -213,9 +235,13 @@ internal class Connection public int Timeout(int seconds) { if (seconds < 0) + { _timer = null; + } else + { _timer = new Timer(HandleTimeout, this, seconds * 1000, global::System.Threading.Timeout.Infinite); + } return 0; } @@ -223,7 +249,9 @@ internal class Connection public static int TimeoutNative(IntPtr ptr, int seconds) { if (GCHandle.FromIntPtr(ptr).Target is Connection connection) + { return connection.Timeout(seconds); + } return 0; } diff --git a/VpSharp/src/Internal/ObjectReferenceCounter.cs b/VpSharp/src/Internal/ObjectReferenceCounter.cs index f9b9493..8b80672 100644 --- a/VpSharp/src/Internal/ObjectReferenceCounter.cs +++ b/VpSharp/src/Internal/ObjectReferenceCounter.cs @@ -11,9 +11,14 @@ internal static class ObjectReferenceCounter int ret; Rwl.EnterWriteLock(); if (s_reference < int.MaxValue) + { ret = s_reference++; + } else + { ret = s_reference = int.MinValue; + } + Rwl.ExitWriteLock(); return ret; } diff --git a/VpSharp/src/Internal/ValueConverters/UriConverter.cs b/VpSharp/src/Internal/ValueConverters/UriConverter.cs index 405a818..9814f0a 100644 --- a/VpSharp/src/Internal/ValueConverters/UriConverter.cs +++ b/VpSharp/src/Internal/ValueConverters/UriConverter.cs @@ -13,6 +13,8 @@ internal sealed class UriConverter : ValueConverter public override void Serialize(TextWriter writer, Uri value) { if (value is not null) + { writer.Write(value.ToString()); + } } } \ No newline at end of file diff --git a/VpSharp/src/Internal/ValueConverters/Vector2Converter.cs b/VpSharp/src/Internal/ValueConverters/Vector2Converter.cs index 1e07292..4c2bad0 100644 --- a/VpSharp/src/Internal/ValueConverters/Vector2Converter.cs +++ b/VpSharp/src/Internal/ValueConverters/Vector2Converter.cs @@ -18,10 +18,14 @@ internal sealed class Vector2Converter : ValueConverter var currentChar = (char) readChar; if (currentChar == ' ') + { spaceCount++; + } if (spaceCount < 2 && readChar != -1) + { continue; + } result = builder.AsSpan().ToVector2(); break; diff --git a/VpSharp/src/Internal/ValueConverters/Vector3Converter.cs b/VpSharp/src/Internal/ValueConverters/Vector3Converter.cs index 5a8bdeb..cbd8166 100644 --- a/VpSharp/src/Internal/ValueConverters/Vector3Converter.cs +++ b/VpSharp/src/Internal/ValueConverters/Vector3Converter.cs @@ -18,10 +18,14 @@ internal sealed class Vector3Converter : ValueConverter var currentChar = (char) readChar; if (currentChar == ' ') + { spaceCount++; + } if (spaceCount < 3 && readChar != -1) + { continue; + } result = builder.AsSpan().ToVector3(); break; diff --git a/VpSharp/src/Internal/ValueConverters/Vector3ToColorConverter.cs b/VpSharp/src/Internal/ValueConverters/Vector3ToColorConverter.cs index 6acc3fc..cdbc4f8 100644 --- a/VpSharp/src/Internal/ValueConverters/Vector3ToColorConverter.cs +++ b/VpSharp/src/Internal/ValueConverters/Vector3ToColorConverter.cs @@ -17,10 +17,14 @@ internal sealed class Vector3ToColorConverter : ValueConverter var currentChar = (char) readChar; if (currentChar == ' ') + { spaceCount++; + } if (spaceCount < 3 && readChar != -1) + { continue; + } (float x, float y, float z) = builder.AsSpan().ToVector3(); result = ColorF.FromArgb(x, y, z); diff --git a/VpSharp/src/Internal/ValueConverters/Vector3dConverter.cs b/VpSharp/src/Internal/ValueConverters/Vector3dConverter.cs index 639d8c0..9e87843 100644 --- a/VpSharp/src/Internal/ValueConverters/Vector3dConverter.cs +++ b/VpSharp/src/Internal/ValueConverters/Vector3dConverter.cs @@ -17,10 +17,14 @@ internal sealed class Vector3dConverter : ValueConverter var currentChar = (char) readChar; if (currentChar == ' ') + { spaceCount++; + } if (spaceCount < 3 && readChar != -1) + { continue; + } result = builder.AsSpan().ToVector3d(); break; diff --git a/VpSharp/src/Internal/ValueConverters/Vector4ToColorConverter.cs b/VpSharp/src/Internal/ValueConverters/Vector4ToColorConverter.cs index 0135df3..2334df4 100644 --- a/VpSharp/src/Internal/ValueConverters/Vector4ToColorConverter.cs +++ b/VpSharp/src/Internal/ValueConverters/Vector4ToColorConverter.cs @@ -17,10 +17,14 @@ internal sealed class Vector4ToColorConverter : ValueConverter var currentChar = (char) readChar; if (currentChar == ' ') + { spaceCount++; + } if (spaceCount < 4 && readChar != -1) + { continue; + } (float x, float y, float z, float w) = builder.AsSpan().ToVector4(); result = ColorF.FromArgb(w, x, y, z); diff --git a/VpSharp/src/Internal/ValueConverters/Vector4ToVector3Converter.cs b/VpSharp/src/Internal/ValueConverters/Vector4ToVector3Converter.cs index 1cfe5cf..039c1be 100644 --- a/VpSharp/src/Internal/ValueConverters/Vector4ToVector3Converter.cs +++ b/VpSharp/src/Internal/ValueConverters/Vector4ToVector3Converter.cs @@ -18,10 +18,14 @@ internal sealed class Vector4ToVector3Converter : ValueConverter var currentChar = (char) readChar; if (currentChar == ' ') + { spaceCount++; + } if (spaceCount < 3 && readChar != -1) + { continue; + } result = builder.AsSpan().ToVector3(); break; diff --git a/VpSharp/src/Internal/ValueConverters/VectorToNthComponentConverter.cs b/VpSharp/src/Internal/ValueConverters/VectorToNthComponentConverter.cs index 6cf1c59..17a0619 100644 --- a/VpSharp/src/Internal/ValueConverters/VectorToNthComponentConverter.cs +++ b/VpSharp/src/Internal/ValueConverters/VectorToNthComponentConverter.cs @@ -24,13 +24,19 @@ internal sealed class VectorToNthComponentConverter : ValueConverter int readChar = reader.Read(); if (readChar == -1) + { break; + } var currentChar = (char) readChar; if (currentChar == ' ') + { spaceCount++; + } else if (spaceCount == _componentNumber - 1) + { builder.Append(currentChar); + } } result = builder.AsSpan().ToSingle(); diff --git a/VpSharp/src/Internal/ValueConverters/WorldSettingsConverter.cs b/VpSharp/src/Internal/ValueConverters/WorldSettingsConverter.cs index 070745d..b7a0264 100644 --- a/VpSharp/src/Internal/ValueConverters/WorldSettingsConverter.cs +++ b/VpSharp/src/Internal/ValueConverters/WorldSettingsConverter.cs @@ -15,13 +15,17 @@ internal static class WorldSettingsConverter { var attribute = property.GetCustomAttribute(); if (attribute is null) + { continue; + } object? propertyValue = property.GetValue(settings); Type propertyType = property.PropertyType; if (propertyValue is null) + { continue; + } var result = propertyValue.ToString(); @@ -33,9 +37,13 @@ internal static class WorldSettingsConverter ValueConverter? converter; if (converterAttribute.UseArgs) + { converter = Activator.CreateInstance(converterType, converterAttribute.Args) as ValueConverter; + } else + { converter = Activator.CreateInstance(converterType) as ValueConverter; + } if (converter is not null) { @@ -48,11 +56,15 @@ internal static class WorldSettingsConverter else { if (propertyType == typeof(bool) || propertyType == typeof(bool?)) + { result = (bool)propertyValue ? "1" : "0"; + } } if (result is not null) + { dictionary.Add(attribute.Key, result); + } } return dictionary; @@ -67,7 +79,9 @@ internal static class WorldSettingsConverter { var defaultValueAttribute = property.GetCustomAttribute(); if (defaultValueAttribute is null) + { continue; + } property.SetValue(settings, defaultValueAttribute.Value); } @@ -79,7 +93,9 @@ internal static class WorldSettingsConverter StringComparison.OrdinalIgnoreCase)); if (property is null) + { continue; + } using var reader = new StringReader(value); object propertyValue = value; @@ -95,15 +111,25 @@ internal static class WorldSettingsConverter Type propertyType = property.PropertyType; if (propertyType == typeof(bool)) + { propertyValue = value == "1" || (bool.TryParse(value, out bool result) && result); + } else if (propertyType == typeof(int)) + { propertyValue = int.TryParse(value, out int result) ? result : 0; + } else if (propertyType == typeof(float)) + { propertyValue = float.TryParse(value, out float result) ? result : 0.0f; + } else if (propertyType == typeof(double)) + { propertyValue = double.TryParse(value, out double result) ? result : 0.0; + } else if (propertyType.IsEnum && int.TryParse(value, out int result)) + { propertyValue = Convert.ChangeType(result, propertyType); + } } // ReSharper disable ConditionIsAlwaysTrueOrFalse @@ -112,9 +138,13 @@ internal static class WorldSettingsConverter { ValueConverter? converter; if (converterAttribute.UseArgs) + { converter = Activator.CreateInstance(converterType, converterAttribute.Args) as ValueConverter; + } else + { converter = Activator.CreateInstance(converterType) as ValueConverter; + } converter?.Deserialize(reader, out propertyValue); } diff --git a/VpSharp/src/InviteRequest.cs b/VpSharp/src/InviteRequest.cs index b7e25c8..2c4e28d 100644 --- a/VpSharp/src/InviteRequest.cs +++ b/VpSharp/src/InviteRequest.cs @@ -46,8 +46,16 @@ public sealed class InviteRequest : IEquatable /// public bool Equals(InviteRequest? other) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + return _requestId == other._requestId && _client.Equals(other._client); } @@ -59,10 +67,15 @@ public sealed class InviteRequest : IEquatable /// public Task AcceptAsync(bool suppressTeleport = false) { - lock (_client.Lock) Native.vp_invite_accept(_client.NativeInstanceHandle, _requestId); + lock (_client.Lock) + { + Native.vp_invite_accept(_client.NativeInstanceHandle, _requestId); + } if (suppressTeleport) + { return Task.CompletedTask; + } return _client.CurrentAvatar.TeleportAsync(Location); } @@ -72,7 +85,10 @@ public sealed class InviteRequest : IEquatable /// public Task DeclineAsync() { - lock (_client.Lock) Native.vp_invite_decline(_client.NativeInstanceHandle, _requestId); + lock (_client.Lock) + { + Native.vp_invite_decline(_client.NativeInstanceHandle, _requestId); + } return Task.CompletedTask; } @@ -80,7 +96,11 @@ public sealed class InviteRequest : IEquatable /// public override bool Equals(object? obj) { - if (ReferenceEquals(this, obj)) return true; + if (ReferenceEquals(this, obj)) + { + return true; + } + return obj is InviteRequest other && Equals(other); } diff --git a/VpSharp/src/JoinRequest.cs b/VpSharp/src/JoinRequest.cs index 8ba3323..51975e2 100644 --- a/VpSharp/src/JoinRequest.cs +++ b/VpSharp/src/JoinRequest.cs @@ -45,15 +45,19 @@ public sealed class JoinRequest : IEquatable public Task AcceptAsync(Location? location = null) { if (_client.CurrentAvatar is null) + { ThrowHelper.ThrowNotInWorldException(); - + } + location ??= _client.CurrentAvatar!.Location; string worldName = location.Value.World.Name; (double x, double y, double z) = location.Value.Position; (double pitch, double yaw, double _) = location.Value.Rotation.ToEulerAngles(); lock (_client.Lock) + { Native.vp_join_accept(_client.NativeInstanceHandle, _requestId, worldName, x, y, z, (float) yaw, (float) pitch); + } return Task.CompletedTask; } @@ -63,7 +67,10 @@ public sealed class JoinRequest : IEquatable /// public Task DeclineAsync() { - lock (_client.Lock) Native.vp_join_decline(_client.NativeInstanceHandle, _requestId); + lock (_client.Lock) + { + Native.vp_join_decline(_client.NativeInstanceHandle, _requestId); + } return Task.CompletedTask; } @@ -72,15 +79,27 @@ public sealed class JoinRequest : IEquatable /// public bool Equals(JoinRequest? other) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + return _requestId == other._requestId && _client.Equals(other._client); } /// public override bool Equals(object? obj) { - if (ReferenceEquals(this, obj)) return true; + if (ReferenceEquals(this, obj)) + { + return true; + } + return obj is JoinRequest other && Equals(other); } diff --git a/VpSharp/src/Scene/FluentActionComponent.cs b/VpSharp/src/Scene/FluentActionComponent.cs index 2f53b7c..2be7611 100644 --- a/VpSharp/src/Scene/FluentActionComponent.cs +++ b/VpSharp/src/Scene/FluentActionComponent.cs @@ -104,8 +104,15 @@ public abstract class FluentActionComponent var builder = new StringBuilder(); builder.Append($"texture {texture}"); - if (!string.IsNullOrWhiteSpace(mask)) builder.Append($" mask={mask}"); - if (!string.IsNullOrWhiteSpace(tag)) builder.Append($" tag={tag}"); + if (!string.IsNullOrWhiteSpace(mask)) + { + builder.Append($" mask={mask}"); + } + + if (!string.IsNullOrWhiteSpace(tag)) + { + builder.Append($" tag={tag}"); + } return new FluentActionCommand(Action, Command.Texture); } diff --git a/VpSharp/src/Vector3d.cs b/VpSharp/src/Vector3d.cs index 5f4210b..896011d 100644 --- a/VpSharp/src/Vector3d.cs +++ b/VpSharp/src/Vector3d.cs @@ -67,7 +67,9 @@ public struct Vector3d : IEquatable, IFormattable public Vector3d(ReadOnlySpan values) { if (values.Length < 3) + { throw new IndexOutOfRangeException("The specified span has an insufficient number of elements."); + } this = Unsafe.ReadUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(values))); } @@ -428,13 +430,19 @@ public struct Vector3d : IEquatable, IFormattable public readonly void CopyTo(double[] array, int index = 0) { if (array is null) + { throw new ArgumentNullException(nameof(array)); + } if (index < 0 || index >= array.Length) + { throw new ArgumentOutOfRangeException(nameof(index), "Specified index was out of the bounds of the array."); + } if (array.Length - index < 3) + { throw new ArgumentException("The number of elements in source vector is greater than the destination array."); + } array[index] = X; array[index + 1] = Y; diff --git a/VpSharp/src/VirtualParadiseClient.Native.cs b/VpSharp/src/VirtualParadiseClient.Native.cs index 494b3d3..6ad1258 100644 --- a/VpSharp/src/VirtualParadiseClient.Native.cs +++ b/VpSharp/src/VirtualParadiseClient.Native.cs @@ -17,7 +17,9 @@ public sealed partial class VirtualParadiseClient { var reason = (ReasonCode) Native.vp_init(); if (reason == ReasonCode.VersionMismatch) + { throw new VersionMismatchException(); + } _instanceHandle = GCHandle.Alloc(this); _netConfig.Context = GCHandle.ToIntPtr(_instanceHandle); diff --git a/VpSharp/src/VirtualParadiseClient.NativeCallbacks.cs b/VpSharp/src/VirtualParadiseClient.NativeCallbacks.cs index dee3a66..8e51198 100644 --- a/VpSharp/src/VirtualParadiseClient.NativeCallbacks.cs +++ b/VpSharp/src/VirtualParadiseClient.NativeCallbacks.cs @@ -41,7 +41,9 @@ public sealed partial class VirtualParadiseClient private async void OnObjectGetNativeCallback(IntPtr sender, ReasonCode reason, int reference) { if (!_objectCompletionSources.TryGetValue(reference, out TaskCompletionSource<(ReasonCode, VirtualParadiseObject)>? taskCompletionSource)) + { return; + } VirtualParadiseObject virtualParadiseObject = reason == ReasonCode.Success ? await ExtractObjectAsync(sender) : null; taskCompletionSource.SetResult((reason, virtualParadiseObject)); diff --git a/VpSharp/src/VirtualParadiseClient.NativeEvents.cs b/VpSharp/src/VirtualParadiseClient.NativeEvents.cs index a68a8ab..c3b001b 100644 --- a/VpSharp/src/VirtualParadiseClient.NativeEvents.cs +++ b/VpSharp/src/VirtualParadiseClient.NativeEvents.cs @@ -1,4 +1,4 @@ -using System.Collections.Concurrent; +using System.Collections.Concurrent; using System.Drawing; using System.Numerics; using System.Threading.Channels; @@ -167,7 +167,9 @@ public sealed partial class VirtualParadiseClient if (session == 0) { if (_cellChannels.TryGetValue(cell, out Channel? channel)) + { await channel.Writer.WriteAsync(virtualParadiseObject); + } } else { @@ -201,7 +203,9 @@ public sealed partial class VirtualParadiseClient } if (virtualParadiseObject is not null) + { AddOrUpdateObject(virtualParadiseObject); + } var args = new ObjectChangedEventArgs(avatar, cachedObject, virtualParadiseObject); RaiseEvent(ObjectChanged, args); @@ -277,7 +281,9 @@ public sealed partial class VirtualParadiseClient } if (_worldListChannel is not null) + { await _worldListChannel.Writer.WriteAsync(world); + } } private void OnWorldSettingNativeEvent(IntPtr sender) @@ -311,7 +317,10 @@ public sealed partial class VirtualParadiseClient private void OnWorldDisconnectNativeEvent(IntPtr sender) { DisconnectReason reason; - lock (Lock) reason = (DisconnectReason) vp_int(sender, IntegerAttribute.DisconnectErrorCode); + lock (Lock) + { + reason = (DisconnectReason) vp_int(sender, IntegerAttribute.DisconnectErrorCode); + } var args = new DisconnectedEventArgs(reason); RaiseEvent(WorldServerDisconnected, args); @@ -320,7 +329,10 @@ public sealed partial class VirtualParadiseClient private void OnUniverseDisconnectNativeEvent(IntPtr sender) { DisconnectReason reason; - lock (Lock) reason = (DisconnectReason) vp_int(sender, IntegerAttribute.DisconnectErrorCode); + lock (Lock) + { + reason = (DisconnectReason) vp_int(sender, IntegerAttribute.DisconnectErrorCode); + } var args = new DisconnectedEventArgs(reason); RaiseEvent(UniverseServerDisconnected, args); @@ -352,7 +364,9 @@ public sealed partial class VirtualParadiseClient } if (_usersCompletionSources.TryGetValue(userId, out TaskCompletionSource? taskCompletionSource)) + { taskCompletionSource.SetResult(user); + } } private void OnQueryCellEndNativeEvent(IntPtr sender) @@ -368,7 +382,9 @@ public sealed partial class VirtualParadiseClient } if (_cellChannels.TryRemove(cell, out Channel? channel)) + { channel.Writer.TryComplete(); + } } private void OnAvatarClickNativeEvent(IntPtr sender) @@ -456,7 +472,9 @@ public sealed partial class VirtualParadiseClient } if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) + { return; + } VirtualParadiseAvatar? avatar = GetAvatar(session); var uri = new Uri(url); diff --git a/VpSharp/src/VirtualParadiseClient.Objects.cs b/VpSharp/src/VirtualParadiseClient.Objects.cs index 145d35b..e292bfc 100644 --- a/VpSharp/src/VirtualParadiseClient.Objects.cs +++ b/VpSharp/src/VirtualParadiseClient.Objects.cs @@ -24,7 +24,9 @@ public sealed partial class VirtualParadiseClient public IAsyncEnumerable EnumerateObjectsAsync(Cell cell, int? revision = null) { if (_cellChannels.TryGetValue(cell, out Channel? channel)) + { return channel.Reader.ReadAllAsync(); + } channel = Channel.CreateUnbounded(); _cellChannels.TryAdd(cell, channel); @@ -53,18 +55,25 @@ public sealed partial class VirtualParadiseClient /// An enumerable of . public async IAsyncEnumerable EnumerateObjectsAsync(Cell center, int radius, int? revision = null) { - if (radius < 0) throw new ArgumentException("Range must be greater than or equal to 1."); + if (radius < 0) + { + throw new ArgumentException("Range must be greater than or equal to 1."); + } var cells = new HashSet(); for (int x = center.X - radius; x < center.X + radius; x++) for (int z = center.Z - radius; z < center.Z + radius; z++) + { cells.Add(new Cell(x, z)); + } foreach (Cell cell in cells.OrderBy(c => Vector2.Distance(c, center))) { await foreach (VirtualParadiseObject vpObject in EnumerateObjectsAsync(cell)) + { yield return vpObject; + } } } @@ -82,7 +91,9 @@ public sealed partial class VirtualParadiseClient public async ValueTask GetObjectAsync(int id) { if (_objects.TryGetValue(id, out VirtualParadiseObject? virtualParadiseObject)) + { return virtualParadiseObject; + } ReasonCode reason; @@ -97,7 +108,9 @@ public sealed partial class VirtualParadiseClient vp_int_set(NativeInstanceHandle, IntegerAttribute.ReferenceNumber, id); reason = (ReasonCode) vp_object_get(NativeInstanceHandle, id); if (reason != ReasonCode.Success) + { goto PreReturn; + } } } @@ -105,7 +118,9 @@ public sealed partial class VirtualParadiseClient _objectCompletionSources.TryRemove(id, out _); if (virtualParadiseObject is not null) + { _objects.TryAdd(id, virtualParadiseObject); + } PreReturn: return reason switch diff --git a/VpSharp/src/VirtualParadiseClient.Users.cs b/VpSharp/src/VirtualParadiseClient.Users.cs index 3473846..2bcbf58 100644 --- a/VpSharp/src/VirtualParadiseClient.Users.cs +++ b/VpSharp/src/VirtualParadiseClient.Users.cs @@ -19,15 +19,22 @@ public sealed partial class VirtualParadiseClient public async Task GetUserAsync(int userId) { if (_users.TryGetValue(userId, out VirtualParadiseUser? user)) + { return user; + } if (_usersCompletionSources.TryGetValue(userId, out TaskCompletionSource? taskCompletionSource)) + { return await taskCompletionSource.Task; + } taskCompletionSource = new TaskCompletionSource(); _usersCompletionSources.TryAdd(userId, taskCompletionSource); - lock (Lock) vp_user_attributes_by_id(NativeInstanceHandle, userId); + lock (Lock) + { + vp_user_attributes_by_id(NativeInstanceHandle, userId); + } user = await taskCompletionSource.Task; user = AddOrUpdateUser(user); diff --git a/VpSharp/src/VirtualParadiseClient.Worlds.cs b/VpSharp/src/VirtualParadiseClient.Worlds.cs index 33886d4..4525156 100644 --- a/VpSharp/src/VirtualParadiseClient.Worlds.cs +++ b/VpSharp/src/VirtualParadiseClient.Worlds.cs @@ -1,12 +1,6 @@ using System.Collections.Concurrent; -using System.Drawing; -using System.Numerics; using System.Threading.Channels; using VpSharp.Entities; -using VpSharp.Exceptions; -using VpSharp.Internal; -using VpSharp.Internal.NativeAttributes; -using VpSharp.Internal.ValueConverters; namespace VpSharp; @@ -30,12 +24,16 @@ public sealed partial class VirtualParadiseClient public async Task GetWorldAsync(string name) { if (string.IsNullOrWhiteSpace(name)) + { throw new ArgumentException(ExceptionMessages.WorldNameCannotBeEmpty, nameof(name)); + } await foreach (VirtualParadiseWorld world in EnumerateWorldsAsync()) { if (string.Equals(world.Name, name)) + { return world; + } } return null; diff --git a/VpSharp/src/VirtualParadiseClient.cs b/VpSharp/src/VirtualParadiseClient.cs index 825fb9e..9026a9b 100644 --- a/VpSharp/src/VirtualParadiseClient.cs +++ b/VpSharp/src/VirtualParadiseClient.cs @@ -1,4 +1,4 @@ -using System.Collections.Concurrent; +using System.Collections.Concurrent; using System.Drawing; using System.Net; using System.Net.Sockets; @@ -92,8 +92,15 @@ public sealed partial class VirtualParadiseClient : IDisposable /// public async Task ConnectAsync(string? host = null, int port = -1) { - if (string.IsNullOrWhiteSpace(host)) host = DefaultUniverseHost; - if (port < 1) port = DefaultUniversePort; + if (string.IsNullOrWhiteSpace(host)) + { + host = DefaultUniverseHost; + } + + if (port < 1) + { + port = DefaultUniversePort; + } ReasonCode reason; @@ -101,9 +108,11 @@ public sealed partial class VirtualParadiseClient : IDisposable { _connectCompletionSource = new TaskCompletionSource(); - reason = (ReasonCode) vp_connect_universe(NativeInstanceHandle, host, port); + reason = (ReasonCode)vp_connect_universe(NativeInstanceHandle, host, port); if (reason != ReasonCode.Success) + { goto NoSuccess; + } } reason = await _connectCompletionSource.Task; @@ -118,7 +127,7 @@ public sealed partial class VirtualParadiseClient : IDisposable throw new SocketException(); default: - throw new SocketException((int) reason); + throw new SocketException((int)reason); } } @@ -130,7 +139,10 @@ public sealed partial class VirtualParadiseClient : IDisposable /// is not a supported endpoint. public Task ConnectAsync(EndPoint remoteEP) { - if (remoteEP is null) throw new ArgumentNullException(nameof(remoteEP)); + if (remoteEP is null) + { + throw new ArgumentNullException(nameof(remoteEP)); + } string host; int port; @@ -273,7 +285,10 @@ public sealed partial class VirtualParadiseClient : IDisposable if (CurrentWorld is not null) { - lock (Lock) vp_leave(NativeInstanceHandle); + lock (Lock) + { + vp_leave(NativeInstanceHandle); + } } ReasonCode reason; @@ -283,7 +298,7 @@ public sealed partial class VirtualParadiseClient : IDisposable lock (Lock) { - reason = (ReasonCode) vp_enter(NativeInstanceHandle, worldName); + reason = (ReasonCode)vp_enter(NativeInstanceHandle, worldName); if (reason != ReasonCode.Success) { goto NoSuccess; @@ -321,7 +336,10 @@ public sealed partial class VirtualParadiseClient : IDisposable } int size; - lock (Lock) size = vp_int(NativeInstanceHandle, IntegerAttribute.WorldSize); + lock (Lock) + { + size = vp_int(NativeInstanceHandle, IntegerAttribute.WorldSize); + } await _worldSettingsCompletionSource.Task; @@ -332,8 +350,15 @@ public sealed partial class VirtualParadiseClient : IDisposable world = new VirtualParadiseWorld(this, worldName); } - if (CurrentAvatar is not null) CurrentAvatar.Location = new Location(world); - lock (Lock) vp_state_change(NativeInstanceHandle); + if (CurrentAvatar is not null) + { + CurrentAvatar.Location = new Location(world); + } + + lock (Lock) + { + vp_state_change(NativeInstanceHandle); + } world.Size = new Size(size, size); @@ -356,7 +381,9 @@ public sealed partial class VirtualParadiseClient : IDisposable _ = Task.Run(async () => { await foreach (VirtualParadiseObject virtualParadiseObject in EnumerateObjectsAsync(default, radius: size)) + { AddOrUpdateObject(virtualParadiseObject); + } }); } @@ -375,7 +402,11 @@ public sealed partial class VirtualParadiseClient : IDisposable public IAsyncEnumerable EnumerateWorldsAsync() { _worldListChannel = Channel.CreateUnbounded(); - lock (Lock) vp_world_list(NativeInstanceHandle, 0); + lock (Lock) + { + vp_world_list(NativeInstanceHandle, 0); + } + return _worldListChannel.Reader.ReadAllAsync(); } @@ -389,9 +420,11 @@ public sealed partial class VirtualParadiseClient : IDisposable { lock (Lock) { - var reason = (ReasonCode) vp_leave(NativeInstanceHandle); + var reason = (ReasonCode)vp_leave(NativeInstanceHandle); if (reason == ReasonCode.NotInWorld) + { return Task.FromException(ThrowHelper.NotInWorldException()); + } } _avatars.Clear(); @@ -438,7 +471,9 @@ public sealed partial class VirtualParadiseClient : IDisposable _configuration.BotName = botName; if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(botName)) + { throw new ArgumentException("Cannot login due to incomplete configuration."); + } _loginCompletionSource = new TaskCompletionSource(); @@ -454,9 +489,11 @@ public sealed partial class VirtualParadiseClient : IDisposable } } - reason = (ReasonCode) vp_login(NativeInstanceHandle, username, password, botName); + reason = (ReasonCode)vp_login(NativeInstanceHandle, username, password, botName); if (reason != ReasonCode.Success) + { goto NoSuccess; + } } reason = await _loginCompletionSource.Task; diff --git a/VpSharp/src/VirtualParadiseConfiguration.cs b/VpSharp/src/VirtualParadiseConfiguration.cs index b2bc696..558a697 100644 --- a/VpSharp/src/VirtualParadiseConfiguration.cs +++ b/VpSharp/src/VirtualParadiseConfiguration.cs @@ -19,10 +19,15 @@ public sealed class VirtualParadiseConfiguration /// The configuration to copy. public VirtualParadiseConfiguration(VirtualParadiseConfiguration configuration) { - if (configuration is null) throw new ArgumentNullException(nameof(configuration)); + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } if (configuration.Application is ({ } name, { } version)) + { Application = new Application(name, version); + } AutoQuery = configuration.AutoQuery; BotName = new string(configuration.BotName); diff --git a/VpSharp/src/WorldSettingsBuilder.cs b/VpSharp/src/WorldSettingsBuilder.cs index f738395..c66d518 100644 --- a/VpSharp/src/WorldSettingsBuilder.cs +++ b/VpSharp/src/WorldSettingsBuilder.cs @@ -388,12 +388,16 @@ public sealed class WorldSettingsBuilder foreach ((string key, string? value) in dictionary) { if (value is null) + { continue; + } var reason = (ReasonCode)Native.vp_world_setting_set(_client.NativeInstanceHandle, key, value, session); if (reason == ReasonCode.NotAllowed) + { throw new UnauthorizedAccessException("Not allowed to modify world settings."); + } } } }