Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rurre committed Aug 25, 2022
0 parents commit d7abe57
Show file tree
Hide file tree
Showing 7 changed files with 325 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/.idea/
/Temp/
/.run/
/OSCLeashNet/bin/
/OSCLeashNet/obj/
16 changes: 16 additions & 0 deletions OSCLeashNet.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSCLeashNet", "OSCLeashNet\OSCLeashNet.csproj", "{B517BDB6-FEE9-4CAB-A94D-0544DBA441C3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B517BDB6-FEE9-4CAB-A94D-0544DBA441C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B517BDB6-FEE9-4CAB-A94D-0544DBA441C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B517BDB6-FEE9-4CAB-A94D-0544DBA441C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B517BDB6-FEE9-4CAB-A94D-0544DBA441C3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
55 changes: 55 additions & 0 deletions OSCLeashNet/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Encodings.Web;
using System.Text.Json;

namespace OSCLeashNet
{
[Serializable]
public class Config
{
static readonly string ConfigPath = $"{AppContext.BaseDirectory}config.json";
public static Config Instance { get; } = LoadConfig();

public string Ip { get; set; } = "127.0.0.1";

public int ListeningPort { get; set; } = 9001;
public int SendingPort { get; set; } = 9000;
public float RunDeadzone { get; set; } = 0.70f;
public float WalkDeadzone { get; set; } = 0.15f;
public float ActiveDelay { get; set; } = 0.1f;
public float InactiveDelay { get; set; } = 0.15f;
public float InputSendDelay { get; set; } = 0.1f;
public bool Logging { get; set; }

public Dictionary<string, string> Parameters { get; set; } = new Dictionary<string, string>()
{
{ "Z_Positive", "Leash_Z+" },
{ "Z_Negative", "Leash_Z-" },
{ "X_Positive", "Leash_X+" },
{ "X_Negative", "Leash_X-" },
{ "PhysboneParameter", "Leash" },
};

static Config LoadConfig()
{
var options = new JsonSerializerOptions() { WriteIndented = true, AllowTrailingCommas = true };
Config? cfg = File.Exists(ConfigPath) ? JsonSerializer.Deserialize<Config>(File.ReadAllText(ConfigPath), options) : null;
if(cfg == null)
{
cfg = new Config();
cfg.SaveConfig();
}

return cfg;
}

void SaveConfig()
{
var options = new JsonSerializerOptions() { WriteIndented = true, AllowTrailingCommas = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
string json = JsonSerializer.Serialize(this, options);
File.WriteAllText(ConfigPath, json);
}
}
}
19 changes: 19 additions & 0 deletions OSCLeashNet/LeashParameters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace OSCLeashNet
{
public class LeashParameters
{
public bool WasGrabbed = false;
public bool Grabbed = false;
public float Stretch = 0;
public float ZPositive = 0;
public float ZNegative = 0;
public float XPositive = 0;
public float XNegative = 0;

public override string ToString()
{
return
$"Grabbed - {Grabbed} was {WasGrabbed} | Stretch - {Stretch} | ({ZPositive - ZNegative}, {XPositive - XNegative})";
}
}
}
15 changes: 15 additions & 0 deletions OSCLeashNet/OSCLeashNet.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
<ApplicationIcon>VRChatOSCLeash.ico</ApplicationIcon>
<Company>Pumkin</Company>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BuildSoft.OscCore" Version="1.0.5" />
</ItemGroup>

</Project>
215 changes: 215 additions & 0 deletions OSCLeashNet/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
using System;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using BuildSoft.OscCore;

namespace OSCLeashNet
{
public static class Program
{
const string ParamPrefix = "/avatar/parameters/";
const string InputPrefix = "/input/";

static readonly string ZPosAddress = $"{ParamPrefix}{Config.Instance.Parameters["Z_Positive"]}";
static readonly string ZNegAddress = $"{ParamPrefix}{Config.Instance.Parameters["Z_Negative"]}";
static readonly string XPosAddress = $"{ParamPrefix}{Config.Instance.Parameters["X_Positive"]}";
static readonly string XNegAddress = $"{ParamPrefix}{Config.Instance.Parameters["X_Negative"]}";
static readonly string GrabAddress = $"{ParamPrefix}{Config.Instance.Parameters["PhysboneParameter"]}_IsGrabbed";
static readonly string StretchAddress = $"{ParamPrefix}{Config.Instance.Parameters["PhysboneParameter"]}_Stretch";

static readonly object LockObj = new object();
static readonly LeashParameters Leash = new LeashParameters();

static readonly float RunDeadzone = Config.Instance.RunDeadzone;
static readonly float WalkDeadzone = Config.Instance.WalkDeadzone;
static readonly TimeSpan InactiveDelay = TimeSpan.FromSeconds(Config.Instance.InputSendDelay);
static readonly bool Logging = Config.Instance.Logging;

static OscClient Client;
static OscServer Server;

public static async Task Main()
{
Console.Title = "OSCLeashNet";
Console.WriteLine("\x1b OSCLeash is Running! \x1b");
Console.WriteLine(Config.Instance.Ip == IPAddress.Loopback.ToString() ? "IP: Localhost" : $"IP: {Config.Instance.Ip} | Not Localhost? Wack.");
Console.WriteLine("Listening on port: " + Config.Instance.ListeningPort);
Console.WriteLine("Sending to port: " + Config.Instance.SendingPort);
Console.WriteLine($"Run deadzone {MathF.Round(Config.Instance.RunDeadzone * 100, 3)}% of stretch");
Console.WriteLine($"Walking deadzone {MathF.Round(Config.Instance.WalkDeadzone * 100, 3)}% of stretch");
Console.WriteLine($"Delays of {Config.Instance.ActiveDelay * 1000}ms & {Config.Instance.InactiveDelay * 1000}ms");

Client = new OscClient(Config.Instance.Ip, Config.Instance.SendingPort);

StartServer();
await Task.Run(async () =>
{
LeashOutput(0f, 0f, 0f);
TimeSpan delay = TimeSpan.FromSeconds(Config.Instance.ActiveDelay);
while(true)
{
LeashRun();
await Task.Delay(delay);
}
});
}

static void StartServer()
{
if(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners().Any(x => x.Port == Config.Instance.ListeningPort))
{
Console.WriteLine("\x1b \x1b");
Console.WriteLine($"\x1b Warning: An application is already running on port {Config.Instance.ListeningPort}! \x1b");
Console.WriteLine("\x1b \x1b");
Console.WriteLine("Press any key to Exit.");

Console.ReadKey(true);
Environment.Exit(0);
}

Server = new OscServer(Config.Instance.ListeningPort);

Server.TryAddMethod(ZPosAddress, OnReceiveZPos);
Server.TryAddMethod(ZNegAddress, OnReceiveZNeg);
Server.TryAddMethod(XPosAddress, OnReceiveXPos);
Server.TryAddMethod(XNegAddress, OnReceiveXNeg);
Server.TryAddMethod(GrabAddress, OnReceiveGrab);
Server.TryAddMethod(StretchAddress, OnReceiveStretch);

Server.Start();
}

static void LeashRun()
{
bool leashGrabbed, leashReleased;
float verticalOutput, horizontalOutput;

lock(LockObj)
{
verticalOutput = (Leash.ZPositive - Leash.ZNegative) * Leash.Stretch;
horizontalOutput = (Leash.XPositive - Leash.XNegative) * Leash.Stretch;

leashGrabbed = Leash.Grabbed;

if(leashGrabbed)
Leash.WasGrabbed = true;

leashReleased = Leash.Grabbed != Leash.WasGrabbed;

if(leashReleased)
Leash.WasGrabbed = false;
}

if(leashGrabbed)
{
if(Leash.Stretch > RunDeadzone)
LeashOutput(verticalOutput, horizontalOutput, 1f);
else if(Leash.Stretch > WalkDeadzone)
LeashOutput(verticalOutput, horizontalOutput, 0f);
else
LeashOutput(0f, 0f, 0f);
}
else if(leashReleased)
{
LeashOutput(0f, 0f, 0f);
Thread.Sleep(InactiveDelay);
LeashOutput(0f, 0f, 0f);
}
else
{
Thread.Sleep(InactiveDelay);
}
}

static void LeashOutput(float vertical, float horizontal, float run)
{
Client.Send($"{InputPrefix}Vertical", vertical);
Client.Send($"{InputPrefix}Horizontal", horizontal);
Client.Send($"{InputPrefix}Run", run);

if(Logging)
Console.WriteLine($"Sending: Vertical - {MathF.Round(vertical, 2)} | Horizontal = {MathF.Round(horizontal, 2)} | Run - {run}");
}

static void OnReceiveZPos(OscMessageValues msg)
{
try
{
lock(LockObj)
Leash.ZPositive = msg.ReadFloatElement(0);
}
catch(Exception ex)
{
Console.WriteLine($"Exception occured when trying to read float value on address {ZPosAddress}:\n{ex.Message}");
}
}

static void OnReceiveZNeg(OscMessageValues msg)
{
try
{
lock(LockObj)
Leash.ZNegative = msg.ReadFloatElement(0);
}
catch(Exception ex)
{
Console.WriteLine($"Exception occured when trying to read float value on address {ZNegAddress}:\n{ex.Message}");
}
}

static void OnReceiveXPos(OscMessageValues msg)
{
try
{
lock(LockObj)
Leash.XPositive = msg.ReadFloatElement(0);
}
catch(Exception ex)
{
Console.WriteLine($"Exception occured when trying to read float value on address {XPosAddress}:\n{ex.Message}");
}
}

static void OnReceiveXNeg(OscMessageValues msg)
{
try
{
lock(LockObj)
Leash.XNegative = msg.ReadFloatElement(0);
}
catch(Exception ex)
{
Console.WriteLine($"Exception occured when trying to read float value on address {XNegAddress}:\n{ex.Message}");
}
}

static void OnReceiveStretch(OscMessageValues msg)
{
try
{
lock(LockObj)
Leash.Stretch = msg.ReadFloatElement(0);
}
catch(Exception ex)
{
Console.WriteLine($"Exception occured when trying to read float value on address {StretchAddress}:\n{ex.Message}");
}
}

static void OnReceiveGrab(OscMessageValues msg)
{
try
{
lock(LockObj)
Leash.Grabbed = msg.ReadBooleanElement(0);
}
catch(Exception ex)
{
Console.WriteLine($"Exception occured when trying to read float value on address {GrabAddress}:\n{ex.Message}");
}
}
}
}
Binary file added OSCLeashNet/VRChatOSCLeash.ico
Binary file not shown.

0 comments on commit d7abe57

Please sign in to comment.