Code Monkey home page Code Monkey logo

vts-sharp's People

Contributors

fomtarro avatar hugovg avatar millyarde avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vts-sharp's Issues

BUG: Newtonsoft Serializer sending optional values

The old Unity serializer had special logic to prevent it from sending certain optional values. For example, in VTSParameterInjectionValue, the weight field is optional. In the data model, we initialize it as NaN. This stopped it from being included on the serialized model at all in the old way. It seems the new serializer is being overzealous.

Go through the model files and find the various sentinel values we use to try to exclude values from the payload, then update the Newtonsoft serializer to accommodate.

[Enhancement] Maintainability Ideas

  • Enums for MessageType, Add Enum Extension Methods

We can use Extension Methods to get a [Description] tag off of an Enum. This adds a little overhead, since we have to get the string at runtime as opposed to just reading the string.

Example:

using System.ComponentModel;

namespace VTS
{
    public static class EnumExtensions
    {
        public static string GetDescription<T>(this T value)
        {
            var fi = value.GetType().GetField(value.ToString());
            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

            return attributes.Length > 0 ? attributes[0].Description : null;
        }
    }
}

Pros:
Less typos, easier to develop/maintain.

Cons:
Less performant. Not sure if that is an issue, since it is all (usually) running on a local network.

  • Remove Serializable, adding Newtonsoft
    Newtonsoft makes it so we don't need to mark every class in VTSData as [Serializable]. This is marking a class being Binary Serializable in C# and is generally frowned upon for various reasons, especially since we just need to serialize it for JSON data.

Pros:
Not using [Serializable].

Cons:
Adding a library (Newtonsoft) to the project.

  • Rework Data, remove Data from subclasses, merge onto VTSMessageData
    I was thinking we could just use Inheritance and Generics here to not create a new Data on every class. Here is an example of how VTSMessageData and ErrorData could look
public class DTO {}
    public class VTSMessageData<T> where T : DTO
    {
        public string APIName = "VTubeStudioPublicAPI";
        public long Timestamp;
        public string APIVersion = "1.0";
        public string RequestID = Guid.NewGuid().ToString();
        public string MessageType;
        public T Data;

        public VTSMessageData(MessageTypeEnum e)
        {
            MessageType = e.GetDescription();
        }

        public VTSMessageData(MessageTypeEnum e, T d)
        {
            MessageType = e.GetDescription();
            Data = d;
        }
    }

    public class VTSErrorData : VTSMessageData<ErrorData>
    {
        public VTSErrorData() : base(MessageTypeEnum.APIError) { }
        public VTSErrorData(string e) : base(MessageTypeEnum.APIError, new ErrorData(e)) { }

        public class ErrorData : DTO
        {
            public ErrorData() { }
            public ErrorData(string message) { Message = message; }

            public ErrorID ErrorID;
            public string Message;
        }
    }

Pros:
Code is a bit easier to work with and expand upon.

Cons:
Maybe a little less understandable at a glance?
Currently need to use Static Usings, IE: using static VTS.VTSArtMeshListRequestData; to access the 'Data' types, which will clutter usings in some files.
I'll try to think of a better way to handle this though.

  • Remove 'This', general code/linting cleanup
    There are lots of small linting things that bug me a bit, like unnecessary this., variable name casing, null coalescing, null propagation, and other VERY MINOR things. This isn't so much a problem, but thought I'd bring it up and see what your thoughts on it were. I could make these changes in a pull request, but wanted to see if this was overstepping my bounds a little.

Example:
This:

			if(this._ws != null){
				this._ws.Update(timeDelta);
			}

Becomes:
_ws?.Update(timeDelta);

Pros:
My Brain will process this better?

Cons:
Your/Other People's Brains may not?

  • Use Reflection in ProcessResponses
    We can make use of Reflection in C# to remove the switch statements in ProcessResponses, allowing for not having to manually update this whenever we add a new type. This example also uses (dynamic), which I would like to refactor out, since this also adds some extra overhead along with the use of Reflection. I just haven't thought of a better way of doing this yet.

Example:

        private void ProcessResponses()
        {
            while (_ws?.GetNextResponse() is string data)
            {
                var response = JsonConvert.DeserializeObject<VTSMessageData<DTO>>(data);
                Type responseType = Type.GetType("VTS" + response.MessageType + "Data");
                var responseData = JsonConvert.DeserializeObject(data, responseType);

                try
                {
                    if (_events.ContainsKey(response.MessageType))
                    {
                        _events[response.MessageType].OnEvent((dynamic)responseData);
                    }
                    else if (_callbacks.ContainsKey(response.RequestID))
                    {
                        if (response.MessageType == "APIError")
                        {
                            _callbacks[response.RequestID].OnError((dynamic)responseData);
                        }
                        else
                        {
                            _callbacks[response.RequestID].OnSuccess((dynamic)responseData);
                        }

                        _callbacks.Remove(response.RequestID);
                    }
                }
                catch (Exception e)
                {
                    VTSErrorData error = new VTSErrorData(e.Message)
                    {
                        RequestID = response.RequestID
                    };

                    _events[response.MessageType].OnError(error);
                }
            }
        }

Pros:
Easier to maintain.

Cons:
Uses more computation.

Please let me know if any of these possible enhancements interest you! I'll make some pull requests with these features separately. I already have some of this work done in one, gross, big, commit I was working on as a test over at Millyarde@e3851fb. I'll probably wait until version 2 is in main to make these changes, if that isn't too far off!

Websocket aborts unexpectedly after an hour+

I have received a report that the socket gets rejected by the server after an hour (or much more) of connectivity. I suspect in this case, we need to put the attempted request back in the stack,

I unfortunately cannot reliably reproduce these conditions. But I will keep trying.

Incorrect doc link for GetParameterValue

The GetParameterValue call's inline doc says
For more info, see /// <a href="https://github.com/DenchiSoft/VTubeStudio#requesting-list-of-available-tracking-parameters">https://github.com/DenchiSoft/VTubeStudio#requesting-list-of-available-tracking-parameters</a>

However, that's the link for GetInputParameterList. The link for GetParameterValue should probably be this:
https://github.com/DenchiSoft/VTubeStudio#get-the-value-for-one-specific-parameter-default-or-custom

Nuget package ?

I feel like it would be easier to use the library by making a nuget package, this way it could directly be automatically downloaded and setup during build

The WebSocket Sharp version might mistakenly be an old prerelease version

I was trying to develop something using VTS-Sharp and WebSocket Sharp. Initially, I was having problems with WebSocket Sharp classes that couldn't be found and I'd thought that maybe you'd stripped out all the stuff you didn't need from WebSocket Sharp.
So I installed WebSocket Sharp myself, from https://www.nuget.org/packages/WebSocketSharp with the NuGet command line since I didn't really want to install and try and figure out MonoDevelop just to build it from source. Unfortunately, the most recent version on NuGet is pretty old anyway, from back in July 2016, but it seemed to have the classes that I thought were missing (version 1.0.3-rc11 appears to be up to and including this commit sta/websocket-sharp@c044fdc).

Installing version 1.0.3-rc11 with NuGet and replacing the existing websocket-sharp.dll in my Unity project with that version gave a bunch of errors with the VTS-Sharp code.
I noticed in particular that WebSocketSharpImpl.cs was trying to use WebSocketState.CONNECTING, but that was changed to PascalCase in March 2014: sta/websocket-sharp@d632fc8 leading me to guess that you're using a prerelease version older than that.

It could be that the newer versions have some issues that I don't know about or that you have other reasons for using the chosen version of WebSocket Sharp, but I thought it was a bit odd so thought it was worth pointing out.

The old version isn't stopping me from developing or anything since I can look back at all the old code on github and so far it's mostly just changed class names that I've been running into, so feel free to close this issue.

BUG: ItemPinRequestInvalidAngleOrSizeType

ErrorID - ItemPinRequestInvalidAngleOrSizeType

it doesn't matter which combination of VTSItemAngleRelativityMode and VTSItemSizeRelativityMode, size or angle it'll always return this error when dynamically pinning objects.

any way you got this working?
code:

 // Load the item
        var item = await plugin.VTSPlugin.LoadItem(prop.fileName, new VTSCustomDataItemLoadOptions()
        {
            positionX = 0,
            positionY = 0,
        });
        
        //get Item info
        var itemInstanceId = item.data.instanceID;
        // Get Current Model Info
        var model = await plugin.VTSPlugin.GetCurrentModel();
        
        // Get a list of artmeshes
        var artMeshes = await plugin.VTSPlugin.GetArtMeshList();
        
        // Get the first artmesh
        var artMesh = artMeshes.data.artMeshNames.FirstOrDefault();

        // Model Id and ArtMesh Id left empty for random
        await plugin.VTSPlugin.PinItemToRandom(itemInstanceId, "", "", 1,
            VTSItemAngleRelativityMode.RelativeToPinPosition, 
1, 
VTSItemSizeRelativityMode.RelativeToCurrentItemSize);  // Lots of expermentation 

Implement a way to load auth tokens

Currently, the plugin will attempt to get a new auth token on every run, which works, but is annoying. It would probably be preferential to have a mechanism in place for being able to provide a prior token into the Initialize method.

Discovery port detection in VTSWebSocket not configured for shared port ownership

In VTSWebSocket in the function StartUDP() at line 70, the udp client is being initialized with:

UDP_CLIENT = new UdpClient(47779);

Like this it will take full ownership of the port. To allow sharing of the port it must instead be created with something like:

IPEndPoint LOCAL_PT = new IPEndPoint(IPAddress.Any, 47779);
UDP_CLIENT = new UdpClient();
UDP_CLIENT.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
UDP_CLIENT.Client.Bind(LOCAL_PT);

this sets the socket options to allow reuse

Feature: Documentation

It can be quite hard to find the right function that you want at the moment, I thought maybe a documentation Website(gh-pages) or github wiki could be made. I don't know which one you prefer, I can probably help out with that!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.