NET 8 Upgrade (#687)

* Initial .NET8 Upgrade

* Initial GitHub Actions Cleanup

* Fix Desktop Notifications

* Fix throw warning

* Upgrade vunerable transative nuget packages

* Fix warnings with registry overflow

* Adjust async/await usage for configRepository

* Fix TTS voice name and app auto start

* Install .NET 8 with setup

I regret NSIS

* Remove no longer needed System/MS references (included in dotnet sdk)

* Surpress stackalloc in loop warning, that code scares me.

* Removed unused SharpDX packages

* Ignore WebClient warning, hopefully this project doesn't move past NET 8

* Fixed terrifying code

* GenerateAssemblyInfo

* Trimmed editor config to only silence warning.

* Fix open webpage

* Fix updater

---------

Co-authored-by: DubyaDude <ushafiq141@gmail.com>
Co-authored-by: Natsumi <cmcooper123@hotmail.com>
This commit is contained in:
Ethan Cordray
2023-11-21 07:41:57 -05:00
committed by GitHub
parent 7bb5c8ea45
commit 2e9db3153d
26 changed files with 796 additions and 736 deletions
+18 -16
View File
@@ -14,9 +14,9 @@ using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Windows.UI.Notifications;
using CefSharp;
using librsync.net;
using Microsoft.Toolkit.Uwp.Notifications;
using Microsoft.Win32;
using NLog;
@@ -106,7 +106,10 @@ namespace VRCX
if (url.StartsWith("http://") ||
url.StartsWith("https://"))
{
Process.Start(url).Close();
Process.Start(new ProcessStartInfo(url)
{
UseShellExecute = true
});
}
}
@@ -182,20 +185,18 @@ namespace VRCX
/// <param name="Image">The optional image to display in the notification.</param>
public void DesktopNotification(string BoldText, string Text = "", string Image = "")
{
var toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText02);
var stringElements = toastXml.GetElementsByTagName("text");
var imagePath = Path.Combine(Program.BaseDirectory, "VRCX.ico");
if (!string.IsNullOrEmpty(Image))
{
imagePath = Image;
}
ToastContentBuilder builder = new ToastContentBuilder();
if (Uri.TryCreate(Image, UriKind.Absolute, out Uri uri))
builder.AddAppLogoOverride(uri);
stringElements[0].AppendChild(toastXml.CreateTextNode(BoldText));
stringElements[1].AppendChild(toastXml.CreateTextNode(Text));
var imageElements = toastXml.GetElementsByTagName("image");
imageElements[0].Attributes.GetNamedItem("src").NodeValue = imagePath;
var toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier("VRCX").Show(toast);
if (!string.IsNullOrEmpty(BoldText))
builder.AddText(BoldText);
if (!string.IsNullOrEmpty(Text))
builder.AddText(Text);
builder.Show();
}
/// <summary>
@@ -229,7 +230,8 @@ namespace VRCX
{
IPCServer.Send(new IPCPacket
{
Type = "VRCXLaunch"
Type = "VRCXLaunch",
MsgType = "VRCXLaunch"
});
}
+38 -36
View File
@@ -14,27 +14,25 @@ namespace VRCX
public partial class AppApi
{
[DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int RegSetValueExA(
IntPtr hKey,
string lpValueName,
int reserved,
public static extern uint RegSetValueEx(
UIntPtr hKey,
[MarshalAs(UnmanagedType.LPStr)] string lpValueName,
int Reserved,
RegistryValueKind dwType,
byte[] lpData,
int cbData
);
int cbData);
[DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int RegOpenKeyExA(
IntPtr hKey,
string lpSubKey,
public static extern int RegOpenKeyEx(
UIntPtr hKey,
string subKey,
int ulOptions,
int samDesired,
out IntPtr phkResult
);
out UIntPtr hkResult);
[DllImport("advapi32.dll")]
public static extern int RegCloseKey(IntPtr hKey);
public static extern int RegCloseKey(UIntPtr hKey);
public string AddHashToKeyName(string key)
{
// https://discussions.unity.com/t/playerprefs-changing-the-name-of-keys/30332/4
@@ -44,7 +42,7 @@ namespace VRCX
hash = (hash * 33) ^ c;
return key + "_h" + hash;
}
/// <summary>
/// Retrieves the value of the specified key from the VRChat group in the windows registry.
/// </summary>
@@ -94,7 +92,7 @@ namespace VRCX
{
if (regKey == null)
return false;
object setValue = null;
switch (type)
{
@@ -109,13 +107,13 @@ namespace VRCX
if (setValue == null)
return false;
regKey.SetValue(keyName, setValue, type);
}
return true;
}
/// <summary>
/// Sets the value of the specified key in the VRChat group in the windows registry.
/// </summary>
@@ -124,20 +122,20 @@ namespace VRCX
public void SetVRChatRegistryKey(string key, byte[] value)
{
var keyName = AddHashToKeyName(key);
var hKey = (IntPtr)0x80000001; // HKEY_LOCAL_MACHINE
var hKey = (UIntPtr)0x80000001; // HKEY_LOCAL_MACHINE
const int keyWrite = 0x20006;
const string keyFolder = @"SOFTWARE\VRChat\VRChat";
var openKeyResult = RegOpenKeyExA(hKey, keyFolder, 0, keyWrite, out var folderPointer);
var openKeyResult = RegOpenKeyEx(hKey, keyFolder, 0, keyWrite, out var folderPointer);
if (openKeyResult != 0)
throw new Exception("Error opening registry key. Error code: " + openKeyResult);
var setKeyResult = RegSetValueExA(folderPointer, keyName, 0, RegistryValueKind.DWord, value, value.Length);
var setKeyResult = RegSetValueEx(folderPointer, keyName, 0, RegistryValueKind.DWord, value, value.Length);
if (setKeyResult != 0)
throw new Exception("Error setting registry value. Error code: " + setKeyResult);
RegCloseKey(hKey);
}
public Dictionary<string, Dictionary<string, object>> GetVRChatRegistry()
{
var output = new Dictionary<string, Dictionary<string, object>>();
@@ -147,13 +145,17 @@ namespace VRCX
throw new Exception("Nothing to backup.");
var keys = regKey.GetValueNames();
Span<long> spanLong = stackalloc long[1];
Span<double> doubleSpan = MemoryMarshal.Cast<long, double>(spanLong);
foreach (var key in keys)
{
var data = regKey.GetValue(key);
var index = key.LastIndexOf("_h", StringComparison.Ordinal);
if (index <= 0)
continue;
var keyName = key.Substring(0, index);
if (data == null)
continue;
@@ -181,9 +183,9 @@ namespace VRCX
output.Add(keyName, dwordDict);
break;
}
Span<long> spanLong = stackalloc long[] { (long)data };
var doubleValue = MemoryMarshal.Cast<long, double>(spanLong)[0];
spanLong[0] = (long)data;
var doubleValue = doubleSpan[0];
var floatDict = new Dictionary<string, object>
{
{ "data", doubleValue },
@@ -191,7 +193,7 @@ namespace VRCX
};
output.Add(keyName, floatDict);
break;
default:
Debug.WriteLine($"Unknown registry value kind: {type}");
break;
@@ -225,20 +227,20 @@ namespace VRCX
SetVRChatRegistryKey(item.Key, dataBytes);
continue;
}
if (int.TryParse(data.ToString(), out var intValue))
{
SetVRChatRegistryKey(item.Key, intValue, type);
continue;
}
throw new Exception("Unknown number type: " + item.Key);
}
SetVRChatRegistryKey(item.Key, data, type);
}
}
public bool HasVRChatRegistryFolder()
{
using (var regKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\VRChat\VRChat"))
@@ -258,7 +260,7 @@ namespace VRCX
throw new Exception("Error creating registry key.");
}
}
public void DeleteVRChatRegistryFolder()
{
using (var regKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\VRChat\VRChat"))
@@ -269,7 +271,7 @@ namespace VRCX
Registry.CurrentUser.DeleteSubKeyTree(@"SOFTWARE\VRChat\VRChat");
}
}
/// <summary>
/// Opens a file dialog to select a VRChat registry backup JSON file.
/// </summary>
@@ -298,7 +300,7 @@ namespace VRCX
var path = openFileDialog.FileName;
if (string.IsNullOrEmpty(path))
return;
// return file contents
var json = File.ReadAllText(path);
ExecuteAppFunction("restoreVrcRegistryFromFile", json);
+16 -5
View File
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Timers;
using NLog;
namespace VRCX
{
@@ -14,6 +15,7 @@ namespace VRCX
public class AutoAppLaunchManager
{
public static AutoAppLaunchManager Instance { get; private set; }
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public static readonly string VRChatProcessName = "VRChat";
public bool Enabled = false;
@@ -215,14 +217,23 @@ namespace VRCX
/// Starts a new child process.
/// </summary>
/// <param name="path">The path.</param>
internal void StartChildProcess(string path)
private void StartChildProcess(string path)
{
try
{
using (var process = Process.Start(path))
if (process != null)
startedProcesses.Add(path, new HashSet<int>() { process.Id });
} catch { }
var process = new Process();
process.StartInfo = new ProcessStartInfo(path)
{
UseShellExecute = true
};
process.Start();
if (process.Id != 0)
startedProcesses.Add(path, new HashSet<int>() { process.Id });
}
catch (Exception ex)
{
logger.Error(ex);
}
}
/// <summary>
+1 -1
View File
@@ -56,7 +56,7 @@ namespace VRCX
cefSettings.CefCommandLineArgs["remote-allow-origins"] = "*";
}
CefSharpSettings.WcfEnabled = true; // TOOD: REMOVE THIS LINE YO (needed for synchronous configRepository)
//CefSharpSettings.WcfEnabled = true; // TOOD: REMOVE THIS LINE YO (needed for synchronous configRepository)
CefSharpSettings.ShutdownOnExit = false;
if (Cef.Initialize(cefSettings) == false)
+1 -1
View File
@@ -110,7 +110,7 @@ namespace VRCX
if ("true".Equals(VRCXStorage.Instance.Get("VRCX_StartAsMinimizedState")) &&
"true".Equals(VRCXStorage.Instance.Get("VRCX_CloseToTray")))
{
BeginInvoke(new MethodInvoker(Hide));
BeginInvoke(Hide);
}
else
{
+4 -3
View File
@@ -12,6 +12,7 @@ using SharpDX.Direct3D11;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Range = CefSharp.Structs.Range;
namespace VRCX
{
@@ -87,7 +88,7 @@ namespace VRCX
var rowPitch = dataBox.RowPitch;
if (pitch == rowPitch)
{
WinApi.CopyMemory(
WinApi.RtlCopyMemory(
destinationPtr,
sourcePtr,
(uint)(_width * _height * 4)
@@ -97,7 +98,7 @@ namespace VRCX
{
for (var y = _height; y > 0; --y)
{
WinApi.CopyMemory(
WinApi.RtlCopyMemory(
destinationPtr,
sourcePtr,
(uint)pitch
@@ -168,7 +169,7 @@ namespace VRCX
);
}
WinApi.CopyMemory(
WinApi.RtlCopyMemory(
_paintBuffer.AddrOfPinnedObject(),
buffer,
(uint)(width * height * 4)
+5 -5
View File
@@ -263,11 +263,11 @@ namespace VRCX
}
}
_browser2.Dispose();
_browser1.Dispose();
_texture2.Dispose();
_texture1.Dispose();
_device.Dispose();
_browser2?.Dispose();
_browser1?.Dispose();
_texture2?.Dispose();
_texture1?.Dispose();
_device?.Dispose();
}
public void SetActive(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand)
+1 -1
View File
@@ -2003,7 +2003,7 @@ namespace SQLite
throw NotNullConstraintViolationException.New (ex, map, obj);
}
throw ex;
throw;
}
if (rowsAffected > 0)
+4 -2
View File
@@ -32,7 +32,7 @@ namespace VRCX
Install();
}
public static void Install()
private static void Install()
{
try
{
@@ -42,7 +42,9 @@ namespace VRCX
StartInfo = new ProcessStartInfo
{
FileName = VRCX_Setup_Executable,
Arguments = "/S"
Arguments = "/S",
UseShellExecute = true,
WorkingDirectory = Program.AppDataDirectory
}
};
VRCXProcess.Start();
+8 -8
View File
@@ -8,14 +8,14 @@ namespace VRCX
public static void ApplyJavascriptBindings(IJavascriptObjectRepository repository)
{
repository.NameConverter = null;
repository.Register("AppApi", AppApi.Instance, true);
repository.Register("SharedVariable", SharedVariable.Instance, false);
repository.Register("WebApi", WebApi.Instance, true);
repository.Register("VRCXStorage", VRCXStorage.Instance, true);
repository.Register("SQLite", SQLiteLegacy.Instance, true);
repository.Register("LogWatcher", LogWatcher.Instance, true);
repository.Register("Discord", Discord.Instance, true);
repository.Register("AssetBundleCacher", AssetBundleCacher.Instance, true);
repository.Register("AppApi", AppApi.Instance);
repository.Register("SharedVariable", SharedVariable.Instance);
repository.Register("WebApi", WebApi.Instance);
repository.Register("VRCXStorage", VRCXStorage.Instance);
repository.Register("SQLite", SQLiteLegacy.Instance);
repository.Register("LogWatcher", LogWatcher.Instance);
repository.Register("Discord", Discord.Instance);
repository.Register("AssetBundleCacher", AssetBundleCacher.Instance);
}
}
}
+10 -4
View File
@@ -70,7 +70,9 @@ namespace VRCX
{
using (var stream = new MemoryStream(Convert.FromBase64String((string)values[0])))
{
_cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(stream);
_cookieContainer = new CookieContainer();
_cookieContainer.Add(System.Text.Json.JsonSerializer.Deserialize<CookieCollection>(stream));
//_cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(stream);
}
}
catch
@@ -94,7 +96,8 @@ namespace VRCX
{
using (var memoryStream = new MemoryStream())
{
new BinaryFormatter().Serialize(memoryStream, _cookieContainer);
System.Text.Json.JsonSerializer.Serialize(memoryStream, _cookieContainer.GetAllCookies());
//new BinaryFormatter().Serialize(memoryStream, _cookieContainer);
SQLiteLegacy.Instance.ExecuteNonQuery(
"INSERT OR REPLACE INTO `cookies` (`key`, `value`) VALUES (@key, @value)",
new Dictionary<string, object>() {
@@ -116,7 +119,8 @@ namespace VRCX
using (var memoryStream = new MemoryStream())
{
new BinaryFormatter().Serialize(memoryStream, _cookieContainer);
System.Text.Json.JsonSerializer.Serialize(memoryStream, _cookieContainer.GetAllCookies());
//new BinaryFormatter().Serialize(memoryStream, _cookieContainer);
return Convert.ToBase64String(memoryStream.ToArray());
}
}
@@ -125,7 +129,9 @@ namespace VRCX
{
using (var stream = new MemoryStream(Convert.FromBase64String(cookies)))
{
_cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(stream);
//_cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(stream);
_cookieContainer = new CookieContainer();
_cookieContainer.Add(System.Text.Json.JsonSerializer.Deserialize<CookieCollection>(stream));
}
_cookieDirty = true; // force cookies to be saved for lastUserLoggedIn
+1 -1
View File
@@ -12,7 +12,7 @@ namespace VRCX
public static class WinApi
{
[DllImport("kernel32.dll", SetLastError = false)]
public static extern void CopyMemory(IntPtr destination, IntPtr source, uint length);
public static extern void RtlCopyMemory(IntPtr destination, IntPtr source, uint length);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);