further cleanup of repo

This commit is contained in:
NotAKidoS 2025-04-03 03:03:24 -05:00
parent 4f8dcb0cd0
commit 323eb92f2e
140 changed files with 1 additions and 2430 deletions

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Mute SDraw's funny warning, because he only compilled for x64 while most people compile for both -->
<NoWarn>$(NoWarn);MSB3270</NoWarn>
</PropertyGroup>
<!-- Didn't put in the Directory.Build.props because it spams funny warnings... -->
<ItemGroup>
<Reference Include="ECM2">
<HintPath>..\.ManagedLibs\ECM2.dll</HintPath>
</Reference>
<Reference Include="ml_prm">
<HintPath>$(MsBuildThisFileDirectory)\..\.ManagedLibs\ml_prm.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ChatBox">
<HintPath>$(MsBuildThisFileDirectory)\..\.ManagedLibs\ChatBox.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
</Project>

View file

@ -0,0 +1,14 @@
using ABI_RC.Systems.InputManagement;
using HarmonyLib;
namespace NAK.ChatBoxExtensions.HarmonyPatches;
public class CVRInputManagerPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(CVRInputManager), nameof(CVRInputManager.Start))]
private static void Postfix_CVRInputManager_Start(ref CVRInputManager __instance)
{
__instance.AddInputModule(ChatBoxExtensions.InputModule);
}
}

View file

@ -0,0 +1,25 @@
using ABI_RC.Systems.InputManagement;
using UnityEngine;
namespace NAK.ChatBoxExtensions.InputModules;
internal class InputModuleChatBoxExtensions : CVRInputModule
{
public bool jump = false;
public float emote = -1;
public Vector2 lookVector = Vector2.zero;
public Vector3 movementVector = Vector3.zero;
public override void UpdateInput()
{
CVRInputManager.Instance.jump |= jump;
CVRInputManager.Instance.movementVector += movementVector;
CVRInputManager.Instance.lookVector += lookVector;
if (emote > 0) CVRInputManager.Instance.emote = emote;
jump = false;
emote = -1;
lookVector = Vector3.zero;
movementVector = Vector3.zero;
}
}

View file

@ -0,0 +1,56 @@
using ABI_RC.Core.Networking;
using ABI_RC.Core.Player;
namespace NAK.ChatBoxExtensions.Integrations;
public class CommandBase
{
internal static bool IsCommandForAll(string argument)
{
if (String.IsNullOrWhiteSpace(argument)) return false;
return argument == "*" || argument.StartsWith("@a") || argument.StartsWith("@e");
}
internal static bool IsCommandForLocalPlayer(string argument)
{
if (String.IsNullOrWhiteSpace(argument)) return false;
if (argument.Contains("*"))
{
string partialName = argument.Replace("*", "").Trim();
if (String.IsNullOrWhiteSpace(partialName)) return false;
return AuthManager.Username.Contains(partialName);
}
return AuthManager.Username == argument;
}
internal static void LocalCommandIgnoreOthers(string argument, Action<string[]> callback)
{
string[] args = argument.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
// will fail if arguments are specified which arent local player
if (args.Length == 0 || IsCommandForAll(args[0]) || IsCommandForLocalPlayer(args[0])) callback(args);
}
//remote must specify exact player, wont respawn to all
internal static void RemoteCommandListenForSelf(string argument, Action<string[]> callback)
{
string[] args = argument.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
if (args.Length == 0) return;
if (IsCommandForLocalPlayer(args[0])) callback(args);
}
// remote must specify player or all, ignore commands without arguments
internal static void RemoteCommandListenForAll(string argument, Action<string[]> callback)
{
string[] args = argument.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
if (args.Length == 0) return;
if (IsCommandForAll(args[0]) || IsCommandForLocalPlayer(args[0])) callback(args);
}
internal static string GetPlayerUsername(string guid)
{
return CVRPlayerManager.Instance.TryGetPlayerName(guid);
}
}

View file

@ -0,0 +1,91 @@
using Kafe.ChatBox;
namespace NAK.ChatBoxExtensions.Integrations;
internal class ChatBoxCommands : CommandBase
{
public static void RegisterCommands()
{
bool awaitingPing = false;
DateTime pingTime = DateTime.MinValue; // store the time when "ping" command was sent
Commands.RegisterCommand("ping",
onCommandSent: (message, sound, displayMsg) =>
{
pingTime = DateTime.Now;
awaitingPing = true;
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForSelf(message, args =>
{
API.SendMessage("/pong " + GetPlayerUsername(sender), false, true, true);
});
});
Commands.RegisterCommand("pong",
onCommandSent: null,
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForSelf(message, args =>
{
if (awaitingPing)
{
awaitingPing = false;
TimeSpan timeSincePing = DateTime.Now - pingTime; // calculate the time difference
API.SendMessage($"Time since ping: {timeSincePing.TotalMilliseconds}ms", false, true, true);
return;
}
API.SendMessage($"You have to ping first, {GetPlayerUsername(sender)}!", false, true, true);
});
});
Commands.RegisterCommand("sudo",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 1)
{
string command = string.Join(" ", args.Skip(1));
API.SendMessage($"/{command}", false, true, true);
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (args.Length > 1)
{
string command = string.Join(" ", args.Skip(1));
API.SendMessage($"/{command}", false, true, true);
}
});
});
Commands.RegisterCommand("say",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 0)
{
string text = string.Join(" ", args);
API.SendMessage(text, false, true, true);
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (args.Length > 0)
{
string text = string.Join(" ", args);
API.SendMessage(text, false, true, true);
}
});
});
}
}

View file

@ -0,0 +1,32 @@
using ABI_RC.Core.Player;
namespace NAK.ChatBoxExtensions.Integrations;
internal class ChilloutVRAASCommands : CommandBase
{
public static void RegisterCommands()
{
// /aas [target player] [name] [value]
Commands.RegisterCommand("aas",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 2 && float.TryParse(args[2], out float value))
{
PlayerSetup.Instance.ChangeAnimatorParam(args[1], value);
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (args.Length > 2 && float.TryParse(args[2], out float value))
{
PlayerSetup.Instance.ChangeAnimatorParam(args[1], value);
}
});
});
}
}

View file

@ -0,0 +1,118 @@
using ABI_RC.Core;
using ABI_RC.Core.Base;
using ABI_RC.Core.Player;
using ABI_RC.Systems.Movement;
using UnityEngine;
namespace NAK.ChatBoxExtensions.Integrations;
internal class ChilloutVRBaseCommands : CommandBase
{
public static void RegisterCommands()
{
Commands.RegisterCommand("respawn",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
RootLogic.Instance.Respawn();
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, (args) =>
{
RootLogic.Instance.Respawn();
});
});
Commands.RegisterCommand("mute",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
AudioManagement.SetMicrophoneActive(false);
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
AudioManagement.SetMicrophoneActive(false);
});
});
// teleport [x] [y] [z]
Commands.RegisterCommand("teleport",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 2 && float.TryParse(args[0], out float x) && float.TryParse(args[1], out float y) && float.TryParse(args[2], out float z))
{
BetterBetterCharacterController.Instance.TeleportPlayerTo(new Vector3(x, y, z), false, false);
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (args.Length > 2 && float.TryParse(args[0], out float x) && float.TryParse(args[1], out float y) && float.TryParse(args[2], out float z))
{
BetterBetterCharacterController.Instance.TeleportPlayerTo(new Vector3(x, y, z), false, false);
}
});
});
// tp [x] [y] [z]
Commands.RegisterCommand("tp",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 2 && float.TryParse(args[0], out float x) && float.TryParse(args[1], out float y) && float.TryParse(args[2], out float z))
{
BetterBetterCharacterController.Instance.TeleportPlayerTo(new Vector3(x, y, z), false, false);
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (args.Length > 2 && float.TryParse(args[0], out float x) && float.TryParse(args[1], out float y) && float.TryParse(args[2], out float z))
{
BetterBetterCharacterController.Instance.TeleportPlayerTo(new Vector3(x, y, z), false, false);
}
});
});
// teleport [player]
Commands.RegisterCommand("teleport",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 0)
{
string player = args[0];
CVRPlayerEntity playerEnt = CVRPlayerManager.Instance.NetworkPlayers.FirstOrDefault(x => x.Username == player);
if (playerEnt != null) BetterBetterCharacterController.Instance.TeleportPlayerTo(playerEnt.PuppetMaster.transform.position, false, false);
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (args.Length > 0)
{
string player = args[0];
CVRPlayerEntity playerEnt = CVRPlayerManager.Instance.NetworkPlayers.FirstOrDefault(x => x.Username == player);
if (playerEnt != null) BetterBetterCharacterController.Instance.TeleportPlayerTo(playerEnt.PuppetMaster.transform.position, false, false);
}
});
});
}
}

View file

@ -0,0 +1,53 @@
namespace NAK.ChatBoxExtensions.Integrations;
internal class ChilloutVRInputCommands : CommandBase
{
public static void RegisterCommands()
{
Commands.RegisterCommand("emote",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 0 && int.TryParse(args[0], out int emote))
{
ChatBoxExtensions.InputModule.emote = (float)emote;
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (args.Length > 1 && int.TryParse(args[1], out int emote))
{
ChatBoxExtensions.InputModule.emote = (float)emote;
}
});
});
Commands.RegisterCommand("jump",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, args =>
{
if (args.Length > 0 && bool.TryParse(args[0], out bool jump))
{
ChatBoxExtensions.InputModule.jump = jump;
return;
}
ChatBoxExtensions.InputModule.jump = true;
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, args =>
{
if (bool.TryParse(args[0], out bool jump))
{
ChatBoxExtensions.InputModule.jump = jump;
}
});
});
}
}

View file

@ -0,0 +1,54 @@
namespace NAK.ChatBoxExtensions.Integrations;
public static class Commands
{
private const string Character = "/";
private static readonly List<Command> CommandList = new();
internal static void InitializeCommandHandlers()
{
Kafe.ChatBox.API.OnMessageSent += msg => HandleSentCommand(msg.Message, msg.TriggerNotification, msg.DisplayOnChatBox);
Kafe.ChatBox.API.OnMessageReceived += msg => HandleReceivedCommand(msg.SenderGuid, msg.Message, msg.TriggerNotification, msg.DisplayOnChatBox);
}
internal static void RegisterCommand(string prefix, Action<string, bool, bool> onCommandSent = null, Action<string, string, bool, bool> onCommandReceived = null)
{
var cmd = new Command { Prefix = prefix, OnCommandSent = onCommandSent, OnCommandReceived = onCommandReceived };
CommandList.Add(cmd);
}
internal static void UnregisterCommand(string prefix)
{
CommandList.RemoveAll(cmd => cmd.Prefix == prefix);
}
private class Command
{
internal string Prefix;
// Command Sent (message)
internal Action<string, bool, bool> OnCommandSent;
// Command Sent (sender guid, message)
internal Action<string, string, bool, bool> OnCommandReceived;
}
private static void HandleSentCommand(string message, bool notification, bool displayMsg)
{
if (!message.StartsWith(Character)) return;
foreach (var command in CommandList.Where(command => message.StartsWith(Character + command.Prefix)))
{
command.OnCommandSent?.Invoke(message, notification, displayMsg);
}
}
private static void HandleReceivedCommand(string sender, string message, bool notification, bool displayMsg)
{
if (!message.StartsWith(Character)) return;
foreach (var command in CommandList.Where(command => message.StartsWith(Character + command.Prefix)))
{
command.OnCommandReceived?.Invoke(sender, message, notification, displayMsg);
}
}
}

View file

@ -0,0 +1,89 @@
using ml_prm;
namespace NAK.ChatBoxExtensions.Integrations;
internal class PlayerRagdollModCommands : CommandBase
{
public static void RegisterCommands()
{
Commands.RegisterCommand("unragdoll",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, (args) =>
{
if (RagdollController.Instance.IsRagdolled())
{
RagdollController.Instance.SwitchRagdoll();
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, (args) =>
{
if (RagdollController.Instance.IsRagdolled())
{
RagdollController.Instance.SwitchRagdoll();
}
});
});
Commands.RegisterCommand("ragdoll",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, (args) =>
{
bool switchRagdoll = true;
if (args.Length > 0 && bool.TryParse(args[0], out bool state))
{
switchRagdoll = state != RagdollController.Instance.IsRagdolled();
}
if (switchRagdoll)
{
RagdollController.Instance.SwitchRagdoll();
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, (args) =>
{
bool switchRagdoll = true;
if (args.Length > 1 && bool.TryParse(args[1], out bool state))
{
switchRagdoll = state != RagdollController.Instance.IsRagdolled();
}
if (switchRagdoll)
{
RagdollController.Instance.SwitchRagdoll();
}
});
});
Commands.RegisterCommand("kill",
onCommandSent: (message, sound, displayMsg) =>
{
LocalCommandIgnoreOthers(message, (args) =>
{
if (!RagdollController.Instance.IsRagdolled())
{
RagdollController.Instance.SwitchRagdoll();
}
});
},
onCommandReceived: (sender, message, sound, displayMsg) =>
{
RemoteCommandListenForAll(message, (args) =>
{
if (!RagdollController.Instance.IsRagdolled())
{
RagdollController.Instance.SwitchRagdoll();
}
});
});
}
}

View file

@ -0,0 +1,54 @@
using MelonLoader;
using NAK.ChatBoxExtensions.InputModules;
namespace NAK.ChatBoxExtensions;
public class ChatBoxExtensions : MelonMod
{
internal static MelonLogger.Instance Logger;
internal static InputModuleChatBoxExtensions InputModule = new();
public override void OnInitializeMelon()
{
Logger = LoggerInstance;
if (RegisteredMelons.All(it => it.Info.Name != "ChatBox"))
{
Logger.Error("ChatBox was not found!");
return;
}
ApplyIntegrations();
}
private void ApplyIntegrations()
{
Integrations.Commands.InitializeCommandHandlers();
Integrations.ChatBoxCommands.RegisterCommands();
Integrations.ChilloutVRBaseCommands.RegisterCommands();
Integrations.ChilloutVRAASCommands.RegisterCommands();
Integrations.ChilloutVRInputCommands.RegisterCommands();
ApplyPatches(typeof(HarmonyPatches.CVRInputManagerPatches));
if (RegisteredMelons.Any(it => it.Info.Name == "PlayerRagdollMod"))
{
Integrations.PlayerRagdollModCommands.RegisterCommands();
}
}
private void ApplyPatches(Type type)
{
try
{
HarmonyInstance.PatchAll(type);
}
catch (Exception e)
{
Logger.Msg($"Failed while patching {type.Name}!");
Logger.Error(e);
}
}
}

View file

@ -0,0 +1,33 @@
using ChatBoxExtensions.Properties;
using MelonLoader;
using System.Reflection;
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyTitle(nameof(NAK.ChatBoxExtensions))]
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
[assembly: AssemblyProduct(nameof(NAK.ChatBoxExtensions))]
[assembly: MelonInfo(
typeof(NAK.ChatBoxExtensions.ChatBoxExtensions),
nameof(NAK.ChatBoxExtensions),
AssemblyInfoParams.Version,
AssemblyInfoParams.Author,
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/ChatBoxExtensions"
)]
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
[assembly: MelonAdditionalDependencies("ChatBox")]
[assembly: MelonOptionalDependencies("PlayerRagdollMod")]
[assembly: HarmonyDontPatchAll]
namespace ChatBoxExtensions.Properties;
internal static class AssemblyInfoParams
{
public const string Version = "1.0.3";
public const string Author = "NotAKidoS";
}

View file

@ -0,0 +1,23 @@
{
"_id": 129,
"name": "ChatBoxExtensions",
"modversion": "1.0.1",
"gameversion": "2022r170p1",
"loaderversion": "0.6.1",
"modtype": "Mod",
"author": "NotAKidoS",
"description": "Prevents VRIK from using toe bones in VR & optionaly FBT.\n\nVRIK calculates weird center of mass when toes are mapped, so it is sometimes desired to unmap toes to prevent an avatars feet from resting far back.\n\nPlease see the README for relevant imagery detailing the problem.",
"searchtags": [
"toes",
"vrik",
"ik",
"feet"
],
"requirements": [
"None"
],
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r3/ChatBoxExtensions.dll",
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/ChatBoxExtensions/",
"changelog": "",
"embedcolor": "#ffc700"
}