From aa5ebb052a79ddb9c4f80b85a201722bb4e96241 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Fri, 16 Dec 2022 23:53:35 +0900 Subject: [PATCH 01/14] Added XML documentation comments. Resolved #31. --- .../OscAvatarParameterChangedEventHandler.cs | 5 + src/VRCOscLib/VRCOscLib/Avatar/OscAvatar.cs | 13 ++ .../VRCOscLib/Avatar/OscAvatarConfig.cs | 62 ++++++++ .../VRCOscLib/Avatar/OscAvatarParameter.cs | 37 +++++ .../Avatar/OscAvatarParameterInterface.cs | 36 +++++ .../Avatar/OscAvatarParametorContainer.cs | 96 ++++++++++++ src/VRCOscLib/VRCOscLib/Avatar/OscPhysBone.cs | 61 +++++++- .../Avatar/Utility/OscAvatarUtility.cs | 35 +++++ src/VRCOscLib/VRCOscLib/Chatbox/OscChatbox.cs | 27 ++++ .../IReadOnlyOscParameterCollection.cs | 17 ++ .../Collections/OscParameterCollection.cs | 34 ++++ .../Delegate/EventDelegateExtension.cs | 9 ++ .../OscParameterChangedEventHandler.cs | 8 +- .../Delegate/OscValueChangedEventHandler.cs | 8 + .../Event/Generic/ValueChangedEventArgs.cs | 17 ++ .../Event/ParameterChangedEventArgs.cs | 14 ++ .../VRCOscLib/Event/ValueChangedEventArgs.cs | 20 +++ .../VRCOscLib/Event/ValueChangedReason.cs | 14 ++ src/VRCOscLib/VRCOscLib/Input/OscAxisInput.cs | 42 +++++ .../VRCOscLib/Input/OscButtonInput.cs | 105 +++++++++++++ src/VRCOscLib/VRCOscLib/Input/OscInput.cs | 62 ++++++++ src/VRCOscLib/VRCOscLib/OscType.cs | 14 ++ .../VRCOscLib/Tracking/OscTracker.cs | 24 +++ .../VRCOscLib/Tracking/OscTracking.cs | 20 +++ src/VRCOscLib/VRCOscLib/Utility/MathHelper.cs | 13 ++ .../Utility/OscConnectionSettings.cs | 49 +++++- src/VRCOscLib/VRCOscLib/Utility/OscConst.cs | 12 +- .../Utility/OscParameter.Receiver.cs | 15 ++ .../VRCOscLib/Utility/OscParameter.Sender.cs | 147 ++++++++++++++++++ .../VRCOscLib/Utility/OscParameter.cs | 13 ++ .../Utility/OscUtility.AvatarConfig.cs | 25 +++ .../Utility/OscUtility.Connection.cs | 16 +- src/VRCOscLib/VRCOscLib/Utility/OscUtility.cs | 39 +++++ src/VRCOscLib/VRCOscLib/vrcosclib.csproj | 3 + 34 files changed, 1107 insertions(+), 5 deletions(-) diff --git a/src/VRCOscLib/VRCOscLib/Avatar/Delegate/OscAvatarParameterChangedEventHandler.cs b/src/VRCOscLib/VRCOscLib/Avatar/Delegate/OscAvatarParameterChangedEventHandler.cs index 5716788..3a80cb1 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/Delegate/OscAvatarParameterChangedEventHandler.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/Delegate/OscAvatarParameterChangedEventHandler.cs @@ -1,3 +1,8 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// Represents a delegate for handling changes to an . +/// +/// The that has changed. +/// The containing the old and new values. public delegate void OscAvatarParameterChangedEventHandler(OscAvatarParameter parameter, ValueChangedEventArgs e); diff --git a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatar.cs b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatar.cs index e6a9f5a..764e8f3 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatar.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatar.cs @@ -1,8 +1,21 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// Represents a VRChat avatar, as identified by its unique ID. +/// public struct OscAvatar { + /// + /// The unique ID of the avatar. + /// public string? Id { get; set; } + /// + /// Converts the avatar to an object. + /// + /// + /// An object representing the avatar, + /// or null if the avatar does not have a valid ID. + /// public OscAvatarConfig? ToConfig() => Id == null ? null : OscAvatarConfig.Create(Id); } diff --git a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarConfig.cs b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarConfig.cs index eb8b24c..5b5bade 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarConfig.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarConfig.cs @@ -2,29 +2,57 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// Represents the configuration of a VRChat avatar, including its unique ID, name, and a list of avatar parameters. +/// public class OscAvatarConfig { #pragma warning disable IDE0044 // Add readonly modifier + /// + /// The unique ID of the avatar. + /// [JsonProperty("id", Required = Required.Always)] private string _id = string.Empty; + /// + /// The name of the avatar. + /// [JsonProperty("name", Required = Required.Always)] private string _name = string.Empty; #pragma warning restore IDE0044 // Add readonly modifier + /// + /// The list of avatar parameters. + /// [JsonProperty("parameters", Required = Required.Always)] private readonly List _parametersList = new(); + /// + /// Gets the unique ID of the avatar. + /// public string Id => _id; + /// + /// Gets the name of the avatar. + /// public string Name => _name; [JsonIgnore] private OscAvatarParametorContainer? _parameters; + + /// + /// Gets the list of avatar parameters. + /// [JsonIgnore] public OscAvatarParametorContainer Parameters => _parameters ??= new(_parametersList); + /// + /// Gets a value indicating whether the avatar parameters have been created. + /// internal bool IsCreatedParameters => _parameters != null; + /// + /// Gets any additional information that was not explicitly defined in the class, but was present in the avatar configuration file. + /// [field: JsonExtensionData] public Dictionary Extra { get; } = new(); @@ -35,6 +63,17 @@ private OscAvatarConfig() OscAvatarUtility.RegisterAvaterConfig(this); } + /// + /// Initializes a new instance of the class with the specified avatar ID, name, and parameters. + /// + /// The unique ID of the avatar. + /// The name of the avatar. + /// The avatar parameters. + /// + /// is empty. + /// or + /// is empty. + /// public OscAvatarConfig(string id, string name, IEnumerable parameters) : this() { @@ -53,12 +92,20 @@ public OscAvatarConfig(string id, string name, IEnumerable p } + /// + /// Creates an array of all instances in the current directory. + /// + /// An array of all instances in the current directory. public static OscAvatarConfig[] CreateAll() => OscUtility.EnumerateOscAvatarConfigPathes() .AsParallel() .Select(GetAvatarConfig) .Where(config => config != null).ToArray()!; + /// + /// Creates an instance of from the currently active avatar. + /// + /// An instance of from the currently active avatar, or if no avatar is active. public static OscAvatarConfig? CreateAtCurrent() { var path = OscUtility.GetCurrentOscAvatarConfigPath(); @@ -69,11 +116,21 @@ public static OscAvatarConfig[] CreateAll() => return GetAvatarConfig(path); } + /// + /// Creates an instance of with the specified ID. + /// + /// The ID of the avatar to create. + /// An instance of with the specified ID, or if no avatar with the specified ID exists. public static OscAvatarConfig? Create(string avatarId) { return GetAvatarConfig(OscUtility.GetOscAvatarConfigPath(avatarId)); } + /// + /// Asynchronously waits until the current avatar is received, and creates the avatar config. + /// + /// The object that was deserialized. + /// Thrown if deserialization of the avatar configuration file fails. public static async ValueTask WaitAndCreateAtCurrentAsync() { var path = await OscUtility.WaitAndGetCurrentOscAvatarConfigPathAsync(); @@ -85,6 +142,11 @@ public static async ValueTask WaitAndCreateAtCurrentAsync() return config; } + /// + /// Deserializes the avatar configuration file at the specified path. + /// + /// The path of the avatar configuration file to deserialize. + /// The object that was deserialized, or if deserialization failed. private static OscAvatarConfig? GetAvatarConfig(string path) => JsonConvert.DeserializeObject(File.ReadAllText(path)); } diff --git a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameter.cs b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameter.cs index 5b6eab1..2881008 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameter.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameter.cs @@ -2,30 +2,67 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// The model of an avatar parameter. +/// [JsonObject] public record class OscAvatarParameter { #pragma warning disable IDE0044 // Add readonly modifier + /// + /// Gets the name of the parameter. + /// [JsonProperty("name", Required = Required.Always)] private string _name = string.Empty; + + /// + /// Gets the input interface for the parameter. + /// [JsonProperty("input", Required = Required.DisallowNull)] private OscAvatarParameterInterface? _input; + + /// + /// Gets the output interface for the parameter. + /// [JsonProperty("output", Required = Required.DisallowNull)] private OscAvatarParameterInterface? _output; #pragma warning restore IDE0044 // Add readonly modifier + /// + /// Gets the name of the parameter. + /// public string Name => _name; + + /// + /// Gets the input interface for the parameter. + /// public OscAvatarParameterInterface? Input => _input; + + /// + /// Gets the output interface for the parameter. + /// public OscAvatarParameterInterface? Output => _output; + /// + /// Gets the readable address for the parameter. + /// public string ReadableAddress => (Output ?? Input)!.Address; + /// + /// Initializes a new instance of the class. + /// [JsonConstructor] private OscAvatarParameter() { } + /// + /// Initializes a new instance of the class. + /// + /// The name of the parameter. + /// The input interface for the parameter. + /// The output interface for the parameter. public OscAvatarParameter(string name, OscAvatarParameterInterface? input = null, OscAvatarParameterInterface? output = null) { if (input == null && output == null) diff --git a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameterInterface.cs b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameterInterface.cs index 5befe17..3e034cf 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameterInterface.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParameterInterface.cs @@ -4,18 +4,39 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// This class provides an interface for Open Sound Control (OSC) messages to avatar parameter. +/// [JsonObject] public class OscAvatarParameterInterface { #pragma warning disable IDE0044 // Add readonly modifier + /// + /// Gets the address of the parameter interface. + /// [JsonProperty("address", Required = Required.Always)] private string _address = string.Empty; + + /// + /// Gets the blob string for the address of the parameter interface. + /// private BlobString _addressBlob = default; + + /// + /// Gets the OSC type of the parameter interface. + /// [JsonProperty("type", Required = Required.Always, ItemConverterType = typeof(StringEnumConverter))] private OscType _type = 0; #pragma warning restore IDE0044 // Add readonly modifier + /// + /// Gets the address of the parameter interface. + /// public string Address => _address; + + /// + /// Gets the blob string for the address of the parameter interface. + /// public BlobString AddressBlob { get @@ -28,16 +49,31 @@ public BlobString AddressBlob } } + /// + /// Gets the OSC type of the parameter interface. + /// public OscType OscType => _type; + + /// + /// Gets the OSC type of the parameter interface as a string. + /// public string Type => _type.ToString(); + /// + /// Initializes a new instance of the class. + /// [JsonConstructor] private OscAvatarParameterInterface() { } + /// + /// Initializes a new instance of the class. + /// + /// The address of the parameter interface. + /// The OSC type of the parameter interface. public OscAvatarParameterInterface(string address, OscType type) { _address = address; diff --git a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParametorContainer.cs b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParametorContainer.cs index a2a4e54..8044dc7 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParametorContainer.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/OscAvatarParametorContainer.cs @@ -8,6 +8,9 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// This class represents a container for avatar parameters in VRChat. +/// public class OscAvatarParametorContainer : IReadOnlyDictionary { #region Static methods(s) @@ -29,6 +32,11 @@ static OscAvatarParametorContainer() #endregion #region Constructor(s) + + /// + /// Creates a new instance of with the specified avatar parameters. + /// + /// The avatar parameters to be contained in this instance. public OscAvatarParametorContainer(ImmutableArray parameters) { Items = parameters; @@ -43,18 +51,45 @@ public OscAvatarParametorContainer(ImmutableArray parameters } } + /// + /// Creates a new instance of with the specified avatar parameters. + /// + /// The avatar parameters to be contained in this instance. public OscAvatarParametorContainer(IEnumerable parameters) : this(parameters.ToImmutableArray()) { } + #endregion #region Datas + /// + /// Gets the avatar parameters contained in this instance. + /// public ImmutableArray Items { get; } + + /// + /// Gets the avatar parameter with the specified name. + /// + /// The name of the avatar parameter to retrieve. + /// The avatar parameter with the specified name. public OscAvatarParameter Get(string name) => Items.First(p => p.Name == name); + + /// + /// Attempts to retrieve the avatar parameter with the specified name. + /// + /// The name of the avatar parameter to retrieve. + /// The avatar parameter with the specified name, if it exists; otherwise, null. internal OscAvatarParameter? TryGet(string name) => Items.FirstOrDefault(p => p.Name == name); + /// + /// Gets a collection of the unique avatar parameters contained in this instance. + /// public IEnumerable UniqueParameters => Items.Where(parm => !OscAvatarUtility.IsCommonParameter(parm.Name)); + + /// + /// Gets a collection of the values of the unique avatar parameters contained in this instance. + /// public IEnumerable UniqueParameterValues { get @@ -69,14 +104,31 @@ public IEnumerable UniqueParameterValues } } + /// + /// Gets a collection of the names of the avatar parameters contained in this instance. + /// public IEnumerable Names => Items.Select(param => param.Name); + /// + /// Gets a collection of the keys (i.e., names) of the avatar parameters contained in this instance. + /// public IEnumerable Keys => Names; + + /// + /// Gets a collection of the values of the avatar parameters contained in this instance. + /// public IEnumerable Values => Items.Select(v => GetAs(v.Name)); + /// + /// Gets the number of avatar parameters contained in this instance. + /// public int Count => Items.Length; private ImmutableArray _physBones; + + /// + /// Gets a contained in this instance. + /// public IReadOnlyList PhysBones { get @@ -140,12 +192,23 @@ private ImmutableArray CreatePhysBones() #endregion #region Value accessor(s) + + /// + /// Gets or sets the value of the avatar parameter with the specified name. + /// + /// The name of the avatar parameter whose value to get or set. public object? this[string name] { get => GetAs(name); set => SetAs(name, value); } + /// + /// Gets the value of the avatar parameter with the specified name as the specified type. + /// + /// The type to retrieve the avatar parameter value as. + /// The name of the avatar parameter whose value to retrieve. + /// The value of the avatar parameter as the specified type. public T? GetAs(string name) where T : notnull { var param = Get(name); @@ -157,6 +220,12 @@ public object? this[string name] return default; } + /// + /// Sets the value of the avatar parameter with the specified name to the specified value. + /// + /// The type of the value to set the avatar parameter to. + /// The name of the avatar parameter whose value to set. + /// The value to set the avatar parameter to. public void SetAs(string name, T value) { var inputInterface = Get(name).Input; @@ -181,8 +250,20 @@ public void SetAs(string name, T value) } } + /// + /// Determines whether this instance contains an avatar parameter with the specified name. + /// + /// The name of the avatar parameter to locate in this instance. + /// if this instance contains an avatar parameter with the specified name; otherwise, . public bool ContainsKey(string key) => Items.Any(param => param.Name == key); + /// + /// Tries to get the value of the avatar parameter with the specified name. + /// + /// The name of the avatar parameter whose value to get. + /// When this method returns, contains the value of the avatar parameter with the specified name, if found; + /// otherwise, the default value for the type of the parameter. + /// if the avatar parameter with the specified name is found; otherwise, . public bool TryGetValue(string key, #if NETSTANDARD2_1_OR_GREATER [NotNullWhen(true)] @@ -202,6 +283,11 @@ public bool TryGetValue(string key, #endregion #region Events + /// + /// Callback method that is called when the value of an avatar parameter changes. + /// + /// The object that raised the event. + /// The event data. private void GetValueCallback(IReadOnlyOscParameterCollection sender, ParameterChangedEventArgs e) { var name = e.Address.Substring(OscConst.AvatarParameterAddressSpace.Length); @@ -214,8 +300,16 @@ private void GetValueCallback(IReadOnlyOscParameterCollection sender, ParameterC OnParameterChanged(param, e); } + /// + /// Occurs when the value of an avatar parameter contained in this instance changes. + /// public event OscAvatarParameterChangedEventHandler? ParameterChanged; + /// + /// Raises the event. + /// + /// The avatar parameter whose value changed. + /// The event data. protected internal void OnParameterChanged(OscAvatarParameter param, ValueChangedEventArgs e) { ParameterChanged?.DynamicInvokeAllWithoutException(param, e); @@ -223,11 +317,13 @@ protected internal void OnParameterChanged(OscAvatarParameter param, ValueChange #endregion #region GetEnumerator method(s) + /// public IEnumerator> GetEnumerator() => Items .Select(param => new KeyValuePair(param.Name, GetAs(param.Name))) .GetEnumerator(); + /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion } diff --git a/src/VRCOscLib/VRCOscLib/Avatar/OscPhysBone.cs b/src/VRCOscLib/VRCOscLib/Avatar/OscPhysBone.cs index 306c0b6..4795998 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/OscPhysBone.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/OscPhysBone.cs @@ -5,28 +5,65 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// Represents a VRCPhysBone in an avatar. +/// public class OscPhysBone { private readonly OscAvatarParametorContainer _parameters; + /// + /// Gets the name of the parameter that represents this VRCPhysBone. + /// public string ParamName { get; } + /// + /// Gets a value indicating whether this VRCPhysBone is grabbed. + /// public bool IsGrabbed => GetParameterValue(nameof(IsGrabbed)); + + /// + /// Gets the angle of this VRCPhysBone. + /// public float Angle => GetParameterValue(nameof(Angle)); + + /// + /// Gets the stretch of this VRCPhysBone. + /// public float Stretch => GetParameterValue(nameof(Stretch)); + /// + /// Occurs when a parameter of this VRCPhysBone changes. + /// public event OscAvatarParameterChangedEventHandler? ParameterChanged; + /// + /// Initializes a new instance of the class with the specified avatar and parameter name. + /// + /// The avatar that the VRCPhysBone belongs to. + /// The name of the parameter that represents this VRCPhysBone. public OscPhysBone(OscAvatarConfig avatar, string paramName) : this(avatar.Parameters, paramName, true, nameof(avatar)) { } + /// + /// Initializes a new instance of the class with the specified parameter container and parameter name. + /// + /// The parameter container that the VRCPhysBone belongs to. + /// The name of the parameter that represents this VRCPhysBone. internal OscPhysBone(OscAvatarParametorContainer parameters, string paramName) : this(parameters, paramName, true, nameof(parameters)) { } + /// + /// Initializes a new instance of the class with the specified parameter container and parameter name. + /// + /// The parameter container that the VRCPhysBone belongs to. + /// The name of the parameter that represents this VRCPhysBone. + /// Indicates whether to check if the specified parameter exists in the parameter container. + /// The name of the parameter to include in the exception message if the check fails. internal OscPhysBone(OscAvatarParametorContainer parameters, string paramName, bool needCheck, string checkedParamName = "parameters") { (string Name, OscType Type)[] actualParam = { @@ -51,6 +88,13 @@ internal OscPhysBone(OscAvatarParametorContainer parameters, string paramName, b } } + /// + /// Throws an if the specified parameter does not exist in the parameter container. + /// + /// The parameter container to check for the specified parameter. + /// The name of the parameter to check for. + /// An array of tuples containing the names and types of the expected parameters. + /// The name of the parameter to include in the exception message if the check fails. private static void ThrowArgumentException_IfNotExistParameters( OscAvatarParametorContainer parameters, string paramName, @@ -87,18 +131,33 @@ private static void ThrowArgumentException_IfNotExistParameters( } } + /// + /// Raises the event when a value in the parameter collection changes. + /// + /// The parameter collection that raised the event. + /// The event data. private void GetValueCallback(IReadOnlyOscParameterCollection sender, ParameterChangedEventArgs e) { var name = e.Address.Substring(OscConst.AvatarParameterAddressSpace.Length); OnParameterChanged(_parameters.Get(name), e); } + /// + /// Raises the event with the specified parameter and event data. + /// + /// The parameter that changed. + /// The event data. protected internal void OnParameterChanged(OscAvatarParameter param, ValueChangedEventArgs e) { ParameterChanged?.Invoke(param, e); } - + /// + /// Gets the value of the specified parameter as the specified type. + /// + /// The type of the parameter value to get. + /// The name of the parameter to get the value of. + /// The value of the parameter, or if the parameter does not exist or is not of the specified type. private T? GetParameterValue(string name) where T : notnull { return _parameters.GetAs(ParamName + "_" + name); diff --git a/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs b/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs index 6575bfb..a94ec45 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs @@ -3,8 +3,14 @@ namespace BuildSoft.VRChat.Osc.Avatar; +/// +/// A utility class for interacting with VRChat avatars using the OSC protocol. +/// public static class OscAvatarUtility { + /// + /// A list of common avatar parameters. + /// internal static readonly HashSet _commonParameters = new() { "VRCFaceBlendV", @@ -38,16 +44,29 @@ internal static void RegisterAvaterConfig(OscAvatarConfig avatarConfig) AvatarConfigs.Add(new WeakReference(avatarConfig)); } + /// + /// Gets a dictionary of common avatar parameters and their current values. + /// public static IReadOnlyDictionary CommonParameters => _commonParameters.ToDictionary(s => s, GetCommonParameterValue); + /// + /// Gets the current . + /// public static OscAvatar CurrentAvatar => _currentAvatar; private static OscAvatar _currentAvatar; private static OscAvatar _changedAvatar; + + /// + /// Event that is raised when the current avatar changes. + /// public static event OscValueChangedEventHandler? AvatarChanged; + /// + /// Initializes the OSC avatar system. + /// public static void Initialize() { OscParameter.Initialize(); @@ -81,9 +100,25 @@ private static void ReadAvatarIdFromApp(IReadOnlyOscParameterCollection sender, CallOnAvatarChanged(); } + /// + /// Determines whether the specified parameter is a common parameter for VRChat avatars. + /// + /// The name of the parameter to check. + /// true if the parameter is common; otherwise, . public static bool IsCommonParameter(string paramName) => _commonParameters.Contains(paramName); + + /// + /// Gets the value of the specified common parameter for the current avatar. + /// + /// The name of the parameter to get the value of. + /// The value of the specified parameter, or null if the parameter does not exist or is not common. public static object? GetCommonParameterValue(string paramName) => OscParameter.GetValue(OscConst.AvatarParameterAddressSpace + paramName); + + /// + /// Gets the values of all common parameters for the current avatar. + /// + /// An enumerable containing the values of all common parameters for the current avatar. public static IEnumerable GetCommonParameterValues() => _commonParameters.Select(GetCommonParameterValue); diff --git a/src/VRCOscLib/VRCOscLib/Chatbox/OscChatbox.cs b/src/VRCOscLib/VRCOscLib/Chatbox/OscChatbox.cs index 05db6e9..0fced32 100644 --- a/src/VRCOscLib/VRCOscLib/Chatbox/OscChatbox.cs +++ b/src/VRCOscLib/VRCOscLib/Chatbox/OscChatbox.cs @@ -3,10 +3,28 @@ using BuildSoft.OscCore; namespace BuildSoft.VRChat.Osc.Chatbox; + +/// +/// Provides methods for sending messages and typing notifications to the VRChat chatbox. +/// public static class OscChatbox { + /// + /// The OSC address for sending chatbox input messages. + /// public static string InputAddress = "/chatbox/input"; + + /// + /// The OSC address for sending typing notifications. + /// public static string TypingAddress = "/chatbox/typing"; + + /// + /// Sends a message to the VRChat chatbox. + /// + /// The message to send. + /// Indicates whether the message shows in direct or UI. + /// Indicates whether the message uses to trigger the notification SFX. public static void SendMessage(string message, bool direct, bool complete = false) { OscClient client = OscUtility.Client; @@ -20,11 +38,20 @@ public static void SendMessage(string message, bool direct, bool complete = fals socket.Send(writer.Buffer, writer.Length, SocketFlags.None); } + /// + /// Sends a typing notification to the VRChat chatbox. + /// + /// Indicates whether the user is typing or not typing. public static void SetIsTyping(bool isTyping) { OscParameter.SendValue(TypingAddress, isTyping); } + /// + /// Writes the specified string in UTF-8 encoding to the OSC message. + /// + /// The OSC message writer to write the string to. + /// The string to write. private static void WriteUtfString(this OscWriter writer, string data) { var utf8String = Encoding.UTF8.GetBytes(data); diff --git a/src/VRCOscLib/VRCOscLib/Collections/IReadOnlyOscParameterCollection.cs b/src/VRCOscLib/VRCOscLib/Collections/IReadOnlyOscParameterCollection.cs index 9bae997..a58a860 100644 --- a/src/VRCOscLib/VRCOscLib/Collections/IReadOnlyOscParameterCollection.cs +++ b/src/VRCOscLib/VRCOscLib/Collections/IReadOnlyOscParameterCollection.cs @@ -2,10 +2,27 @@ namespace BuildSoft.VRChat.Osc; +/// +/// Represents a read-only collection of OSC parameters. +/// public interface IReadOnlyOscParameterCollection : IReadOnlyDictionary { + /// + /// Occurs when a value in the collection changes. + /// event ParamChangedHandler? ValueChanged; + /// + /// Adds an event handler to the collection that is invoked when the value of the parameter with the specified OSC address changes. + /// + /// The OSC address of the parameter to listen for value changes on. + /// The event handler to add. void AddValueChangedEventByAddress(string address, ParamChangedHandler handler); + + /// + /// Removes an event handler to the collection that is invoked when the value of the parameter with the specified OSC address changes. + /// + /// The OSC address of the parameter to listen for value changes on. + /// The event handler to remove. bool RemoveValueChangedEventByAddress(string address, ParamChangedHandler handler); } diff --git a/src/VRCOscLib/VRCOscLib/Collections/OscParameterCollection.cs b/src/VRCOscLib/VRCOscLib/Collections/OscParameterCollection.cs index 7629fb0..91c18cc 100644 --- a/src/VRCOscLib/VRCOscLib/Collections/OscParameterCollection.cs +++ b/src/VRCOscLib/VRCOscLib/Collections/OscParameterCollection.cs @@ -7,12 +7,16 @@ namespace BuildSoft.VRChat.Osc; +/// +/// A collection of OSC parameters that can be accessed using a string address. +/// public class OscParameterCollection : IDictionary, IReadOnlyOscParameterCollection { private readonly Dictionary _items = new(); private Dictionary>? _handlersPerAddress; + /// public object? this[string address] { get => _items[address]; @@ -28,23 +32,30 @@ public object? this[string address] } } + /// public ICollection Keys => _items.Keys; + /// public ICollection Values => _items.Values; + /// public int Count => _items.Count; + /// public bool IsReadOnly => false; + /// public void Add(string address, object? value) { _items.Add(address, value); OnValueChanged(new ParameterChangedEventArgs(null, value, address, ValueChangedReason.Added)); } + /// public void Add(KeyValuePair item) => Add(item.Key, item.Value); + /// public void Clear() { var copiedItems = _items.ToArray(); @@ -55,11 +66,14 @@ public void Clear() } } + /// public bool Contains(KeyValuePair item) => _items.TryGetValue(item.Key, out var value) && item.Value == value; + /// public bool ContainsKey(string key) => _items.ContainsKey(key); + /// public bool Remove(string key) { var item = _items; @@ -75,35 +89,52 @@ public bool Remove(string key) return false; } + /// public bool TryGetValue(string key, out object? value) => _items.TryGetValue(key, out value); + /// public IEnumerator> GetEnumerator() => _items.GetEnumerator(); #region Interface methods implemented explicitly + /// IEnumerable IReadOnlyDictionary.Keys => Keys; + /// IEnumerable IReadOnlyDictionary.Values => Values; + /// void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { ((ICollection>)_items).CopyTo(array, arrayIndex); } + /// bool ICollection>.Remove(KeyValuePair item) { return ((ICollection>)_items).Remove(item); } + /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion #region Event(s) + + /// public event ParamChangedHandler? ValueChanged; + /// + /// Raises the event and invokes the event handlers registered by address. + /// + /// The event data. protected void OnValueChanged(ParameterChangedEventArgs args) { ValueChanged?.DynamicInvokeAllWithoutException(this, args); OnValueChangedByAddress(args); } + /// + /// Invokes the event handlers registered by address for the event. + /// + /// The event data. protected void OnValueChangedByAddress(ParameterChangedEventArgs args) { var handlersPerAddress = _handlersPerAddress; @@ -131,6 +162,8 @@ protected void OnValueChangedByAddress(ParameterChangedEventArgs args) } #region Event registration methods + + /// public void AddValueChangedEventByAddress(string address, ParamChangedHandler handler) { var dict = _handlersPerAddress; @@ -147,6 +180,7 @@ public void AddValueChangedEventByAddress(string address, ParamChangedHandler ha dict.Add(address, new() { handler }); } + /// public bool RemoveValueChangedEventByAddress(string address, ParamChangedHandler handler) { var dict = _handlersPerAddress; diff --git a/src/VRCOscLib/VRCOscLib/Delegate/EventDelegateExtension.cs b/src/VRCOscLib/VRCOscLib/Delegate/EventDelegateExtension.cs index 324ec83..edaae52 100644 --- a/src/VRCOscLib/VRCOscLib/Delegate/EventDelegateExtension.cs +++ b/src/VRCOscLib/VRCOscLib/Delegate/EventDelegateExtension.cs @@ -1,7 +1,16 @@ namespace BuildSoft.VRChat.Osc.Delegate; +/// +/// Extension methods for . +/// internal static class EventDelegateExtension { + /// + /// Invokes all of the methods in the specified delegate, catching any exceptions that are thrown. + /// + /// The type of the delegate. + /// The delegate to invoke. + /// The arguments to pass to the delegate methods. public static void DynamicInvokeAllWithoutException(this T @delegate, params object[] args) where T : System.Delegate { foreach (var item in @delegate.GetInvocationList()) diff --git a/src/VRCOscLib/VRCOscLib/Delegate/OscParameterChangedEventHandler.cs b/src/VRCOscLib/VRCOscLib/Delegate/OscParameterChangedEventHandler.cs index 5f9d3c4..a59041f 100644 --- a/src/VRCOscLib/VRCOscLib/Delegate/OscParameterChangedEventHandler.cs +++ b/src/VRCOscLib/VRCOscLib/Delegate/OscParameterChangedEventHandler.cs @@ -3,5 +3,11 @@ using System.Text; namespace BuildSoft.VRChat.Osc; -public delegate void OscParameterChangedEventHandler(TSender sender, ParameterChangedEventArgs e); +/// +/// Represents a delegate that handles OSC parameter change events. +/// +/// The type of the sender of the event. +/// The sender of the event. +/// The event data. +public delegate void OscParameterChangedEventHandler(TSender sender, ParameterChangedEventArgs e); diff --git a/src/VRCOscLib/VRCOscLib/Delegate/OscValueChangedEventHandler.cs b/src/VRCOscLib/VRCOscLib/Delegate/OscValueChangedEventHandler.cs index f8046e3..d7ed116 100644 --- a/src/VRCOscLib/VRCOscLib/Delegate/OscValueChangedEventHandler.cs +++ b/src/VRCOscLib/VRCOscLib/Delegate/OscValueChangedEventHandler.cs @@ -3,4 +3,12 @@ using System.Text; namespace BuildSoft.VRChat.Osc; + +/// +/// Represents a delegate that handles value change events. +/// +/// The type of the sender of the event. +/// The type of the value that was changed. +/// The sender of the event. +/// The event data. public delegate void OscValueChangedEventHandler(TSender sender, ValueChangedEventArgs e); diff --git a/src/VRCOscLib/VRCOscLib/Event/Generic/ValueChangedEventArgs.cs b/src/VRCOscLib/VRCOscLib/Event/Generic/ValueChangedEventArgs.cs index a17aaf9..9d51672 100644 --- a/src/VRCOscLib/VRCOscLib/Event/Generic/ValueChangedEventArgs.cs +++ b/src/VRCOscLib/VRCOscLib/Event/Generic/ValueChangedEventArgs.cs @@ -1,9 +1,26 @@ namespace BuildSoft.VRChat.Osc; + +/// +/// Provides data for value change events. +/// +/// The type of the value that was changed. public class ValueChangedEventArgs : EventArgs { + /// + /// Gets the old value. + /// public T OldValue { get; } + + /// + /// Gets the new value. + /// public T NewValue { get; } + /// + /// Initializes a new instance of the class. + /// + /// The old value. + /// The new value. public ValueChangedEventArgs(T oldValue, T newValue) { OldValue = oldValue; diff --git a/src/VRCOscLib/VRCOscLib/Event/ParameterChangedEventArgs.cs b/src/VRCOscLib/VRCOscLib/Event/ParameterChangedEventArgs.cs index 3220655..14ab11a 100644 --- a/src/VRCOscLib/VRCOscLib/Event/ParameterChangedEventArgs.cs +++ b/src/VRCOscLib/VRCOscLib/Event/ParameterChangedEventArgs.cs @@ -1,8 +1,22 @@ namespace BuildSoft.VRChat.Osc; +/// +/// Provides data for OSC parameter change events. +/// public class ParameterChangedEventArgs : ValueChangedEventArgs { + /// + /// Gets the address of the OSC parameter that was changed. + /// public string Address { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The old value of the OSC parameter. + /// The new value of the OSC parameter. + /// The address of the OSC parameter. + /// The reason for the change in the OSC parameter's value. public ParameterChangedEventArgs(object? oldValue, object? newValue, string address, ValueChangedReason reason) : base(oldValue, newValue, reason) { diff --git a/src/VRCOscLib/VRCOscLib/Event/ValueChangedEventArgs.cs b/src/VRCOscLib/VRCOscLib/Event/ValueChangedEventArgs.cs index ef228f9..6260ebf 100644 --- a/src/VRCOscLib/VRCOscLib/Event/ValueChangedEventArgs.cs +++ b/src/VRCOscLib/VRCOscLib/Event/ValueChangedEventArgs.cs @@ -1,11 +1,31 @@ namespace BuildSoft.VRChat.Osc; +/// +/// Provides data for value change events. +/// public class ValueChangedEventArgs : EventArgs { + /// + /// Gets the old value. + /// public object? OldValue { get; } + + /// + /// Gets the new value. + /// public object? NewValue { get; } + + /// + /// Gets the reason for the change in value. + /// public ValueChangedReason Reason { get; } + /// + /// Initializes a new instance of the class. + /// + /// The old value. + /// The new value. + /// The reason for the change in the value. public ValueChangedEventArgs(object? oldValue, object? newValue, ValueChangedReason reason) { OldValue = oldValue; diff --git a/src/VRCOscLib/VRCOscLib/Event/ValueChangedReason.cs b/src/VRCOscLib/VRCOscLib/Event/ValueChangedReason.cs index 7539f39..ba5467a 100644 --- a/src/VRCOscLib/VRCOscLib/Event/ValueChangedReason.cs +++ b/src/VRCOscLib/VRCOscLib/Event/ValueChangedReason.cs @@ -1,8 +1,22 @@ namespace BuildSoft.VRChat.Osc; +/// +/// Specifies the reason for a change in the value. +/// public enum ValueChangedReason { + /// + /// The value was added. + /// Added, + + /// + /// The value was removed. + /// Removed, + + /// + /// The value was substituted. + /// Substituted } diff --git a/src/VRCOscLib/VRCOscLib/Input/OscAxisInput.cs b/src/VRCOscLib/VRCOscLib/Input/OscAxisInput.cs index 7daac02..0103237 100644 --- a/src/VRCOscLib/VRCOscLib/Input/OscAxisInput.cs +++ b/src/VRCOscLib/VRCOscLib/Input/OscAxisInput.cs @@ -2,18 +2,60 @@ namespace BuildSoft.VRChat.Osc.Input; +/// +/// Specifies the type of OSC axis input. +/// public enum OscAxisInput { + /// + /// The vertical axis input. + /// Vertical, + + /// + /// The horizontal axis input. + /// Horizontal, + + /// + /// The horizontal look axis input. + /// LookHorizontal, + + /// + /// The vertical look axis input. + /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Now not supported by VRChat. Do not use this. An unknown error may occur.")] LookVertical, + + /// + /// The right use axis input. + /// UseAxisRight, + + /// + /// The right grab axis input. + /// GrabAxisRight, + + /// + /// The forward/backward move-hold axis input. + /// MoveHoldFB, + + /// + /// The clockwise/counterclockwise spin-hold axis input. + /// SpinHoldCwCcw, + + /// + /// The up/down spin-hold axis input. + /// SpinHoldUD, + + /// + /// The left/right spin-hold axis input. + /// SpinHoldLR, } diff --git a/src/VRCOscLib/VRCOscLib/Input/OscButtonInput.cs b/src/VRCOscLib/VRCOscLib/Input/OscButtonInput.cs index ffa8586..ddee310 100644 --- a/src/VRCOscLib/VRCOscLib/Input/OscButtonInput.cs +++ b/src/VRCOscLib/VRCOscLib/Input/OscButtonInput.cs @@ -2,44 +2,149 @@ namespace BuildSoft.VRChat.Osc.Input; +/// +/// Specifies the type of OSC button input. +/// public enum OscButtonInput { + /// + /// The move forward button input. + /// MoveForward, + + /// + /// The move backward button input. + /// MoveBackward, + + /// + /// The move left button input. + /// MoveLeft, + + /// + /// The move right button input. + /// MoveRight, + + /// + /// The look left button input. + /// LookLeft, + + /// + /// The look right button input. + /// LookRight, + + /// + /// The look down button input. + /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Now not supported by VRChat. Do not use this. An unknown error may occur.")] LookDown, + + /// + /// The look up button input. + /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Now not supported by VRChat. Do not use this. An unknown error may occur.")] LookUp, + /// + /// The jump button input. + /// Jump, + + /// + /// The run button input. + /// Run, + + /// + /// The back button input. + /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Now not supported by VRChat. Do not use this. An unknown error may occur.")] Back, + + /// + /// The menu button input. + /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Now not supported by VRChat. Do not use this. An unknown error may occur.")] Menu, + + /// + /// The comfort left button input. + /// ComfortLeft, + + /// + /// The comfort right button input. + /// ComfortRight, + + /// + /// The drop right button input. + /// DropRight, + + /// + /// The use right button input. + /// UseRight, + + /// + /// The grab right button input. + /// GrabRight, + + /// + /// The drop left button input. + /// DropLeft, + + /// + /// The use left button input. + /// UseLeft, + + /// + /// The grab left button input. + /// GrabLeft, + + /// + /// The panic button input. + /// PanicButton, + + /// + /// The quick menu toggle left button input. + /// QuickMenuToggleLeft, + + /// + /// The quick menu toggle right button input. + /// QuickMenuToggleRight, + + /// + /// The toggle sit/stand button input. + /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Now not supported by VRChat. Do not use this. An unknown error may occur.")] ToggleSitStand, + + /// + /// The AFK toggle button input. + /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Now not supported by VRChat. Do not use this. An unknown error may occur.")] AFKToggle, + + /// + /// The voice button input. + /// Voice, } diff --git a/src/VRCOscLib/VRCOscLib/Input/OscInput.cs b/src/VRCOscLib/VRCOscLib/Input/OscInput.cs index db7d305..b498a49 100644 --- a/src/VRCOscLib/VRCOscLib/Input/OscInput.cs +++ b/src/VRCOscLib/VRCOscLib/Input/OscInput.cs @@ -3,31 +3,76 @@ namespace BuildSoft.VRChat.Osc.Input; +/// +/// Provides a way to manipulate input controls with OSC. +/// public static class OscInput { + /// + /// A cache of OSC addresses for values. + /// private static readonly Dictionary _axisInputAddressCache = new(); + + /// + /// A cache of OSC addresses for values. + /// private static readonly Dictionary _buttonInputAddressCache = new(); + + /// + /// The active button inputs. + /// private static IEnumerable? _activeButtonInputs; + + /// + /// The active axis inputs. + /// private static IEnumerable? _activeAxisInputs; + + /// + /// Sends an OSC message with the specified content. + /// + /// The OSC button input content. + /// A value indicating whether the button is being pressed () or released (). public static void Send(this OscButtonInput content, bool isOn = true) { OscParameter.SendValue(content.CreateAddress(), isOn ? 1 : 0); } + + /// + /// Sends an OSC message to press the specified . + /// + /// The OSC button input to press. public static void Press(this OscButtonInput content) { Send(content, true); } + + /// + /// Sends an OSC message to release the specified . + /// + /// The OSC button input to release. public static void Release(this OscButtonInput content) { Send(content, false); } + /// + /// Sends the specified value to the OSC address associated with the specified content. + /// The value will be clamped between -1 and 1. + /// + /// The axis input to send the value for. + /// The value to send. This will be clamped between -1 and 1. public static void Send(this OscAxisInput content, float value) { OscParameter.SendValue(content.CreateAddress(), MathHelper.Clamp(value, -1f, 1f)); } + /// + /// Gets the OSC address associated with the specified content. + /// + /// The button input to get the OSC address for. + /// The OSC address associated with the specified button input. public static string CreateAddress(this OscButtonInput content) { if (_buttonInputAddressCache.TryGetValue(content, out var address)) @@ -46,6 +91,11 @@ public static string CreateAddress(this OscButtonInput content) return address; } + /// + /// Gets the OSC address associated with the specified content. + /// + /// The axis input to get the OSC address for. + /// The OSC address associated with the specified axis input. public static string CreateAddress(this OscAxisInput content) { if (_axisInputAddressCache.TryGetValue(content, out var address)) @@ -64,9 +114,21 @@ public static string CreateAddress(this OscAxisInput content) return address; } + /// + /// Gets the active button inputs. + /// public static IEnumerable ActiveButtonInputs => _activeButtonInputs ??= CreateActiveFields(); + + /// + /// Gets the active axis inputs. + /// public static IEnumerable ActiveAxisInputs => _activeAxisInputs ??= CreateActiveFields(); + /// + /// Creates a collection of active fields of the specified type. + /// + /// The type of the fields to retrieve. Must be an enumeration type. + /// A collection of active fields of the specified type. private static IEnumerable CreateActiveFields() where T : Enum { return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static) diff --git a/src/VRCOscLib/VRCOscLib/OscType.cs b/src/VRCOscLib/VRCOscLib/OscType.cs index 00aef40..efda36b 100644 --- a/src/VRCOscLib/VRCOscLib/OscType.cs +++ b/src/VRCOscLib/VRCOscLib/OscType.cs @@ -4,9 +4,23 @@ namespace BuildSoft.VRChat.Osc; +/// +/// An enumeration of OSC types. +/// public enum OscType { + /// + /// The OSC type for a boolean value. + /// Bool, + + /// + /// The OSC type for an integer value. + /// Int, + + /// + /// The OSC type for a floating-point value. + /// Float, } diff --git a/src/VRCOscLib/VRCOscLib/Tracking/OscTracker.cs b/src/VRCOscLib/VRCOscLib/Tracking/OscTracker.cs index 7055d67..6f3ad1b 100644 --- a/src/VRCOscLib/VRCOscLib/Tracking/OscTracker.cs +++ b/src/VRCOscLib/VRCOscLib/Tracking/OscTracker.cs @@ -1,19 +1,39 @@ using BuildSoft.OscCore.UnityObjects; namespace BuildSoft.VRChat.Osc.Tracking; + +/// +/// Provides an OSC tracker +/// public class OscTracker { + /// + /// The number of supported trackers. + /// public static readonly int SupportedTrackerCount = 8; + /// + /// The OSC address for the position of the tracker. + /// public string PositionAddress { get; } + + /// + /// The OSC address for the rotation of the tracker. + /// public string RotationAddress { get; } + /// + /// Gets or sets the position of the tracker. + /// public Vector3 Position { get => OscParameter.GetValueAsVector3(PositionAddress) ?? default; set => OscParameter.SendValue(PositionAddress, value); } + /// + /// Gets or sets the rotation of the tracker. + /// public Vector3 Rotation { get => OscParameter.GetValueAsVector3(RotationAddress) ?? default; @@ -37,6 +57,10 @@ public OscTracker(int index) : this((index + 1).ToString()) } } + /// + /// Create the OSC tracker. + /// + /// The part of the OSC address for the tracker. internal OscTracker(string part) { PositionAddress = $"/tracking/trackers/{part}/position"; diff --git a/src/VRCOscLib/VRCOscLib/Tracking/OscTracking.cs b/src/VRCOscLib/VRCOscLib/Tracking/OscTracking.cs index d544b9b..020331b 100644 --- a/src/VRCOscLib/VRCOscLib/Tracking/OscTracking.cs +++ b/src/VRCOscLib/VRCOscLib/Tracking/OscTracking.cs @@ -2,14 +2,34 @@ namespace BuildSoft.VRChat.Osc.Tracking; +/// +/// Provide methods for interacting with OSC tracking. +/// public class OscTracking { + /// + /// The head tracker. + /// private static OscTracker? _headTracker; + /// + /// A lazy-initialized array of all trackers. + /// private static readonly Lazy> _trackers = new(CreateTrackers); + /// + /// Gets the head tracker. + /// public static OscTracker HeadTracker => _headTracker ??= new OscTracker("head"); + + /// + /// Gets all trackers. + /// public static ImmutableArray Trackers => _trackers.Value; + /// + /// Creates an array of all trackers. + /// + /// An array of all trackers. private static ImmutableArray CreateTrackers() { var trackers = ImmutableArray.CreateBuilder(OscTracker.SupportedTrackerCount); diff --git a/src/VRCOscLib/VRCOscLib/Utility/MathHelper.cs b/src/VRCOscLib/VRCOscLib/Utility/MathHelper.cs index 4153052..08ad576 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/MathHelper.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/MathHelper.cs @@ -3,8 +3,21 @@ using System.Text; namespace BuildSoft.VRChat.Osc.Utility; + +/// +/// Provide various math utility methods. +/// internal static class MathHelper { + /// + /// Clamps a value between a minimum and a maximum. + /// + /// The type of the value to clamp. + /// The value to clamp. + /// The minimum value. + /// The maximum value. + /// The clamped value. + /// Thrown if is greater than . public static T Clamp(T value, T min, T max) where T : IComparable { if (min.CompareTo(max) > 0) diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscConnectionSettings.cs b/src/VRCOscLib/VRCOscLib/Utility/OscConnectionSettings.cs index 21fa944..83df243 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscConnectionSettings.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscConnectionSettings.cs @@ -2,17 +2,45 @@ namespace BuildSoft.VRChat.Osc; +/// +/// The settings for an OSC connection. +/// public static class OscConnectionSettings { + /// + /// Indicates whether has been initialized. + /// internal static bool _utilityInitialized = false; + /// + /// The OSC server used to receive messages. + /// private static OscServer? _server; + + /// + /// The OSC client used to send messages. + /// private static OscClient? _client; - + + /// + /// Gets the OSC server used to receive messages. + /// internal static OscServer Server => _server ??= new OscServer(_receivePort); + + /// + /// Gets the OSC client used to send messages. + /// internal static OscClient Client => _client ??= new OscClient(_vrcIPAddress, _sendPort); + /// + /// The port number used to receive OSC messages. + /// private static int _receivePort = 9001; + + /// + /// Gets or sets the port number used to receive OSC messages. + /// + /// Thrown when the value is less than 0 or greater than 65535. public static int ReceivePort { get => _receivePort; @@ -47,7 +75,15 @@ public static int ReceivePort } } + /// + /// The port number used to send OSC messages. + /// private static int _sendPort = 9000; + + /// + /// Gets or sets the port number used to send OSC messages. + /// + /// Thrown when the value is less than 0 or greater than 65535. public static int SendPort { get => _sendPort; @@ -71,8 +107,16 @@ public static int SendPort } } + /// + /// The IP address to VRChat client running. + /// + private static string _vrcIPAddress = "127.0.0.1"; + /// + /// Gets or sets the IP address of the VRChat client to send OSC messages to. + /// + /// Thrown when the value cannot be parsed as an IP address. public static string VrcIPAddress { get => _vrcIPAddress; @@ -89,5 +133,8 @@ public static string VrcIPAddress } } + /// + /// A list of callbacks to be invoked when an OSC message is received. + /// internal static List MonitorCallbacks { get; } = new List(); } diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscConst.cs b/src/VRCOscLib/VRCOscLib/Utility/OscConst.cs index e9c6a2d..91e3f7b 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscConst.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscConst.cs @@ -3,9 +3,19 @@ using System.Text; namespace BuildSoft.VRChat.Osc; + +/// +/// A class containing constants used in the OSC communication. +/// internal class OscConst { + /// + /// The address space for avatar parameter messages. + /// public const string AvatarParameterAddressSpace = "/avatar/parameters/"; - public const string AvatarIdAddress = "/avatar/change"; + /// + /// The address for avatar change messages. + /// + public const string AvatarIdAddress = "/avatar/change"; } diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Receiver.cs b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Receiver.cs index b18d207..b449074 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Receiver.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Receiver.cs @@ -9,6 +9,11 @@ namespace BuildSoft.VRChat.Osc; public static partial class OscParameter { + /// + /// Handles an incoming OSC message by updating the corresponding OSC parameter in the collection. + /// + /// The address of the OSC message. + /// The values contained in the OSC message. internal static void ReceiveMessage(BlobString address, OscMessageValues values) { var addressString = address.ToString(); @@ -30,6 +35,11 @@ internal static void ReceiveMessage(BlobString address, OscMessageValues values) Parameters[addressString] = objects; } + /// + /// Gets the value of an OSC parameter as a . + /// + /// The address of the OSC parameter. + /// The value of the OSC parameter as a , or if the value cannot be converted to a . internal static Vector3? GetValueAsVector3(string address) { Parameters.TryGetValue(address, out var value); @@ -57,6 +67,11 @@ internal static void ReceiveMessage(BlobString address, OscMessageValues values) return new(x, y, z); } + /// + /// Gets the value of an OSC parameter. + /// + /// The address of the OSC parameter. + /// The value of the OSC parameter, or if the parameter does not exist. public static object? GetValue(string address) { Parameters.TryGetValue(address, out var value); diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs index ff0fc9f..114a4d4 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs @@ -9,66 +9,142 @@ namespace BuildSoft.VRChat.Osc; public static partial class OscParameter { #region SendAvatarParameter + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, float value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, int value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, bool value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, string value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, double value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + ///// + ///// Sends an OSC message with the specified value to the specified OSC address. + ///// + ///// The name of the OSC parameter. + ///// The value of the OSC parameter. //public static void SendAvatarParameter(string name, long value) //{ // string address = OscConst.AvatarParameterAddressSpace + name; // SendValue(address, value); //} + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, Vector2 value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, Vector3 value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, Color32 value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, MidiMessage value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified [] value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, byte[] value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, char value) { string address = OscConst.AvatarParameterAddressSpace + name; SendValue(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. public static void SendAvatarParameter(string name, object value) { string address = OscConst.AvatarParameterAddressSpace + name; @@ -77,61 +153,132 @@ public static void SendAvatarParameter(string name, object value) #endregion #region SendValue + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, float value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, int value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, bool value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, string value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, double value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + ///// + ///// Sends an OSC message with the specified value to the specified OSC address. + ///// + ///// The OSC address to send the message to. + ///// The value to send in the OSC message. //public static void SendValue(string address, long value) //{ // Parameters[address] = value; // OscUtility.Client.Send(address, value); //} + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, Vector2 value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, Vector3 value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, Color32 value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, MidiMessage value) { Parameters[address] = value; OscUtility.Client.Send(address, value); } + + /// + /// Sends an OSC message with the specified [] value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, byte[] value) { Parameters[address] = value; OscUtility.Client.Send(address, value, value.Length); } + + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. public static void SendValue(string address, char value) { Parameters[address] = value; diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.cs b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.cs index 97a2c8c..d329bc7 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.cs @@ -6,10 +6,20 @@ using ParamChangedHandler = BuildSoft.VRChat.Osc.OscParameterChangedEventHandler; namespace BuildSoft.VRChat.Osc; + +/// +/// Provides a way to get/set OSC parameters and parameter values. +/// public static partial class OscParameter { + /// + /// A collection of OSC parameters. + /// internal static OscParameterCollection Parameters { get; } = new(); + /// + /// An event that is raised when the value of an OSC parameter is changed. + /// public static event ParamChangedHandler ValueChanged { add => Parameters.ValueChanged += value; @@ -33,6 +43,9 @@ static OscParameter() } } + /// + /// Initializes the OSC parameter system. + /// internal static void Initialize() { MonitorCallback callback = ReceiveMessage; diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscUtility.AvatarConfig.cs b/src/VRCOscLib/VRCOscLib/Utility/OscUtility.AvatarConfig.cs index 7f5699d..a1d0083 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscUtility.AvatarConfig.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscUtility.AvatarConfig.cs @@ -4,6 +4,10 @@ namespace BuildSoft.VRChat.Osc; public static partial class OscUtility { + /// + /// Gets the file path of the configuration file for the currently selected avatar. + /// + /// The file path of the configuration file for the currently selected avatar, or if no avatar is selected. public static string? GetCurrentOscAvatarConfigPath() { var avatarId = OscAvatarUtility.CurrentAvatar.Id; @@ -14,6 +18,12 @@ public static partial class OscUtility return GetOscAvatarConfigPath(avatarId); } + /// + /// Asynchronously waits for an avatar to be selected and then gets the file path of the configuration file for the currently selected avatar. + /// + /// A that can be used to cancel the operation. + /// The file path of the configuration file for the currently selected avatar. + /// The operation was cancelled. public static async ValueTask WaitAndGetCurrentOscAvatarConfigPathAsync(CancellationToken token = default) { string? avatarId = OscAvatarUtility.CurrentAvatar.Id; @@ -25,6 +35,13 @@ public static async ValueTask WaitAndGetCurrentOscAvatarConfigPathAsync( return GetOscAvatarConfigPath(avatarId); } + /// + /// Gets the file path for the avatar configuration file with the specified avatar ID. + /// If the avatar configuration file is not found, a is thrown. + /// + /// The avatar ID for the avatar configuration file to be retrieved. + /// The file path for the avatar configuration file with the specified avatar ID. + /// Throws if the avatar configuration file is not found. public static string GetOscAvatarConfigPath(string avatarId) { try @@ -37,11 +54,19 @@ public static string GetOscAvatarConfigPath(string avatarId) } } + /// + /// Gets the paths to all OSC avatar config files. + /// + /// An immutable array of strings representing the paths to the OSC avatar config files. public static ImmutableArray GetOscAvatarConfigPathes() { return EnumerateOscAvatarConfigPathes().ToImmutableArray(); } + /// + /// Enumerates the paths to all OSC avatar config files. + /// + /// An enumerable collection of strings representing the paths to the OSC avatar config files. internal static IEnumerable EnumerateOscAvatarConfigPathes() { if (!Directory.Exists(VRChatOscPath)) diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscUtility.Connection.cs b/src/VRCOscLib/VRCOscLib/Utility/OscUtility.Connection.cs index 94df899..bccc4f0 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscUtility.Connection.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscUtility.Connection.cs @@ -4,10 +4,14 @@ namespace BuildSoft.VRChat.Osc; public static partial class OscUtility { + /// internal static OscServer Server => OscConnectionSettings.Server; + + /// internal static OscClient Client => OscConnectionSettings.Client; + /// [Obsolete($"Use '{nameof(OscConnectionSettings)}.{nameof(OscConnectionSettings.ReceivePort)}'")] public static int ReceivePort { @@ -15,6 +19,7 @@ public static int ReceivePort set => OscConnectionSettings.ReceivePort = value; } + /// [Obsolete($"Use '{nameof(OscConnectionSettings)}.{nameof(OscConnectionSettings.SendPort)}'")] public static int SendPort { @@ -22,6 +27,7 @@ public static int SendPort set => OscConnectionSettings.SendPort = value; } + /// [Obsolete($"Use '{nameof(OscConnectionSettings)}.{nameof(OscConnectionSettings.VrcIPAddress)}'")] public static string VrcIPAddress { @@ -29,13 +35,21 @@ public static string VrcIPAddress set => OscConnectionSettings.VrcIPAddress = value; } - + /// + /// Registers a monitor callback with the OSC server and adds it to the list of monitor callbacks. + /// + /// The callback to register and add to the list of monitor callbacks. public static void RegisterMonitorCallback(MonitorCallback callback) { var callbacks = OscConnectionSettings.MonitorCallbacks; Server.AddMonitorCallback(callback); callbacks.Add(callback); } + + /// + /// Unregisters a monitor callback from the OSC server and removes it from the list of monitor callbacks. + /// + /// The callback to unregister and remove from the list of monitor callbacks. public static void UnregisterMonitorCallback(MonitorCallback callback) { var callbacks = OscConnectionSettings.MonitorCallbacks; diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscUtility.cs b/src/VRCOscLib/VRCOscLib/Utility/OscUtility.cs index 52ec9f0..ae40175 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscUtility.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscUtility.cs @@ -3,15 +3,41 @@ namespace BuildSoft.VRChat.Osc; +/// +/// Provides basic functionality about OSC. +/// public static partial class OscUtility { + /// + /// The path to the user's profile directory. + /// internal static readonly string UserProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + + /// + /// The path to the VRChat AppData directory. + /// public static readonly string VRChatAppDataPath = Path.Combine(UserProfile, @"AppData", "LocalLow", "VRChat", "VRChat"); + + /// + /// The path to the VRChat OSC directory. + /// public static readonly string VRChatOscPath = Path.Combine(VRChatAppDataPath, @"Osc"); + + /// + /// A list of exceptions that were thrown during the initialization of the OSC utility. + /// internal static readonly List _initializationExceptions = new(); + + /// + /// Indicates whether the OSC utility failed to initialize automatically. + /// + /// if the OSC utility failed to initialize automatically, otherwise . public static bool IsFailedAutoInitialization => _initializationExceptions.Count > 0; + /// + /// Initializes the OSC utility. + /// public static void Initialize() { OscAvatarUtility.Initialize(); @@ -30,6 +56,13 @@ static OscUtility() OscConnectionSettings._utilityInitialized = true; } + /// + /// Reads a value from the specified index in an OSC message values object. + /// + /// The OSC message values object to read from. + /// The index of the value to read. + /// The value at the specified index in the OSC message values object, or null if the value is a nil type tag. + /// Thrown if the type tag at the specified index is an array start or array end type tag. internal static object? ReadValue(this OscMessageValues value, int index) { return value.GetTypeTag(index) switch @@ -54,6 +87,12 @@ static OscUtility() }; } + /// + /// Determines whether the specified objects are equal. + /// + /// The first object to compare. + /// The second object to compare. + /// if the specified objects are equal, otherwise . internal static bool AreEqual(object? left, object? right) => left is null ? right is null : left.Equals(right); } diff --git a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj index 72e8b30..9fc6ac1 100644 --- a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj +++ b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj @@ -9,6 +9,9 @@ ..\..\..\artifacts\bin + True + ..\..\..\artifacts\xml\$(AssemblyName).xml + VRCOscLib 1.4.2 ChanyaKushima From 112e077ad664f6297ae47197df24c6f988fb0b77 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 00:09:46 +0900 Subject: [PATCH 02/14] Added test --- .../Tests/vrcosclib.Test/Avatar/OscAvatarParameterTests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/VRCOscLib/Tests/vrcosclib.Test/Avatar/OscAvatarParameterTests.cs b/src/VRCOscLib/Tests/vrcosclib.Test/Avatar/OscAvatarParameterTests.cs index 41c5cbb..3325088 100644 --- a/src/VRCOscLib/Tests/vrcosclib.Test/Avatar/OscAvatarParameterTests.cs +++ b/src/VRCOscLib/Tests/vrcosclib.Test/Avatar/OscAvatarParameterTests.cs @@ -31,4 +31,10 @@ public void CtorTest() Assert.IsNull(parameter3.Output); Assert.AreEqual(input.Address, parameter3.ReadableAddress); } + + [Test] + public void Ctor_BothNullTest() + { + Assert.Throws(() => new OscAvatarParameter("param", null, null)); + } } From f85d8cc54b1e7b4bc50dd00a3e3a54bfa755dd07 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 00:10:02 +0900 Subject: [PATCH 03/14] Updated test packages. --- .../vrcosclib.OscUtilityInitialize.Test.csproj | 2 +- src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj index c672080..03f7eec 100644 --- a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj index 073b49b..eefb293 100644 --- a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj @@ -16,7 +16,7 @@ - + From 49ddf1717eba674be755cab6f12c59f3534adbb7 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 21:04:46 +0900 Subject: [PATCH 04/14] Added `SendAvatarParameter(string, long)` --- .../Utility/OscParameterTests.cs | 10 +++++ .../VRCOscLib/Utility/OscParameter.Sender.cs | 40 +++++++++---------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/VRCOscLib/Tests/vrcosclib.Test/Utility/OscParameterTests.cs b/src/VRCOscLib/Tests/vrcosclib.Test/Utility/OscParameterTests.cs index 909bae9..384b981 100644 --- a/src/VRCOscLib/Tests/vrcosclib.Test/Utility/OscParameterTests.cs +++ b/src/VRCOscLib/Tests/vrcosclib.Test/Utility/OscParameterTests.cs @@ -62,6 +62,11 @@ public async Task SendAvatarParameterTest() Assert.AreEqual(10, value.ReadIntElementUnchecked(0)); value = null; + OscParameter.SendAvatarParameter(ParamName, 1234567890123456789); + await LoopWhile(() => value == null, LatencyTimeout); + Assert.AreEqual(1234567890123456789, value.ReadInt64ElementUnchecked(0)); + value = null; + OscParameter.SendAvatarParameter(ParamName, true); await LoopWhile(() => value == null, LatencyTimeout); Assert.AreEqual(true, value.ReadBooleanElement(0)); @@ -139,6 +144,11 @@ public async Task SendValueTest() Assert.AreEqual(10, value.ReadIntElementUnchecked(0)); value = null; + OscParameter.SendValue(Address, 1234567890123456789); + await LoopWhile(() => value == null, LatencyTimeout); + Assert.AreEqual(1234567890123456789, value.ReadInt64ElementUnchecked(0)); + value = null; + OscParameter.SendValue(Address, true); await LoopWhile(() => value == null, LatencyTimeout); Assert.AreEqual(true, value.ReadBooleanElement(0)); diff --git a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs index 114a4d4..ce113f3 100644 --- a/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs +++ b/src/VRCOscLib/VRCOscLib/Utility/OscParameter.Sender.cs @@ -63,16 +63,16 @@ public static void SendAvatarParameter(string name, double value) SendValue(address, value); } - ///// - ///// Sends an OSC message with the specified value to the specified OSC address. - ///// - ///// The name of the OSC parameter. - ///// The value of the OSC parameter. - //public static void SendAvatarParameter(string name, long value) - //{ - // string address = OscConst.AvatarParameterAddressSpace + name; - // SendValue(address, value); - //} + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The name of the OSC parameter. + /// The value of the OSC parameter. + public static void SendAvatarParameter(string name, long value) + { + string address = OscConst.AvatarParameterAddressSpace + name; + SendValue(address, value); + } /// /// Sends an OSC message with the specified value to the specified OSC address. @@ -208,16 +208,16 @@ public static void SendValue(string address, double value) OscUtility.Client.Send(address, value); } - ///// - ///// Sends an OSC message with the specified value to the specified OSC address. - ///// - ///// The OSC address to send the message to. - ///// The value to send in the OSC message. - //public static void SendValue(string address, long value) - //{ - // Parameters[address] = value; - // OscUtility.Client.Send(address, value); - //} + /// + /// Sends an OSC message with the specified value to the specified OSC address. + /// + /// The OSC address to send the message to. + /// The value to send in the OSC message. + public static void SendValue(string address, long value) + { + Parameters[address] = value; + OscUtility.Client.Send(address, value); + } /// /// Sends an OSC message with the specified value to the specified OSC address. From f02a43f9fb88839ab7e6f4800ed79515bf249863 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 21:06:10 +0900 Subject: [PATCH 05/14] Update a package --- src/VRCOscLib/VRCOscLib/vrcosclib.csproj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj index 9fc6ac1..6381003 100644 --- a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj +++ b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj @@ -6,9 +6,9 @@ BuildSoft.VRChat.Osc 10.0 enable - + ..\..\..\artifacts\bin - + True ..\..\..\artifacts\xml\$(AssemblyName).xml @@ -22,16 +22,16 @@ - + - + - + <_FakeOutputPath Include="$(MSBuildProjectDirectory)\$(PackageOutputPath)\$(AssemblyName).dll" /> From 109cf0da9db22839a97f76018f4caccc10d32a10 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 21:07:55 +0900 Subject: [PATCH 06/14] Updated LangVersion --- .../vrcosclib.OscUtilityInitialize.Test.csproj | 2 +- src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj | 4 ++-- src/VRCOscLib/VRCOscLib/vrcosclib.csproj | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj index 03f7eec..e8f9875 100644 --- a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj @@ -5,7 +5,7 @@ net6.0 enable BuildSoft.VRChat.Osc.Test - 10.0 + 11.0 enable false true diff --git a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj index eefb293..9c1ffd9 100644 --- a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj @@ -5,9 +5,9 @@ net6.0 enable BuildSoft.VRChat.Osc.Test - 10.0 + 11.0 enable - false + false true diff --git a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj index 6381003..46d2dc4 100644 --- a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj +++ b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj @@ -3,8 +3,8 @@ netstandard2.0;netstandard2.1 enable - BuildSoft.VRChat.Osc - 10.0 + BuildSoft.VRChat.Osc + 11.0 enable ..\..\..\artifacts\bin From 578c6fb60fd8f4346244f04f6d10b3ba1477583a Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 21:16:04 +0900 Subject: [PATCH 07/14] Updated for .NET 7 --- src/Sample/AvatarParameterSender/AvatarParameterSender.csproj | 2 +- src/Sample/ChatboxSender/ChatboxSender.csproj | 2 +- src/Sample/GuiController/GuiController.csproj | 2 +- src/Sample/LogAvatarParametars/LogAvatarParametars.csproj | 2 +- .../vrcosclib.OscUtilityInitialize.Test.csproj | 4 ++-- src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj b/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj index 0214168..156dbc1 100644 --- a/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj +++ b/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows + net7.0-windows enable true ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/Sample/ChatboxSender/ChatboxSender.csproj b/src/Sample/ChatboxSender/ChatboxSender.csproj index ab645ce..a376e47 100644 --- a/src/Sample/ChatboxSender/ChatboxSender.csproj +++ b/src/Sample/ChatboxSender/ChatboxSender.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable enable ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/Sample/GuiController/GuiController.csproj b/src/Sample/GuiController/GuiController.csproj index 7ba246b..07b709b 100644 --- a/src/Sample/GuiController/GuiController.csproj +++ b/src/Sample/GuiController/GuiController.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows + net7.0-windows enable true ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj b/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj index ab645ce..a376e47 100644 --- a/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj +++ b/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable enable ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj index e8f9875..082a87c 100644 --- a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj @@ -1,8 +1,8 @@ - net6.0;net461 - net6.0 + net6.0;net7.0;net461 + net6.0;net7.0 enable BuildSoft.VRChat.Osc.Test 11.0 diff --git a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj index 9c1ffd9..a86a092 100644 --- a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj @@ -1,8 +1,8 @@  - net6.0;net461 - net6.0 + net6.0;net7.0;net461 + net6.0;net7.0 enable BuildSoft.VRChat.Osc.Test 11.0 From 4efc69186bde1f00ac8fac600c9aa7d9ab6b4132 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 21:22:37 +0900 Subject: [PATCH 08/14] Update dotnet.yml --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b2cfd04..40808bf 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: 7.0.* - name: Restore dependencies run: dotnet restore /p:Platform="For Test" - name: Test Build @@ -29,7 +29,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: 7.0.* - name: Restore dependencies run: dotnet restore /p:Platform="Full Build" - name: Full Build From 08b2b9d538866cea63853a3fda34eaf7335e707c Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 21:30:23 +0900 Subject: [PATCH 09/14] Revert "Update dotnet.yml" This reverts commit 4efc69186bde1f00ac8fac600c9aa7d9ab6b4132. --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 40808bf..b2cfd04 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.* + dotnet-version: 6.0.x - name: Restore dependencies run: dotnet restore /p:Platform="For Test" - name: Test Build @@ -29,7 +29,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.* + dotnet-version: 6.0.x - name: Restore dependencies run: dotnet restore /p:Platform="Full Build" - name: Full Build From e10d2aab003e1ff2e35d4c9d120bdac7ce8d2400 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Sat, 17 Dec 2022 21:30:31 +0900 Subject: [PATCH 10/14] Revert "Updated for .NET 7" This reverts commit 578c6fb60fd8f4346244f04f6d10b3ba1477583a. --- src/Sample/AvatarParameterSender/AvatarParameterSender.csproj | 2 +- src/Sample/ChatboxSender/ChatboxSender.csproj | 2 +- src/Sample/GuiController/GuiController.csproj | 2 +- src/Sample/LogAvatarParametars/LogAvatarParametars.csproj | 2 +- .../vrcosclib.OscUtilityInitialize.Test.csproj | 4 ++-- src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj b/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj index 156dbc1..0214168 100644 --- a/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj +++ b/src/Sample/AvatarParameterSender/AvatarParameterSender.csproj @@ -2,7 +2,7 @@ WinExe - net7.0-windows + net6.0-windows enable true ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/Sample/ChatboxSender/ChatboxSender.csproj b/src/Sample/ChatboxSender/ChatboxSender.csproj index a376e47..ab645ce 100644 --- a/src/Sample/ChatboxSender/ChatboxSender.csproj +++ b/src/Sample/ChatboxSender/ChatboxSender.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net6.0 enable enable ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/Sample/GuiController/GuiController.csproj b/src/Sample/GuiController/GuiController.csproj index 07b709b..7ba246b 100644 --- a/src/Sample/GuiController/GuiController.csproj +++ b/src/Sample/GuiController/GuiController.csproj @@ -2,7 +2,7 @@ WinExe - net7.0-windows + net6.0-windows enable true ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj b/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj index a376e47..ab645ce 100644 --- a/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj +++ b/src/Sample/LogAvatarParametars/LogAvatarParametars.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net6.0 enable enable ..\..\..\artifacts\Sample\$(MSBuildProjectName)\bin diff --git a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj index 082a87c..e8f9875 100644 --- a/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.OscUtilityInitialize.Test/vrcosclib.OscUtilityInitialize.Test.csproj @@ -1,8 +1,8 @@ - net6.0;net7.0;net461 - net6.0;net7.0 + net6.0;net461 + net6.0 enable BuildSoft.VRChat.Osc.Test 11.0 diff --git a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj index a86a092..9c1ffd9 100644 --- a/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj +++ b/src/VRCOscLib/Tests/vrcosclib.Test/vrcosclib.Test.csproj @@ -1,8 +1,8 @@  - net6.0;net7.0;net461 - net6.0;net7.0 + net6.0;net461 + net6.0 enable BuildSoft.VRChat.Osc.Test 11.0 From ec6def54479d48b56a15078f5b661d45538276f7 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Mon, 19 Dec 2022 20:02:19 +0900 Subject: [PATCH 11/14] Updated common parameters. --- src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs b/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs index a94ec45..62c1a1f 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs @@ -13,9 +13,6 @@ public static class OscAvatarUtility /// internal static readonly HashSet _commonParameters = new() { - "VRCFaceBlendV", - "VRCFaceBlendH", - "VRCEmote", "VelocityY", "VelocityX", "VelocityZ", @@ -25,6 +22,7 @@ public static class OscAvatarUtility "Upright", "AngularY", "Grounded", + "Earmuffs", "MuteSelf", "VRMode", "TrackingType", From 4f3e9014c840d7b8c73693529987e586b8b66c57 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Mon, 19 Dec 2022 20:23:22 +0900 Subject: [PATCH 12/14] Implemented `CommonParameterNames`. --- src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs b/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs index 62c1a1f..a210ed4 100644 --- a/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs +++ b/src/VRCOscLib/VRCOscLib/Avatar/Utility/OscAvatarUtility.cs @@ -48,6 +48,12 @@ internal static void RegisterAvaterConfig(OscAvatarConfig avatarConfig) public static IReadOnlyDictionary CommonParameters => _commonParameters.ToDictionary(s => s, GetCommonParameterValue); + /// + /// Enumerates common avatar parameters. + /// + public static IEnumerable CommonParameterNames + => _commonParameters.OrderBy(s => s); + /// /// Gets the current . /// From d6abad47421c866e868b78592fda3f0f523a1c41 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Tue, 20 Dec 2022 00:42:14 +0900 Subject: [PATCH 13/14] Updated a package --- src/VRCOscLib/VRCOscLib/vrcosclib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj index 46d2dc4..aef5b13 100644 --- a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj +++ b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj @@ -22,7 +22,7 @@ - + From fa914125184f5e69e720d75944feb08858df0915 Mon Sep 17 00:00:00 2001 From: ChanyaKushima <63221603+ChanyaVRC@users.noreply.github.com> Date: Tue, 20 Dec 2022 00:49:46 +0900 Subject: [PATCH 14/14] Release v1.4.3 --- src/VRCOscLib/VRCOscLib/vrcosclib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj index aef5b13..93caf28 100644 --- a/src/VRCOscLib/VRCOscLib/vrcosclib.csproj +++ b/src/VRCOscLib/VRCOscLib/vrcosclib.csproj @@ -13,7 +13,7 @@ ..\..\..\artifacts\xml\$(AssemblyName).xml VRCOscLib - 1.4.2 + 1.4.3 ChanyaKushima MIT A OSC library for VRChat