Skip to content

Commit

Permalink
initial commit (again)
Browse files Browse the repository at this point in the history
  • Loading branch information
nyakowint committed Sep 20, 2023
0 parents commit 9951bbe
Show file tree
Hide file tree
Showing 12 changed files with 863 additions and 0 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Build & Release

concurrency:
group: "build"
cancel-in-progress: true

on:
push:
branches:
- main
paths-ignore:
- '**.md'
- '**.js'
workflow_dispatch:
jobs:
build:
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Checkout XSO assemblies
uses: actions/checkout@v4
with:
repository: ${{ secrets.xsoRepo }}
token: ${{ secrets.repoToken }}
path: refs

- name: Setup .NET
uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: '7.0.x'

- name: Add Bepis NuGet & Restore dependencies
run: |
dotnet nuget add source https://nuget.bepinex.dev/v3/index.json
dotnet restore
- name: Build
run: dotnet build -c Release --no-restore

- name: Tag version
id: tag_version
uses: mathieudutour/github-tag-action@v6.1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Create Release
run: |
short_sha=${${{ github.sha }}:0:6}
gh release create ${{ steps.tag_version.outputs.new_tag }}-$short_sha ./builds/Release/net472/KeyboardOSC.dll --title "KeyboardOSC Build $short_sha" --prerelease --notes "${{ steps.tag_version.outputs.changelog }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63 changes: 63 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/.idea.XSOMod.iml
/contentModel.xml
/projectSettingsUpdater.xml

# Ignore Visual Studio temporary files, build results, and files generated by popular Visual Studio add-ons.
*.exe
*.dll
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.opensdf
*.unsuccessfulbuild
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/

# Ignore Visual Studio Code temporary files
.vscode/

# Ignore JetBrains Rider temporary files
.idea/


[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
[Ll]ibrary/

*.nupkg
packages/
!**/packages/build/
!**/packages/tools/
*.nuspec


NuGet.Config
nuget.config
nuget.targets

refs/
160 changes: 160 additions & 0 deletions KeyboardOSC/ChatModeManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using WindowsInput.Native;
using XSOverlay;

// ReSharper disable SwitchStatementMissingSomeEnumCasesNoDefault

namespace KeyboardOSC;

public static class ChatModeManager
{
private static bool _isSilentMsg;
private static string _currentText = "";
private static string _lastMsg = "";
private static DateTime _lastPingTime;
private static readonly ManualLogSource Logger = Plugin.PluginLogger;
private static TextMeshProUGUI _oscBarText;
private static List<KeyboardKey> _currentlyDownStickyKeys = new();

public static void HandleKey(KeyboardKey.VirtualKeyEventData eventData)
{
var scanCode = eventData.Sender.UsingRawVirtualKeyCode
? (uint) eventData.KeyCode[0]
: eventData.Sender.ScanCode[0];
var shiftedField = AccessTools.Field(typeof(KeyboardKey), "IsShifted");
var isShifted = (bool) shiftedField.GetValue(eventData.Sender);

foreach (var key in eventData.KeyCode)
{
var character = Tools.ConvertVirtualKeyToUnicode(key, scanCode, isShifted);
ProcessKey(key, eventData, character);
}
}

private static void ProcessKey(VirtualKeyCode key, KeyboardKey.VirtualKeyEventData data, string character)
{
var isCtrlHeld = _currentlyDownStickyKeys
.Any(k => k.Key[0] is VirtualKeyCode.LCONTROL or VirtualKeyCode.RCONTROL);
switch (key)
{
// backspace/delete keys
case VirtualKeyCode.BACK or VirtualKeyCode.DELETE:
{
if (_currentText.Length <= 0) return;
if (isCtrlHeld)
{
var lastSpaceIndex = _currentText.LastIndexOf(' ');
_currentText = lastSpaceIndex >= 0 ? _currentText.Substring(0, lastSpaceIndex) : "";
UpdateChatText(_currentText);
Logger.LogInfo("bulk deleting chat text: " + _currentText);
return;
}

_currentText = _currentText.Remove(key is VirtualKeyCode.DELETE ? 0 : _currentText.Length - 1);
UpdateChatText(_currentText);
Logger.LogInfo("deleting chat text: " + _currentText);
return;
}
// silent switch (no pop sound)
case VirtualKeyCode.TAB:
_isSilentMsg = !_isSilentMsg;
UpdateChatColor();
return;
// clear shortcut
case VirtualKeyCode.ESCAPE:
_currentText = "";
UpdateChatText(_currentText);
Logger.LogInfo("clearing chat text");
SendTyping(false);
return;
case VirtualKeyCode.END:
SendMessage("/chatbox/input", string.Empty, true, false);
return;
case VirtualKeyCode.INSERT:
_currentText = _lastMsg;
UpdateChatText(_currentText);
return;
// copy + paste
case VirtualKeyCode.VK_C:
if (!isCtrlHeld) return;
GUIUtility.systemCopyBuffer = _currentText;
return;
case VirtualKeyCode.VK_V:
if (!isCtrlHeld) return;
_currentText += GUIUtility.systemCopyBuffer;
UpdateChatText(_currentText);
return;
}


// send to vrchat
if (key is VirtualKeyCode.RETURN)
{
if (_currentText.Length <= 0) return;
Logger.LogInfo("sending chat text: " + _currentText);
_lastMsg = _currentText;
SendMessage("/chatbox/input", _currentText, true, _isSilentMsg);
UpdateChatText("");
_currentText = "";
_isSilentMsg = false;
Plugin.ReleaseStickyKeys.Invoke(Plugin.Instance.inputHandler, null);
SendTyping(false);
UpdateChatColor();
return;
}


if (string.IsNullOrEmpty(character)) return;
_currentText += character;
UpdateChatText(_currentText);
SendTyping(true);
Logger.LogInfo("updating chat text with " + _currentText);
}

public static void SendTyping(bool typing)
{
if (DateTime.Now - _lastPingTime < TimeSpan.FromSeconds(2) && typing) return;
_lastPingTime = DateTime.Now;
if (typing)
{
Tools.SendOsc("/chatbox/typing", "true");
return;
}

Tools.SendOsc("/chatbox/typing", "false");
}

private static void SendMessage(string address, string msg, bool now, bool sound)
{
Tools.SendOsc(address, msg, now, sound);
}

public static void Setup(TextMeshProUGUI obText)
{
_oscBarText = obText;
var stickyKeysField = AccessTools.Field(typeof(KeyboardInputHandler), "CurrentlyDownStickyKeys");
_currentlyDownStickyKeys = (List<KeyboardKey>) stickyKeysField.GetValue(Plugin.Instance.inputHandler);
}

private static void UpdateChatColor()
{
_oscBarText.color =
_isSilentMsg ? UIThemeHandler.Instance.T_WarningTone : UIThemeHandler.Instance.T_ConstrastingTone;
}

private static void UpdateChatText(string text)
{
if (text.Length > 250)
{
text = text.Substring(0, 250);
}

XSTools.SetTMPUIText(_oscBarText, text);
}
}
55 changes: 55 additions & 0 deletions KeyboardOSC/KeyboardOSC.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<AssemblyName>KeyboardOSC</AssemblyName>
<Description>Keyboard mod for XSOverlay</Description>
<Version>1.0.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<OutputPath>$(SolutionDir)\builds\$(Configuration)</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>Full</DebugType>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition=" '$(Configuration)' == 'Debug' ">
<Exec Command="taskkill /f /im XSOverlay.exe" IgnoreExitCode="true" IgnoreStandardErrorWarningFormat="true" ContinueOnError="true"/>
<Exec Command="sleep 0.5"/>
<Exec Command="move &quot;$(SolutionDir)builds\Debug\net472\$(ProjectName).dll&quot; &quot;C:\Program Files (x86)\Steam\steamapps\common\XSOverlay_Beta\BepInEx\plugins&quot;"/>
</Target>
<ItemGroup>
<PackageReference Include="BepInEx.Analyzers" Version="1.0.8" PrivateAssets="all" />
<PackageReference Include="BepInEx.Core" Version="5.4.21" />
<PackageReference Include="BepInEx.PluginInfoProps" Version="2.1.0" />
<PackageReference Include="UnityEngine.Modules" Version="2019.4.34" IncludeAssets="compile"/>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<Reference Include="Assembly-CSharp">
<HintPath>$(SolutionDir)refs\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="Unity.TextMeshPro">
<HintPath>$(SolutionDir)refs\Unity.TextMeshPro.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>$(SolutionDir)refs\UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.IMGUIModule">
<HintPath>$(SolutionDir)refs\UnityEngine.IMGUIModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>$(SolutionDir)refs\UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="uOSC.Runtime">
<HintPath>$(SolutionDir)refs\uOSC.Runtime.dll</HintPath>
</Reference>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="chat.png"/>
</ItemGroup>
</Project>
Loading

0 comments on commit 9951bbe

Please sign in to comment.