first commit
This commit is contained in:
commit
aa44d3ad70
1585 changed files with 277994 additions and 0 deletions
141
Assets/Plugins/CodeAssist/Editor/Input/Binary2TextExec.cs
Normal file
141
Assets/Plugins/CodeAssist/Editor/Input/Binary2TextExec.cs
Normal file
|
@ -0,0 +1,141 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
#nullable enable
|
||||
|
||||
|
||||
//namespace UTJ.UnityCommandLineTools
|
||||
namespace Meryel.UnityCodeAssist.Editor.Input
|
||||
{
|
||||
// <summary>
|
||||
// bin2textをUnityEditorから実行する為のClass
|
||||
// programed by Katsumasa.Kimura
|
||||
// </summary>
|
||||
public class Binary2TextExec : EditorToolExec
|
||||
{
|
||||
public Binary2TextExec() : base("binary2text") { }
|
||||
|
||||
// <summary>
|
||||
// bin2text filePath outPath options
|
||||
// /summary>
|
||||
public int Exec(string filePath, string outPath, string options)
|
||||
{
|
||||
var args = string.Format(@"""{0}"" ""{1}"" {2}", filePath, outPath, options);
|
||||
return Exec(args);
|
||||
}
|
||||
|
||||
public int Exec(string filePath, string outPath, bool detailed = false, bool largeBinaryHashOnly = false, bool hexFloat = false)
|
||||
{
|
||||
//var args = string.Format(@"""{0}"" ""{1}"" {2}", filePath, outPath, options);
|
||||
var args = string.Format(@"""{0}"" ""{1}""", filePath, outPath);
|
||||
|
||||
if (detailed)
|
||||
args += " -detailed";
|
||||
if (largeBinaryHashOnly)
|
||||
args += " -largebinaryhashonly";
|
||||
if (hexFloat)
|
||||
args += " -hexfloat";
|
||||
|
||||
return Exec(args);
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// UnityEditorに含まれるコマンドラインツールを実行する為の基底Class
|
||||
// programed by Katsumasa.Kimura
|
||||
//</summary>
|
||||
public class EditorToolExec
|
||||
{
|
||||
// <value>
|
||||
// UnityEditorがインストールされているディレクトリへのパス
|
||||
// </value>
|
||||
protected string mEditorPath;
|
||||
|
||||
// <value>
|
||||
// Toolsディレクトリへのパス
|
||||
// </value>
|
||||
protected string mToolsPath;
|
||||
|
||||
// <value>
|
||||
// 実行ファイル名
|
||||
// </value>
|
||||
protected string mExecFname;
|
||||
|
||||
// <value>
|
||||
// 実行ファイルへのフルパス
|
||||
// </value>
|
||||
protected string mExecFullPath;
|
||||
|
||||
// <value>
|
||||
// 実行結果のOUTPUT
|
||||
// </value>
|
||||
private string? mOutput;
|
||||
|
||||
// <value>
|
||||
// 実行結果のOUTPUT
|
||||
// </value>
|
||||
public string? Output
|
||||
{
|
||||
get { return mOutput; }
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// コンストラクタ
|
||||
// <param>
|
||||
// mExecFname : 実行ファイル名
|
||||
// </param>
|
||||
// /summary>
|
||||
public EditorToolExec(string mExecFname)
|
||||
{
|
||||
mEditorPath = Path.GetDirectoryName(EditorApplication.applicationPath);
|
||||
mToolsPath = Path.Combine(mEditorPath, @"Data/Tools");
|
||||
this.mExecFname = mExecFname;
|
||||
//var files = Directory.GetFiles(mToolsPath, mExecFname, SearchOption.AllDirectories);
|
||||
var files = Directory.GetFiles(mEditorPath, mExecFname + "*", SearchOption.AllDirectories);
|
||||
|
||||
if (files.Length == 0)
|
||||
Serilog.Log.Error("{App} app couldn't be found at {Path}", mExecFname, mEditorPath);
|
||||
|
||||
mExecFullPath = files[0];
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// コマンドラインツールを実行する
|
||||
// <param>
|
||||
// arg : コマンドラインツールに渡す引数
|
||||
// </param>
|
||||
// </summary>
|
||||
public int Exec(string arg)
|
||||
{
|
||||
int exitCode = -1;
|
||||
|
||||
try
|
||||
{
|
||||
using var process = new Process();
|
||||
process.StartInfo.FileName = mExecFullPath;
|
||||
process.StartInfo.Arguments = arg;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
process.Start();
|
||||
mOutput = process.StandardOutput.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
exitCode = process.ExitCode;
|
||||
process.Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//UnityEngine.Debug.Log(e);
|
||||
Serilog.Log.Error(e, "Exception while running process at {Scope}.{Location}", nameof(EditorToolExec), nameof(Exec));
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6db78598a7c20a141975035612031328
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
111
Assets/Plugins/CodeAssist/Editor/Input/InputManagerMonitor.cs
Normal file
111
Assets/Plugins/CodeAssist/Editor/Input/InputManagerMonitor.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
#nullable enable
|
||||
|
||||
|
||||
namespace Meryel.UnityCodeAssist.Editor.Input
|
||||
{
|
||||
|
||||
public class InputManagerMonitor
|
||||
{
|
||||
private static readonly Lazy<InputManagerMonitor> _instance = new Lazy<InputManagerMonitor>(() => new InputManagerMonitor());
|
||||
public static InputManagerMonitor Instance => _instance.Value;
|
||||
|
||||
//UnityInputManager inputManager;
|
||||
readonly string inputManagerFilePath;
|
||||
DateTime previousTagManagerLastWrite;
|
||||
|
||||
public InputManagerMonitor()
|
||||
{
|
||||
EditorApplication.update += Update;
|
||||
inputManagerFilePath = CommonTools.GetInputManagerFilePath();
|
||||
|
||||
previousTagManagerLastWrite = System.IO.File.GetLastWriteTime(inputManagerFilePath);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
var currentInputManagerLastWrite = System.IO.File.GetLastWriteTime(inputManagerFilePath);
|
||||
if (currentInputManagerLastWrite != previousTagManagerLastWrite)
|
||||
{
|
||||
previousTagManagerLastWrite = currentInputManagerLastWrite;
|
||||
Bump();
|
||||
}
|
||||
}
|
||||
|
||||
public void Bump()
|
||||
{
|
||||
Serilog.Log.Debug("InputMonitor {Event}", nameof(Bump));
|
||||
|
||||
var inputManager = new UnityInputManager();
|
||||
inputManager.ReadFromPath(inputManagerFilePath);
|
||||
inputManager.SendData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static partial class Extensions
|
||||
{
|
||||
public static string GetInfo(this List<InputAxis> axes, string? name)
|
||||
{
|
||||
if (name == null || string.IsNullOrEmpty(name))
|
||||
return string.Empty;
|
||||
|
||||
//axis.descriptiveName
|
||||
var axesWithName = axes.Where(a => a.Name == name);
|
||||
|
||||
int threshold = 80;
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
foreach (var axis in axesWithName)
|
||||
if (!string.IsNullOrEmpty(axis.descriptiveName))
|
||||
sb.Append($"{axis.descriptiveName} ");
|
||||
|
||||
if (sb.Length > threshold)
|
||||
return sb.ToString();
|
||||
|
||||
foreach (var axis in axesWithName)
|
||||
if (!string.IsNullOrEmpty(axis.descriptiveNegativeName))
|
||||
sb.Append($"{axis.descriptiveNegativeName} ");
|
||||
|
||||
if (sb.Length > threshold)
|
||||
return sb.ToString();
|
||||
|
||||
foreach (var axis in axesWithName)
|
||||
if (!string.IsNullOrEmpty(axis.positiveButton))
|
||||
sb.Append($"[{axis.positiveButton}] ");
|
||||
|
||||
if (sb.Length > threshold)
|
||||
return sb.ToString();
|
||||
|
||||
foreach (var axis in axesWithName)
|
||||
if (!string.IsNullOrEmpty(axis.altPositiveButton))
|
||||
sb.Append($"{{{axis.altPositiveButton}}} ");
|
||||
|
||||
if (sb.Length > threshold)
|
||||
return sb.ToString();
|
||||
|
||||
foreach (var axis in axesWithName)
|
||||
if (!string.IsNullOrEmpty(axis.negativeButton))
|
||||
sb.Append($"-[{axis.negativeButton}] ");
|
||||
|
||||
if (sb.Length > threshold)
|
||||
return sb.ToString();
|
||||
|
||||
foreach (var axis in axesWithName)
|
||||
if (!string.IsNullOrEmpty(axis.altNegativeButton))
|
||||
sb.Append($"-{{{axis.altNegativeButton}}} ");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: abc0210fcf4b7cb46baab11d1db6fdb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
210
Assets/Plugins/CodeAssist/Editor/Input/Text2Yaml.cs
Normal file
210
Assets/Plugins/CodeAssist/Editor/Input/Text2Yaml.cs
Normal file
|
@ -0,0 +1,210 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
||||
#nullable enable
|
||||
|
||||
|
||||
namespace Meryel.UnityCodeAssist.Editor.Input
|
||||
{
|
||||
|
||||
public class Text2Yaml
|
||||
{
|
||||
public static string Convert(IEnumerable<string> textLines)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var stack = new Stack<(string typeName, string identifier, int indentation)>();
|
||||
|
||||
sb.AppendLine(@"%YAML 1.1");
|
||||
sb.AppendLine(@"%TAG !u! tag:unity3d.com,2011:");
|
||||
sb.AppendLine(@"--- !u!13 &1");
|
||||
sb.AppendLine(@"InputManager:");
|
||||
|
||||
var regexIndentation = new Regex("^\\s*");
|
||||
|
||||
var regexString = new Regex("^(\\s+)(\\w+)\\s+\"([a-zA-Z0-9_ ]*)\"\\s+\\(string\\)$");
|
||||
var regexValue = new Regex("^(\\s+)(\\w+)\\s+(-?[0-9.]*)\\s+\\(((bool)|(int)|(float)|(unsigned int))\\)$");
|
||||
var regexType = new Regex("^(\\s+)(\\w+)\\s+\\((\\w+)\\)$");
|
||||
|
||||
var regexVectorSize = new Regex("(\\s+)size\\s+(\\d)+\\s+\\(int\\)");
|
||||
//var regexVectorData = new Regex("(\\s+)data \\(InputAxis\\)"); // remove InputAxis to make it more generic
|
||||
|
||||
string curTextLine;
|
||||
var curTextLineNo = 3;
|
||||
var textIndentation = 1;
|
||||
var indentationPrefix = new string(' ', textIndentation * 2);
|
||||
stack.Push(("InputManager", "InputManager", textIndentation));
|
||||
|
||||
|
||||
foreach (var line in textLines.Skip(4))
|
||||
{
|
||||
curTextLine = line;
|
||||
curTextLineNo++;
|
||||
|
||||
|
||||
// Skip empty lines
|
||||
if (line.Length == 0)
|
||||
continue;
|
||||
|
||||
// Check if type undeclared, scope goes down, indentation decrements
|
||||
{
|
||||
var indentationMatch = regexIndentation.Match(line);
|
||||
if (indentationMatch.Success)
|
||||
{
|
||||
var indentation = indentationMatch.Groups[0].Value.Length;
|
||||
|
||||
if (indentation > textIndentation)
|
||||
Error($"indentation({indentation}) > textIndentation({textIndentation})");
|
||||
|
||||
while (indentation < textIndentation)
|
||||
{
|
||||
stack.Pop();
|
||||
textIndentation--;
|
||||
var typeIndentation = textIndentation;
|
||||
if (stack.TryPeek(out var curType2))
|
||||
typeIndentation = curType2.indentation;
|
||||
else if (line.Length > 0)
|
||||
Error("stack empty at type undeclaration");
|
||||
indentationPrefix = new string(' ', typeIndentation * 2);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Error($"{nameof(regexIndentation)} failed");
|
||||
}
|
||||
}
|
||||
|
||||
// Skip size field of vectors
|
||||
if (stack.TryPeek(out var curType1) && curType1.typeName == "vector")
|
||||
{
|
||||
var vectorSizeMatch = regexVectorSize.Match(line);
|
||||
if (vectorSizeMatch.Success)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Read string fields
|
||||
{
|
||||
var stringMatch = regexString.Match(line);
|
||||
if (stringMatch.Success)
|
||||
{
|
||||
AddLine(stringMatch.Groups[2] + ": " + stringMatch.Groups[3]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Read bool/int/float/unsignedInt fields
|
||||
{
|
||||
var valueMatch = regexValue.Match(line);
|
||||
if (valueMatch.Success)
|
||||
{
|
||||
AddLine(valueMatch.Groups[2] + ": " + valueMatch.Groups[3]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if new type declared, scope goes up, indentation increases
|
||||
{
|
||||
var typeMatch = regexType.Match(line);
|
||||
if (typeMatch.Success)
|
||||
{
|
||||
var identifier = typeMatch.Groups[2].Value;
|
||||
var typeName = typeMatch.Groups[3].Value;
|
||||
|
||||
var isVectorData = false;
|
||||
if (stack.TryPeek(out var curType2) && curType2.typeName == "vector" && identifier == "data")
|
||||
isVectorData = true;
|
||||
|
||||
var typeIndentation = textIndentation;
|
||||
if (stack.TryPeek(out var curType3))
|
||||
typeIndentation = curType3.indentation;
|
||||
else if (line.Length > 0)
|
||||
Error("stack empty at type declaration");
|
||||
|
||||
if (!isVectorData)
|
||||
{
|
||||
AddLine(typeMatch.Groups[2] + ":");
|
||||
}
|
||||
else
|
||||
{
|
||||
var customIndentation = typeIndentation - 1;
|
||||
if (customIndentation < 0)
|
||||
Error($"customIndentation({customIndentation}) < 0");
|
||||
var customIndentationPrefix = new string(' ', customIndentation * 2);
|
||||
AddLine("- serializedVersion: 3", customIndentationPrefix);
|
||||
}
|
||||
|
||||
|
||||
textIndentation++;
|
||||
typeIndentation++;
|
||||
|
||||
if (isVectorData)
|
||||
typeIndentation--;
|
||||
|
||||
stack.Push((typeName, identifier, typeIndentation));
|
||||
indentationPrefix = new string(' ', typeIndentation * 2);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Error("line failed to match all cases");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
|
||||
void AddLine(string line, string? customIndentationPrefix = null)
|
||||
{
|
||||
string suffix;
|
||||
if (stack.TryPeek(out var top))
|
||||
suffix = $" # {textIndentation}, {top.indentation}, {top.typeName} {top.identifier}";
|
||||
else
|
||||
suffix = $" # {textIndentation}, nil";
|
||||
|
||||
if (customIndentationPrefix != null)
|
||||
sb.AppendLine(customIndentationPrefix + line + suffix);
|
||||
else
|
||||
sb.AppendLine(indentationPrefix + line + suffix);
|
||||
}
|
||||
|
||||
void Error(string message)
|
||||
{
|
||||
var errorMessage = $"Text2Yaml error '{message}' at lineNo: {curTextLineNo}, line: '{curTextLine}' at {Environment.StackTrace}";
|
||||
//throw new Exception(errorMessage);
|
||||
Serilog.Log.Warning(errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static partial class Extensions
|
||||
{
|
||||
public static bool TryPeek<T>(this Stack<T> stack, /*[MaybeNullWhen(false)]*/ out T result)
|
||||
{
|
||||
if (stack.Count > 0)
|
||||
{
|
||||
result = stack.Peek();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = default!;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
Assets/Plugins/CodeAssist/Editor/Input/Text2Yaml.cs.meta
Normal file
11
Assets/Plugins/CodeAssist/Editor/Input/Text2Yaml.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d662105b3c16a894aa31647bdbd740ea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
405
Assets/Plugins/CodeAssist/Editor/Input/UnityInputManager.cs
Normal file
405
Assets/Plugins/CodeAssist/Editor/Input/UnityInputManager.cs
Normal file
|
@ -0,0 +1,405 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
|
||||
#nullable enable
|
||||
|
||||
|
||||
namespace Meryel.UnityCodeAssist.Editor.Input
|
||||
{
|
||||
|
||||
|
||||
internal class UnityInputManager
|
||||
{
|
||||
//string yamlPath;
|
||||
TextReader? reader;
|
||||
InputManager? inputManager;
|
||||
|
||||
public void ReadFromText(string text)
|
||||
{
|
||||
reader = new StringReader(text);
|
||||
ReadAux(false, out _);
|
||||
}
|
||||
|
||||
public void ReadFromPath(string yamlPath)
|
||||
{
|
||||
|
||||
switch (UnityEditor.EditorSettings.serializationMode)
|
||||
{
|
||||
case UnityEditor.SerializationMode.ForceText:
|
||||
{
|
||||
reader = new StreamReader(yamlPath);
|
||||
ReadAux(false, out _);
|
||||
}
|
||||
break;
|
||||
|
||||
case UnityEditor.SerializationMode.ForceBinary:
|
||||
{
|
||||
// this approach will work for InputManager since its file size is small and limited
|
||||
// but in the future, we may need to switch to reading binary files for big files
|
||||
// like this https://github.com/Unity-Technologies/UnityDataTools
|
||||
// or this https://github.com/SeriousCache/UABE
|
||||
var converted = GetOrCreateConvertedFile(yamlPath);
|
||||
if (!File.Exists(converted))
|
||||
{
|
||||
Serilog.Log.Warning("Temp file {TempFile} couldn't found for converted yaml input file. Auto Input Manager will not work!", converted);
|
||||
return;
|
||||
}
|
||||
var rawLines = File.ReadLines(converted);
|
||||
var yamlText = Text2Yaml.Convert(rawLines);
|
||||
reader = new StringReader(yamlText);
|
||||
ReadAux(false, out _);
|
||||
}
|
||||
break;
|
||||
|
||||
case UnityEditor.SerializationMode.Mixed:
|
||||
{
|
||||
reader = new StreamReader(yamlPath);
|
||||
ReadAux(true, out var hasSemanticError);
|
||||
if (hasSemanticError)
|
||||
{
|
||||
var converted = GetOrCreateConvertedFile(yamlPath);
|
||||
if (!File.Exists(converted))
|
||||
{
|
||||
Serilog.Log.Warning("Temp file {TempFile} couldn't found for converted yaml input file. Auto Input Manager will not work!", converted);
|
||||
return;
|
||||
}
|
||||
var rawLines = File.ReadLines(converted);
|
||||
var yamlText = Text2Yaml.Convert(rawLines);
|
||||
reader = new StringReader(yamlText);
|
||||
ReadAux(false, out _);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReadAux(bool canHaveSemanticError, out bool hasSemanticError)
|
||||
{
|
||||
hasSemanticError = false;
|
||||
|
||||
if (reader == null)
|
||||
{
|
||||
Serilog.Log.Warning($"{nameof(UnityInputManager)}.{nameof(reader)} is null");
|
||||
return;
|
||||
}
|
||||
|
||||
//var reader = new StreamReader(yamlPath);
|
||||
var deserializer = new YamlDotNet.Serialization.DeserializerBuilder()
|
||||
.WithTagMapping("tag:unity3d.com,2011:13", typeof(Class13Mapper))
|
||||
.IgnoreUnmatchedProperties()
|
||||
.Build();
|
||||
//serializer.Settings.RegisterTagMapping("tag:unity3d.com,2011:13", typeof(Class13));
|
||||
//serializer.Settings.ComparerForKeySorting = null;
|
||||
Class13Mapper? result;
|
||||
try
|
||||
{
|
||||
result = deserializer.Deserialize<Class13Mapper>(reader);
|
||||
}
|
||||
catch (YamlDotNet.Core.SemanticErrorException semanticErrorException)
|
||||
{
|
||||
Serilog.Log.Debug(semanticErrorException, "Couldn't parse InputManager.asset yaml file");
|
||||
if (!canHaveSemanticError)
|
||||
Serilog.Log.Error(semanticErrorException, "Couldn't parse InputManager.asset yaml file unexpectedly");
|
||||
|
||||
hasSemanticError = true;
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
var inputManagerMapper = result?.InputManager;
|
||||
if (inputManagerMapper == null)
|
||||
{
|
||||
Serilog.Log.Warning($"{nameof(inputManagerMapper)} is null");
|
||||
return;
|
||||
}
|
||||
|
||||
inputManager = new InputManager(inputManagerMapper);
|
||||
}
|
||||
|
||||
|
||||
public void SendData()
|
||||
{
|
||||
if (inputManager == null)
|
||||
return;
|
||||
|
||||
var axisNames = inputManager.Axes.Select(a => a.Name!).Where(n => !string.IsNullOrEmpty(n)).Distinct().ToArray();
|
||||
var axisInfos = axisNames.Select(a => inputManager.Axes.GetInfo(a)).ToArray();
|
||||
if (!CreateBindingsMap(out var buttonKeys, out var buttonAxis))
|
||||
return;
|
||||
|
||||
string[] joystickNames;
|
||||
try
|
||||
{
|
||||
joystickNames = UnityEngine.Input.GetJoystickNames();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// Occurs if user have switched active Input handling to Input System package in Player Settings.
|
||||
joystickNames = new string[0];
|
||||
}
|
||||
|
||||
NetMQInitializer.Publisher?.SendInputManager(axisNames, axisInfos, buttonKeys, buttonAxis, joystickNames);
|
||||
|
||||
/*
|
||||
NetMQInitializer.Publisher?.SendInputManager(
|
||||
inputManager.Axes.Select(a => a.Name).Distinct().ToArray(),
|
||||
inputManager.Axes.Select(a => a.positiveButton).ToArray(),
|
||||
inputManager.Axes.Select(a => a.negativeButton).ToArray(),
|
||||
inputManager.Axes.Select(a => a.altPositiveButton).ToArray(),
|
||||
inputManager.Axes.Select(a => a.altNegativeButton).ToArray(),
|
||||
UnityEngine.Input.GetJoystickNames()
|
||||
);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool CreateBindingsMap([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? inputKeys, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? inputAxis)
|
||||
{
|
||||
if (inputManager == null)
|
||||
{
|
||||
inputKeys = null;
|
||||
inputAxis = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var dict = new Dictionary<string, string?>();
|
||||
|
||||
foreach (var axis in inputManager.Axes)
|
||||
{
|
||||
if (axis.altNegativeButton != null && !string.IsNullOrEmpty(axis.altNegativeButton))
|
||||
dict[axis.altNegativeButton] = axis.Name;
|
||||
}
|
||||
foreach (var axis in inputManager.Axes)
|
||||
{
|
||||
if (axis.negativeButton != null && !string.IsNullOrEmpty(axis.negativeButton))
|
||||
dict[axis.negativeButton] = axis.Name;
|
||||
}
|
||||
foreach (var axis in inputManager.Axes)
|
||||
{
|
||||
if (axis.altPositiveButton != null && !string.IsNullOrEmpty(axis.altPositiveButton))
|
||||
dict[axis.altPositiveButton] = axis.Name;
|
||||
}
|
||||
foreach (var axis in inputManager.Axes)
|
||||
{
|
||||
if (axis.positiveButton != null && !string.IsNullOrEmpty(axis.positiveButton))
|
||||
dict[axis.positiveButton] = axis.Name;
|
||||
}
|
||||
|
||||
var keys = new string[dict.Count];
|
||||
var values = new string[dict.Count];
|
||||
dict.Keys.CopyTo(keys, 0);
|
||||
dict.Values.CopyTo(values, 0);
|
||||
|
||||
inputKeys = keys;
|
||||
inputAxis = values;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static string GetOrCreateConvertedFile(string filePath)
|
||||
{
|
||||
var hash = GetMD5Hash(filePath);
|
||||
var convertedPath = Path.Combine(Path.GetTempPath(), $"UCA_IM_{hash}.txt");
|
||||
|
||||
if (!File.Exists(convertedPath))
|
||||
{
|
||||
Serilog.Log.Debug("Converting binary to text format of {File} to {Target}", filePath, convertedPath);
|
||||
var converter = new Binary2TextExec();
|
||||
converter.Exec(filePath, convertedPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serilog.Log.Debug("Converted file already exists at {Target}", convertedPath);
|
||||
}
|
||||
|
||||
return convertedPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a hash of the file using MD5.
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetMD5Hash(string filePath)
|
||||
{
|
||||
using var md5 = new MD5CryptoServiceProvider();
|
||||
return GetHash(filePath, md5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a hash of the file using MD5.
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetMD5Hash(Stream s)
|
||||
{
|
||||
using var md5 = new MD5CryptoServiceProvider();
|
||||
return GetHash(s, md5);
|
||||
}
|
||||
|
||||
private static string GetHash(string filePath, HashAlgorithm hasher)
|
||||
{
|
||||
using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return GetHash(fs, hasher);
|
||||
}
|
||||
|
||||
private static string GetHash(Stream s, HashAlgorithm hasher)
|
||||
{
|
||||
var hash = hasher.ComputeHash(s);
|
||||
var hashStr = Convert.ToBase64String(hash);
|
||||
//return hashStr.TrimEnd('=');
|
||||
var hashStrAlphaNumeric = System.Text.RegularExpressions.Regex.Replace(hashStr, "[^A-Za-z0-9]", "");
|
||||
return hashStrAlphaNumeric;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum AxisType
|
||||
{
|
||||
KeyOrMouseButton = 0,
|
||||
MouseMovement = 1,
|
||||
JoystickAxis = 2
|
||||
};
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
|
||||
public class InputAxisMapper
|
||||
{
|
||||
public int serializedVersion { get; set; }
|
||||
|
||||
public string? m_Name { get; set; }
|
||||
public string? descriptiveName { get; set; }
|
||||
public string? descriptiveNegativeName { get; set; }
|
||||
public string? negativeButton { get; set; }
|
||||
public string? positiveButton { get; set; }
|
||||
public string? altNegativeButton { get; set; }
|
||||
public string? altPositiveButton { get; set; }
|
||||
|
||||
//public float gravity { get; set; }
|
||||
//public float dead { get; set; }
|
||||
//public float sensitivity { get; set; }
|
||||
public string? gravity { get; set; }
|
||||
public string? dead { get; set; }
|
||||
public string? sensitivity { get; set; }
|
||||
|
||||
//public bool snap { get; set; }
|
||||
public int snap { get; set; }
|
||||
//public bool invert { get; set; }
|
||||
public int invert { get; set; }
|
||||
|
||||
//public AxisType type { get; set; }
|
||||
public int type { get; set; }
|
||||
|
||||
public int axis { get; set; }
|
||||
public int joyNum { get; set; }
|
||||
}
|
||||
|
||||
public class InputAxis
|
||||
{
|
||||
readonly InputAxisMapper map;
|
||||
|
||||
public InputAxis(InputAxisMapper map)
|
||||
{
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public int SerializedVersion
|
||||
{
|
||||
get { return map.serializedVersion; }
|
||||
set { map.serializedVersion = value; }
|
||||
}
|
||||
|
||||
public string? Name => map.m_Name;
|
||||
public string? descriptiveName => map.descriptiveName;
|
||||
public string? descriptiveNegativeName => map.descriptiveNegativeName;
|
||||
public string? negativeButton => map.negativeButton;
|
||||
public string? positiveButton => map.positiveButton;
|
||||
public string? altNegativeButton => map.altNegativeButton;
|
||||
public string? altPositiveButton => map.altPositiveButton;
|
||||
|
||||
public float gravity => float.Parse(map.gravity);//**--format
|
||||
public float dead => float.Parse(map.dead);//**--format
|
||||
public float sensitivity => float.Parse(map.sensitivity);//**--format
|
||||
|
||||
public bool snap => map.snap != 0;
|
||||
public bool invert => map.invert != 0;
|
||||
|
||||
public AxisType type => (AxisType)map.type;
|
||||
|
||||
public int axis => map.axis;
|
||||
public int joyNum => map.joyNum;
|
||||
}
|
||||
|
||||
public class InputManagerMapper
|
||||
{
|
||||
public int m_ObjectHideFlags { get; set; }
|
||||
public int serializedVersion { get; set; }
|
||||
public int m_UsePhysicalKeys { get; set; }
|
||||
public List<InputAxisMapper>? m_Axes { get; set; }
|
||||
}
|
||||
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
public class InputManager
|
||||
{
|
||||
readonly InputManagerMapper map;
|
||||
readonly List<InputAxis> axes;
|
||||
|
||||
public InputManager(InputManagerMapper map)
|
||||
{
|
||||
this.map = map;
|
||||
this.axes = new List<InputAxis>();
|
||||
|
||||
if (map.m_Axes == null)
|
||||
{
|
||||
Serilog.Log.Warning($"map.m_Axes is null");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var a in map.m_Axes)
|
||||
this.axes.Add(new InputAxis(a));
|
||||
}
|
||||
|
||||
public int ObjectHideFlags
|
||||
{
|
||||
get { return map.m_ObjectHideFlags; }
|
||||
set { map.m_ObjectHideFlags = value; }
|
||||
}
|
||||
|
||||
public int SerializedVersion
|
||||
{
|
||||
get { return map.serializedVersion; }
|
||||
set { map.serializedVersion = value; }
|
||||
}
|
||||
|
||||
public bool UsePhysicalKeys
|
||||
{
|
||||
get { return map.m_UsePhysicalKeys != 0; }
|
||||
set { map.m_UsePhysicalKeys = value ? 1 : 0; }
|
||||
}
|
||||
|
||||
/*public List<InputAxisMapper> Axes
|
||||
{
|
||||
get { return map.m_Axes; }
|
||||
set { map.m_Axes = value; }
|
||||
}*/
|
||||
public List<InputAxis> Axes => axes;
|
||||
}
|
||||
|
||||
public class Class13Mapper
|
||||
{
|
||||
public InputManagerMapper? InputManager { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 94bc173b04900674ba9cf4b722f8f8d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue