mirror of
https://github.com/knah/VRCMelonAssistant.git
synced 2024-09-28 23:31:33 +12:00
Compare commits
16 commits
v1.1.20.10
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
f905428238 | ||
|
b74c421bbb | ||
|
71efc3990f | ||
|
d57e730baa | ||
|
2adb976b21 | ||
|
59cd085130 | ||
|
992480facc | ||
|
8160521d10 | ||
|
a6321a9ecc | ||
|
88c987d714 | ||
|
610098dcbf | ||
|
ec8cd210f7 | ||
|
66d2b41de8 | ||
|
ed27510ccc | ||
|
0f60e68c02 | ||
|
f250bb893c |
14 changed files with 143 additions and 64 deletions
|
@ -6,8 +6,8 @@ namespace VRCMelonAssistant
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, List<string>> CategoryContents = new()
|
private static readonly Dictionary<string, List<string>> CategoryContents = new()
|
||||||
{
|
{
|
||||||
{"Safety & Security", new() {"Advanced Safety", "Finitizer", "True Shader Anticrash", "Safety-Presets"}},
|
{"Safety & Security", new() {"Advanced Safety", "Finitizer", "True Shader Anticrash", "Safety-Presets", "Final IK Sanity"}},
|
||||||
{"Core mods and libraries", new() {"UI Expansion Kit", "ActionMenuApi", "VRCModUpdater.Loader"}},
|
{"Core mods and libraries", new() {"UI Expansion Kit", "ActionMenuApi", "VRCModUpdater.Loader", "VRChatUtilityKit"}},
|
||||||
{"All-in-one mods", new() {"emmVRCLoader"}},
|
{"All-in-one mods", new() {"emmVRCLoader"}},
|
||||||
{"Camera mods", new() {
|
{"Camera mods", new() {
|
||||||
"CameraMinus", "DesktopCamera", "BetterSteadycam", "ITR's Melon Cameras", "CameraResChanger",
|
"CameraMinus", "DesktopCamera", "BetterSteadycam", "ITR's Melon Cameras", "CameraResChanger",
|
||||||
|
@ -15,16 +15,17 @@ namespace VRCMelonAssistant
|
||||||
}},
|
}},
|
||||||
{"Performance & Fidelity", new() {
|
{"Performance & Fidelity", new() {
|
||||||
"Core Limiter", "MirrorResolutionUnlimiter", "AvatarHider", "Runtime Graphics Settings",
|
"Core Limiter", "MirrorResolutionUnlimiter", "AvatarHider", "Runtime Graphics Settings",
|
||||||
"GamePriority", "FrameFocus", "ClearVRAM", "NoPerformanceStats"
|
"GamePriority", "FrameFocus", "ClearVRAM", "NoPerformanceStats", "Turbones"
|
||||||
}},
|
}},
|
||||||
{"Utilities & Tweaks", new() {
|
{"Utilities & Tweaks", new() {
|
||||||
"ReloadAvatars", "KeyboardPaste", "No Outlines", "UnmuteSound", "SparkleBeGone",
|
"ReloadAvatars", "KeyboardPaste", "No Outlines", "UnmuteSound", "SparkleBeGone",
|
||||||
"BTKSAImmersiveHud", "OGTrustRanks", "ToggleMicIcon", "Friends+ home",
|
"BTKSAImmersiveHud", "OGTrustRanks", "ToggleMicIcon", "Friends+ home",
|
||||||
"MicSensitivity", "CloningBeGone", "ToggleFullScreen", "View Point Tweaker",
|
"MicSensitivity", "CloningBeGone", "ToggleFullScreen", "View Point Tweaker",
|
||||||
"SettingsRestart", "SmallUserVolume", "TeleportCameraToYou",
|
"SettingsRestart", "SmallUserVolume", "TeleportCameraToYou",
|
||||||
"BetterPortalPlacement"
|
"BetterPortalPlacement", "BetterDirections", "ChairExitController",
|
||||||
|
"Panic Button Rework", "SelectYourself", "Trust Color Changer", "Voice Falloff Override"
|
||||||
}},
|
}},
|
||||||
{"Hardware support", new() {"LeapMotionExtension", "ThumbParams", "VRCFaceTracking", "VRCPimaxEyeTracker"}},
|
{"Hardware support", new() {"LeapMotionExtension", "ThumbParams", "VRCFaceTracking", "VRCPimaxEyeTracker", "VRCBhapticsIntegration"}},
|
||||||
{"Dynamic bones", new() {
|
{"Dynamic bones", new() {
|
||||||
"ImmersiveTouch", "Dynamic Bones Safety", "MultiplayerDynamicBonesMod", "Multiplayer Dynamic Bones",
|
"ImmersiveTouch", "Dynamic Bones Safety", "MultiplayerDynamicBonesMod", "Multiplayer Dynamic Bones",
|
||||||
}},
|
}},
|
||||||
|
@ -36,12 +37,14 @@ namespace VRCMelonAssistant
|
||||||
"IKTweaks", "JoinNotifier", "FBT Saver", "BTKSANameplateMod", "AdvancedInvites", "VRCVideoLibrary",
|
"IKTweaks", "JoinNotifier", "FBT Saver", "BTKSANameplateMod", "AdvancedInvites", "VRCVideoLibrary",
|
||||||
"BTKSASelfPortrait", "OldMate", "BetterLoadingScreen", "Loading Screen Pictures", "FavCat",
|
"BTKSASelfPortrait", "OldMate", "BetterLoadingScreen", "Loading Screen Pictures", "FavCat",
|
||||||
"ActionMenuUtils", "WorldPredownload", "AskToPortal", "Headlight", "ITR's Player Tracer",
|
"ActionMenuUtils", "WorldPredownload", "AskToPortal", "Headlight", "ITR's Player Tracer",
|
||||||
"InstanceHistory", "PortableMirrorMod", "VRCBonesController"
|
"InstanceHistory", "PortableMirrorMod", "VRCBonesController", "CalibrationLinesVisualizer",
|
||||||
|
"ITR's Collider Mod", "RememberMe", "TriggerESP"
|
||||||
}},
|
}},
|
||||||
{"UI mods", new() {
|
{"UI mods", new() {
|
||||||
"Particle and DynBone limiter settings UI", "CalibrateConfirm", "Emoji Page Buttons",
|
"Particle and DynBone limiter settings UI", "CalibrateConfirm", "Emoji Page Buttons",
|
||||||
"UserInfoExtensions", "MLConsoleViewer", "OwO Mod", "ActiveBackground", "PlayerList", "ComfyVRMenu",
|
"UserInfoExtensions", "MLConsoleViewer", "OwO Mod", "ActiveBackground", "PlayerList", "ComfyVRMenu",
|
||||||
"DiscordMute", "MicToggle", "VRCPlusPet"
|
"DiscordMute", "MicToggle", "VRCPlusPet", "AMMusic", "Friend Notes", "GestureIndicator",
|
||||||
|
"NameplateStats", "PreviewScroller", "ProPlates", "QuickMenuVolume", "ToggleUIStickers"
|
||||||
}},
|
}},
|
||||||
{"Movement", new() {
|
{"Movement", new() {
|
||||||
"TeleporterVR", "ImmobilizePlayerMod", "TrackingRotator", "OculusPlayspaceMover",
|
"TeleporterVR", "ImmobilizePlayerMod", "TrackingRotator", "OculusPlayspaceMover",
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace VRCMelonAssistant
|
||||||
{
|
{
|
||||||
MainWindow.Instance.MainText = $"{(string) App.Current.FindResource("Mods:DownloadingMelonLoader")}...";
|
MainWindow.Instance.MainText = $"{(string) App.Current.FindResource("Mods:DownloadingMelonLoader")}...";
|
||||||
|
|
||||||
using var installerZip = await DownloadFileToMemory("https://github.com/LavaGang/MelonLoader/releases/download/v0.3.0/MelonLoader.x64.zip");
|
using var installerZip = await DownloadFileToMemory("https://github.com/LavaGang/MelonLoader/releases/latest/download/MelonLoader.x64.zip");
|
||||||
using var zipReader = new ZipArchive(installerZip, ZipArchiveMode.Read);
|
using var zipReader = new ZipArchive(installerZip, ZipArchiveMode.Read);
|
||||||
|
|
||||||
MainWindow.Instance.MainText = $"{(string) App.Current.FindResource("Mods:UnpackingMelonLoader")}...";
|
MainWindow.Instance.MainText = $"{(string) App.Current.FindResource("Mods:UnpackingMelonLoader")}...";
|
||||||
|
@ -80,7 +80,7 @@ namespace VRCMelonAssistant
|
||||||
|
|
||||||
public static async Task InstallMod(Mod mod)
|
public static async Task InstallMod(Mod mod)
|
||||||
{
|
{
|
||||||
string downloadLink = mod.versions[0].downloadlink;
|
string downloadLink = mod.versions[0].downloadLink;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(downloadLink))
|
if (string.IsNullOrEmpty(downloadLink))
|
||||||
{
|
{
|
||||||
|
@ -91,21 +91,27 @@ namespace VRCMelonAssistant
|
||||||
if (mod.installedFilePath != null)
|
if (mod.installedFilePath != null)
|
||||||
File.Delete(mod.installedFilePath);
|
File.Delete(mod.installedFilePath);
|
||||||
|
|
||||||
var modUri = new Uri(downloadLink);
|
|
||||||
var targetFilePath = Path.Combine(App.VRChatInstallDirectory, mod.versions[0].IsPlugin ? "Plugins" : "Mods",
|
string targetFilePath = "";
|
||||||
mod.versions[0].IsBroken ? "Broken" : "", modUri.Segments.Last());
|
|
||||||
|
using (var resp = await Http.HttpClient.GetAsync(downloadLink))
|
||||||
|
{
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
await resp.Content.CopyToAsync(stream);
|
||||||
|
stream.Position = 0;
|
||||||
|
|
||||||
|
targetFilePath = Path.Combine(App.VRChatInstallDirectory, mod.versions[0].IsPlugin ? "Plugins" : "Mods",
|
||||||
|
mod.versions[0].IsBroken ? "Broken" : (mod.versions[0].IsRetired ? "Retired" : ""), resp.RequestMessage.RequestUri.Segments.Last());
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(targetFilePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(targetFilePath));
|
||||||
|
|
||||||
using (Stream stream = await DownloadFileToMemory(downloadLink))
|
|
||||||
{
|
|
||||||
using var targetFile = File.OpenWrite(targetFilePath);
|
using var targetFile = File.OpenWrite(targetFilePath);
|
||||||
await stream.CopyToAsync(targetFile);
|
await stream.CopyToAsync(targetFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.ListItem.IsInstalled = true;
|
mod.ListItem.IsInstalled = true;
|
||||||
mod.installedFilePath = targetFilePath;
|
mod.installedFilePath = targetFilePath;
|
||||||
mod.ListItem.InstalledVersion = mod.versions[0].modversion;
|
mod.ListItem.InstalledVersion = mod.versions[0].modVersion;
|
||||||
mod.ListItem.InstalledModInfo = mod;
|
mod.ListItem.InstalledModInfo = mod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace VRCMelonAssistant
|
||||||
public class Mod
|
public class Mod
|
||||||
{
|
{
|
||||||
public int _id;
|
public int _id;
|
||||||
public string uploaddate;
|
public string uploadDate;
|
||||||
public string category;
|
public string category;
|
||||||
public string[] aliases;
|
public string[] aliases;
|
||||||
public ModVersion[] versions;
|
public ModVersion[] versions;
|
||||||
|
@ -15,25 +15,27 @@ namespace VRCMelonAssistant
|
||||||
public string installedFilePath;
|
public string installedFilePath;
|
||||||
public string installedVersion;
|
public string installedVersion;
|
||||||
public bool installedInBrokenDir;
|
public bool installedInBrokenDir;
|
||||||
|
public bool installedInRetiredDir;
|
||||||
|
|
||||||
public class ModVersion
|
public class ModVersion
|
||||||
{
|
{
|
||||||
public int _version;
|
public int _version;
|
||||||
public string name;
|
public string name;
|
||||||
public string modversion;
|
public string modVersion;
|
||||||
public string modtype;
|
public string modType;
|
||||||
public string author;
|
public string author;
|
||||||
public string description;
|
public string description;
|
||||||
public string downloadlink;
|
public string downloadLink;
|
||||||
public string sourcelink;
|
public string sourceLink;
|
||||||
public string hash;
|
public string hash;
|
||||||
public string updatedate;
|
public string updateDate;
|
||||||
public string vrchatversion;
|
public string vrchatVersion;
|
||||||
public string loaderversion;
|
public string loaderVersion;
|
||||||
public int approvalStatus;
|
public int approvalStatus;
|
||||||
|
|
||||||
public bool IsBroken => approvalStatus == 2;
|
public bool IsBroken => approvalStatus == 2;
|
||||||
public bool IsPlugin => modtype.Equals("plugin", StringComparison.InvariantCultureIgnoreCase);
|
public bool IsRetired => approvalStatus == 3;
|
||||||
|
public bool IsPlugin => modType.Equals("plugin", StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace VRCMelonAssistant
|
||||||
public class Constants
|
public class Constants
|
||||||
{
|
{
|
||||||
public const string VRChatAppId = "438100";
|
public const string VRChatAppId = "438100";
|
||||||
public const string VRCMGModsJson = "https://api.vrcmg.com/v0/mods.json";
|
public const string VRCMGModsJson = "https://api.vrcmg.com/v1/mods";
|
||||||
public const string WeebCDNAPIURL = "https://pat.assistant.moe/api/v1.0/";
|
public const string WeebCDNAPIURL = "https://pat.assistant.moe/api/v1.0/";
|
||||||
public const string MD5Spacer = " ";
|
public const string MD5Spacer = " ";
|
||||||
public static readonly char[] IllegalCharacters = new char[]
|
public static readonly char[] IllegalCharacters = new char[]
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace VRCMelonAssistant.Libs
|
||||||
new Regex(@"^(?<major>\d+)" +
|
new Regex(@"^(?<major>\d+)" +
|
||||||
@"(?>\.(?<minor>\d+))?" +
|
@"(?>\.(?<minor>\d+))?" +
|
||||||
@"(?>\.(?<patch>\d+))?" +
|
@"(?>\.(?<patch>\d+))?" +
|
||||||
|
@"(?>\.(?<extra>\d+))?" +
|
||||||
@"(?>\-(?<pre>[0-9A-Za-z\-\.]+))?" +
|
@"(?>\-(?<pre>[0-9A-Za-z\-\.]+))?" +
|
||||||
@"(?>\+(?<build>[0-9A-Za-z\-\.]+))?$",
|
@"(?>\+(?<build>[0-9A-Za-z\-\.]+))?$",
|
||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
|
@ -82,11 +83,12 @@ namespace VRCMelonAssistant.Libs
|
||||||
/// <param name="patch">The patch version.</param>
|
/// <param name="patch">The patch version.</param>
|
||||||
/// <param name="prerelease">The prerelease version (e.g. "alpha").</param>
|
/// <param name="prerelease">The prerelease version (e.g. "alpha").</param>
|
||||||
/// <param name="build">The build metadata (e.g. "nightly.232").</param>
|
/// <param name="build">The build metadata (e.g. "nightly.232").</param>
|
||||||
public SemVersion(int major, int minor = 0, int patch = 0, string prerelease = "", string build = "")
|
public SemVersion(int major, int minor = 0, int patch = 0, int extra = 0, string prerelease = "", string build = "")
|
||||||
{
|
{
|
||||||
Major = major;
|
Major = major;
|
||||||
Minor = minor;
|
Minor = minor;
|
||||||
Patch = patch;
|
Patch = patch;
|
||||||
|
Extra = extra;
|
||||||
|
|
||||||
Prerelease = prerelease ?? "";
|
Prerelease = prerelease ?? "";
|
||||||
Build = build ?? "";
|
Build = build ?? "";
|
||||||
|
@ -151,10 +153,17 @@ namespace VRCMelonAssistant.Libs
|
||||||
else if (strict)
|
else if (strict)
|
||||||
throw new InvalidOperationException("Invalid version (no patch version given in strict mode)");
|
throw new InvalidOperationException("Invalid version (no patch version given in strict mode)");
|
||||||
|
|
||||||
|
var extraMatch = match.Groups["extra"];
|
||||||
|
int extra = 0;
|
||||||
|
if (extraMatch.Success)
|
||||||
|
extra = int.Parse(extraMatch.Value, CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
var prerelease = match.Groups["pre"].Value;
|
var prerelease = match.Groups["pre"].Value;
|
||||||
var build = match.Groups["build"].Value;
|
var build = match.Groups["build"].Value;
|
||||||
|
|
||||||
return new SemVersion(major, minor, patch, prerelease, build);
|
|
||||||
|
|
||||||
|
return new SemVersion(major, minor, patch, extra, prerelease, build);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -197,10 +206,18 @@ namespace VRCMelonAssistant.Libs
|
||||||
}
|
}
|
||||||
else if (strict) return false;
|
else if (strict) return false;
|
||||||
|
|
||||||
|
var extraMatch = match.Groups["extra"];
|
||||||
|
int extra = 0;
|
||||||
|
if (extraMatch.Success)
|
||||||
|
{
|
||||||
|
if (!int.TryParse(extraMatch.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out extra))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var prerelease = match.Groups["pre"].Value;
|
var prerelease = match.Groups["pre"].Value;
|
||||||
var build = match.Groups["build"].Value;
|
var build = match.Groups["build"].Value;
|
||||||
|
|
||||||
semver = new SemVersion(major, minor, patch, prerelease, build);
|
semver = new SemVersion(major, minor, patch, extra, prerelease, build);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,13 +265,14 @@ namespace VRCMelonAssistant.Libs
|
||||||
/// To change only the patch version:
|
/// To change only the patch version:
|
||||||
/// <code>version.Change(patch: 4)</code>
|
/// <code>version.Change(patch: 4)</code>
|
||||||
/// </example>
|
/// </example>
|
||||||
public SemVersion Change(int? major = null, int? minor = null, int? patch = null,
|
public SemVersion Change(int? major = null, int? minor = null, int? patch = null, int? extra = null,
|
||||||
string prerelease = null, string build = null)
|
string prerelease = null, string build = null)
|
||||||
{
|
{
|
||||||
return new SemVersion(
|
return new SemVersion(
|
||||||
major ?? Major,
|
major ?? Major,
|
||||||
minor ?? Minor,
|
minor ?? Minor,
|
||||||
patch ?? Patch,
|
patch ?? Patch,
|
||||||
|
extra ?? Extra,
|
||||||
prerelease ?? Prerelease,
|
prerelease ?? Prerelease,
|
||||||
build ?? Build);
|
build ?? Build);
|
||||||
}
|
}
|
||||||
|
@ -283,6 +301,11 @@ namespace VRCMelonAssistant.Libs
|
||||||
/// </value>
|
/// </value>
|
||||||
public int Patch { get; }
|
public int Patch { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the fourth number present in assembly versions
|
||||||
|
/// </summary>
|
||||||
|
public int Extra { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the prerelease version.
|
/// Gets the prerelease version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -316,6 +339,12 @@ namespace VRCMelonAssistant.Libs
|
||||||
version.Append(Minor);
|
version.Append(Minor);
|
||||||
version.Append('.');
|
version.Append('.');
|
||||||
version.Append(Patch);
|
version.Append(Patch);
|
||||||
|
if (Extra != 0)
|
||||||
|
{
|
||||||
|
version.Append('.');
|
||||||
|
version.Append(Extra);
|
||||||
|
}
|
||||||
|
|
||||||
if (Prerelease.Length > 0)
|
if (Prerelease.Length > 0)
|
||||||
{
|
{
|
||||||
version.Append('-');
|
version.Append('-');
|
||||||
|
@ -409,6 +438,9 @@ namespace VRCMelonAssistant.Libs
|
||||||
r = Patch.CompareTo(other.Patch);
|
r = Patch.CompareTo(other.Patch);
|
||||||
if (r != 0) return r;
|
if (r != 0) return r;
|
||||||
|
|
||||||
|
r = Extra.CompareTo(other.Extra);
|
||||||
|
if (r != 0) return r;
|
||||||
|
|
||||||
return CompareComponent(Prerelease, other.Prerelease, true);
|
return CompareComponent(Prerelease, other.Prerelease, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace VRCMelonAssistant
|
||||||
InstallButton.IsEnabled = false;
|
InstallButton.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ShowModsPage()
|
public async Task ShowModsPage()
|
||||||
{
|
{
|
||||||
void OpenModsPage()
|
void OpenModsPage()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Linq;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Documents;
|
using System.Windows.Documents;
|
||||||
|
|
||||||
|
@ -18,29 +18,30 @@ namespace VRCMelonAssistant
|
||||||
ModDescription.Text = mod.versions[0].description ?? (string) FindResource("ModInfoWindow:NoDescription");
|
ModDescription.Text = mod.versions[0].description ?? (string) FindResource("ModInfoWindow:NoDescription");
|
||||||
ModName.Text = mod.versions[0].name;
|
ModName.Text = mod.versions[0].name;
|
||||||
ModAuthor.Text = string.Format((string) FindResource("ModInfoWindow:Author"), mod.versions[0].author ?? FindResource("ModInfoWindow:NoAuthor"));
|
ModAuthor.Text = string.Format((string) FindResource("ModInfoWindow:Author"), mod.versions[0].author ?? FindResource("ModInfoWindow:NoAuthor"));
|
||||||
ModVersion.Text = mod.versions[0].modversion;
|
ModVersion.Text = mod.versions[0].modVersion;
|
||||||
|
|
||||||
var dlLink = mod.versions[0].downloadlink;
|
var dlLink = mod.versions[0].downloadLink;
|
||||||
DownloadLink.Text = (string) FindResource("ModInfoWindow:DownloadLink");
|
DownloadLink.Text = (string) FindResource("ModInfoWindow:DownloadLink");
|
||||||
DownloadLink.Inlines.Add(new Run(" "));
|
DownloadLink.Inlines.Add(new Run(" "));
|
||||||
if (dlLink?.StartsWith("http") == true)
|
if (dlLink?.StartsWith("http") == true)
|
||||||
DownloadLink.Inlines.Add(WrapNavigator(new Hyperlink(new Run(dlLink))));
|
DownloadLink.Inlines.Add(CreateHyperlink(dlLink));
|
||||||
else
|
else
|
||||||
DownloadLink.Inlines.Add(new Run(dlLink));
|
DownloadLink.Inlines.Add(new Run(dlLink));
|
||||||
|
|
||||||
var srcLink = mod.versions[0].sourcelink;
|
var srcLink = mod.versions[0].sourceLink;
|
||||||
SourceCodeLink.Text = (string) FindResource("ModInfoWindow:SourceCodeLink");
|
SourceCodeLink.Text = (string) FindResource("ModInfoWindow:SourceCodeLink");
|
||||||
SourceCodeLink.Inlines.Add(new Run(" "));
|
SourceCodeLink.Inlines.Add(new Run(" "));
|
||||||
if (srcLink?.StartsWith("http") == true)
|
if (srcLink?.StartsWith("http") == true)
|
||||||
SourceCodeLink.Inlines.Add(WrapNavigator(new Hyperlink(new Run(srcLink))));
|
SourceCodeLink.Inlines.Add(CreateHyperlink(srcLink));
|
||||||
else
|
else
|
||||||
SourceCodeLink.Inlines.Add(new Run(srcLink));
|
SourceCodeLink.Inlines.Add(new Run(srcLink));
|
||||||
|
|
||||||
InternalIds.Text = string.Format((string) FindResource("ModInfoWindow:InternalIds"), mod._id, mod.versions[0]._version);
|
InternalIds.Text = string.Format((string) FindResource("ModInfoWindow:InternalIds"), mod._id, mod.versions[0]._version);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Hyperlink WrapNavigator(Hyperlink link)
|
private static Hyperlink CreateHyperlink(string uri)
|
||||||
{
|
{
|
||||||
|
var link = new Hyperlink(new Run(uri)) {NavigateUri = new Uri(uri)};
|
||||||
link.RequestNavigate += HyperlinkExtensions.Hyperlink_RequestNavigate;
|
link.RequestNavigate += HyperlinkExtensions.Hyperlink_RequestNavigate;
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
@ -49,13 +50,33 @@ namespace VRCMelonAssistant.Pages
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HeadPat()
|
private async Task HeadPat()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
PatImage.Load(await WeebCDN("pats"));
|
PatImage.Load(await WeebCDN("pats"));
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
Utils.ShowErrorMessageBox("Oops! Can't get headpats right now!", ex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task Hug()
|
private async Task Hug()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
HugImage.Load(await WeebCDN("hugs"));
|
HugImage.Load(await WeebCDN("hugs"));
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
Utils.ShowErrorMessageBox("Oops! Can't get hugs right now!", ex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,11 @@ namespace VRCMelonAssistant.Pages
|
||||||
MainWindow.Instance.ModsButton.IsEnabled = true;
|
MainWindow.Instance.ModsButton.IsEnabled = true;
|
||||||
|
|
||||||
string text = (string) FindResource("Intro:ModsTabEnabled");
|
string text = (string) FindResource("Intro:ModsTabEnabled");
|
||||||
Utils.SendNotify(text);
|
|
||||||
MainWindow.Instance.MainText = text;
|
MainWindow.Instance.MainText = text;
|
||||||
Properties.Settings.Default.Agreed = true;
|
Properties.Settings.Default.Agreed = true;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
|
|
||||||
|
MainWindow.Instance.ShowModsPage().NoAwait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Name="SearchText"
|
Name="SearchText"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Height="0"
|
Height="20"
|
||||||
Padding="5,0,0,0"
|
Padding="5,0,0,0"
|
||||||
Panel.ZIndex="1"
|
Panel.ZIndex="1"
|
||||||
Background="{DynamicResource BottomStatusBarBackground}"
|
Background="{DynamicResource BottomStatusBarBackground}"
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="SearchBar"
|
Name="SearchBar"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Height="0"
|
Height="20"
|
||||||
Margin="0,-1,0,0"
|
Margin="0,-1,0,0"
|
||||||
Padding="3,1,0,0"
|
Padding="3,1,0,0"
|
||||||
Panel.ZIndex="2"
|
Panel.ZIndex="2"
|
||||||
|
|
|
@ -31,10 +31,11 @@ namespace VRCMelonAssistant.Pages
|
||||||
public static Mods Instance = new Mods();
|
public static Mods Instance = new Mods();
|
||||||
|
|
||||||
private static readonly ModListItem.CategoryInfo BrokenCategory = new("Broken", "These mods were broken by a game update. They will be temporarily removed and restored once they are updated for the current game version");
|
private static readonly ModListItem.CategoryInfo BrokenCategory = new("Broken", "These mods were broken by a game update. They will be temporarily removed and restored once they are updated for the current game version");
|
||||||
|
private static readonly ModListItem.CategoryInfo RetiredCategory = new("Retired", "These mods are either no longer needed due to VRChat updates or are no longer being maintained");
|
||||||
private static readonly ModListItem.CategoryInfo UncategorizedCategory = new("Uncategorized", "Mods without a category assigned");
|
private static readonly ModListItem.CategoryInfo UncategorizedCategory = new("Uncategorized", "Mods without a category assigned");
|
||||||
private static readonly ModListItem.CategoryInfo UnknownCategory = new("Unknown/Unverified", "Mods not coming from VRCMG. Potentially dangerous.");
|
private static readonly ModListItem.CategoryInfo UnknownCategory = new("Unknown/Unverified", "Mods not coming from VRCMG. Potentially dangerous.");
|
||||||
|
|
||||||
public List<string> DefaultMods = new List<string>() { "UI Expansion Kit", "Finitizer", "VRCModUpdater.Loader" };
|
public List<string> DefaultMods = new List<string>() { "UI Expansion Kit", "Finitizer", "VRCModUpdater.Loader", "VRChatUtilityKit", "Final IK Sanity", "ActionMenuApi" };
|
||||||
public Mod[] AllModsList;
|
public Mod[] AllModsList;
|
||||||
public List<Mod> UnknownMods = new List<Mod>();
|
public List<Mod> UnknownMods = new List<Mod>();
|
||||||
public CollectionView view;
|
public CollectionView view;
|
||||||
|
@ -138,10 +139,12 @@ namespace VRCMelonAssistant.Pages
|
||||||
|
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
CheckInstallDir("Plugins", false);
|
CheckInstallDir("Plugins");
|
||||||
CheckInstallDir("Mods", false);
|
CheckInstallDir("Mods");
|
||||||
CheckInstallDir("Plugins/Broken", true);
|
CheckInstallDir("Plugins/Broken", isBrokenDir: true);
|
||||||
CheckInstallDir("Mods/Broken", true);
|
CheckInstallDir("Mods/Broken", isBrokenDir: true);
|
||||||
|
CheckInstallDir("Plugins/Retired", isRetiredDir: true);
|
||||||
|
CheckInstallDir("Mods/Retired", isRetiredDir: true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +171,7 @@ namespace VRCMelonAssistant.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckInstallDir(string directory, bool isBrokenDir)
|
private void CheckInstallDir(string directory, bool isBrokenDir = false, bool isRetiredDir = false)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(Path.Combine(App.VRChatInstallDirectory, directory)))
|
if (!Directory.Exists(Path.Combine(App.VRChatInstallDirectory, directory)))
|
||||||
{
|
{
|
||||||
|
@ -193,6 +196,7 @@ namespace VRCMelonAssistant.Pages
|
||||||
mod.installedFilePath = file;
|
mod.installedFilePath = file;
|
||||||
mod.installedVersion = modInfo.ModVersion;
|
mod.installedVersion = modInfo.ModVersion;
|
||||||
mod.installedInBrokenDir = isBrokenDir;
|
mod.installedInBrokenDir = isBrokenDir;
|
||||||
|
mod.installedInRetiredDir = isRetiredDir;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,12 +207,13 @@ namespace VRCMelonAssistant.Pages
|
||||||
installedFilePath = file,
|
installedFilePath = file,
|
||||||
installedVersion = modInfo.ModVersion,
|
installedVersion = modInfo.ModVersion,
|
||||||
installedInBrokenDir = isBrokenDir,
|
installedInBrokenDir = isBrokenDir,
|
||||||
|
installedInRetiredDir = isRetiredDir,
|
||||||
versions = new []
|
versions = new []
|
||||||
{
|
{
|
||||||
new Mod.ModVersion()
|
new Mod.ModVersion()
|
||||||
{
|
{
|
||||||
name = modInfo.ModName,
|
name = modInfo.ModName,
|
||||||
modversion = modInfo.ModVersion,
|
modVersion = modInfo.ModVersion,
|
||||||
author = modInfo.ModAuthor,
|
author = modInfo.ModAuthor,
|
||||||
description = ""
|
description = ""
|
||||||
}
|
}
|
||||||
|
@ -255,11 +260,17 @@ namespace VRCMelonAssistant.Pages
|
||||||
|
|
||||||
public async Task PopulateModsList()
|
public async Task PopulateModsList()
|
||||||
{
|
{
|
||||||
foreach (Mod mod in AllModsList)
|
foreach (Mod mod in AllModsList.Where(x => !x.versions[0].IsBroken && !x.versions[0].IsRetired))
|
||||||
AddModToList(mod);
|
AddModToList(mod);
|
||||||
|
|
||||||
foreach (var mod in UnknownMods)
|
foreach (var mod in UnknownMods)
|
||||||
AddModToList(mod, UnknownCategory);
|
AddModToList(mod, UnknownCategory);
|
||||||
|
|
||||||
|
foreach (Mod mod in AllModsList.Where(x => x.versions[0].IsBroken))
|
||||||
|
AddModToList(mod);
|
||||||
|
|
||||||
|
foreach (Mod mod in AllModsList.Where(x => x.versions[0].IsRetired))
|
||||||
|
AddModToList(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddModToList(Mod mod, ModListItem.CategoryInfo categoryOverride = null)
|
private void AddModToList(Mod mod, ModListItem.CategoryInfo categoryOverride = null)
|
||||||
|
@ -285,14 +296,14 @@ namespace VRCMelonAssistant.Pages
|
||||||
IsSelected = preSelected,
|
IsSelected = preSelected,
|
||||||
IsEnabled = true,
|
IsEnabled = true,
|
||||||
ModName = latestVersion.name,
|
ModName = latestVersion.name,
|
||||||
ModVersion = latestVersion.modversion,
|
ModVersion = latestVersion.modVersion,
|
||||||
ModAuthor = HardcodedCategories.FixupAuthor(latestVersion.author),
|
ModAuthor = HardcodedCategories.FixupAuthor(latestVersion.author),
|
||||||
ModDescription = latestVersion.description.Replace("\r\n", " ").Replace("\n", " "),
|
ModDescription = latestVersion.description.Replace("\r\n", " ").Replace("\n", " "),
|
||||||
ModInfo = mod,
|
ModInfo = mod,
|
||||||
IsInstalled = mod.installedFilePath != null,
|
IsInstalled = mod.installedFilePath != null,
|
||||||
InstalledVersion = mod.installedVersion,
|
InstalledVersion = mod.installedVersion,
|
||||||
InstalledModInfo = mod,
|
InstalledModInfo = mod,
|
||||||
Category = categoryOverride ?? (latestVersion.IsBroken ? BrokenCategory : GetCategory(mod))
|
Category = categoryOverride ?? (latestVersion.IsBroken ? BrokenCategory : (latestVersion.IsRetired ? RetiredCategory : GetCategory(mod)))
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (Promotion promo in Promotions.ActivePromotions)
|
foreach (Promotion promo in Promotions.ActivePromotions)
|
||||||
|
@ -319,7 +330,7 @@ namespace VRCMelonAssistant.Pages
|
||||||
foreach (Mod mod in AllModsList)
|
foreach (Mod mod in AllModsList)
|
||||||
{
|
{
|
||||||
// Ignore mods that are newer than installed version or up-to-date
|
// Ignore mods that are newer than installed version or up-to-date
|
||||||
if (mod.ListItem.GetVersionComparison >= 0 && mod.installedInBrokenDir == mod.versions[0].IsBroken) continue;
|
if (mod.ListItem.GetVersionComparison >= 0 && mod.installedInBrokenDir == mod.versions[0].IsBroken && mod.installedInRetiredDir == mod.versions[0].IsRetired) continue;
|
||||||
|
|
||||||
if (mod.ListItem.IsSelected)
|
if (mod.ListItem.IsSelected)
|
||||||
{
|
{
|
||||||
|
@ -506,14 +517,14 @@ namespace VRCMelonAssistant.Pages
|
||||||
if (SearchBar.Height == 0)
|
if (SearchBar.Height == 0)
|
||||||
{
|
{
|
||||||
SearchBar.Focus();
|
SearchBar.Focus();
|
||||||
Animate(SearchBar, 0, 16, new TimeSpan(0, 0, 0, 0, 300));
|
Animate(SearchBar, 0, 20, new TimeSpan(0, 0, 0, 0, 300));
|
||||||
Animate(SearchText, 0, 16, new TimeSpan(0, 0, 0, 0, 300));
|
Animate(SearchText, 0, 20, new TimeSpan(0, 0, 0, 0, 300));
|
||||||
ModsListView.Items.Filter = new Predicate<object>(SearchFilter);
|
ModsListView.Items.Filter = new Predicate<object>(SearchFilter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Animate(SearchBar, 16, 0, new TimeSpan(0, 0, 0, 0, 300));
|
Animate(SearchBar, 20, 0, new TimeSpan(0, 0, 0, 0, 300));
|
||||||
Animate(SearchText, 16, 0, new TimeSpan(0, 0, 0, 0, 300));
|
Animate(SearchText, 20, 0, new TimeSpan(0, 0, 0, 0, 300));
|
||||||
ModsListView.Items.Filter = null;
|
ModsListView.Items.Filter = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,8 +88,10 @@ namespace VRCMelonAssistant.Pages
|
||||||
if (resp == System.Windows.Forms.DialogResult.Yes)
|
if (resp == System.Windows.Forms.DialogResult.Yes)
|
||||||
{
|
{
|
||||||
var modsDir = Path.Combine(App.VRChatInstallDirectory, "Mods");
|
var modsDir = Path.Combine(App.VRChatInstallDirectory, "Mods");
|
||||||
|
if (Directory.Exists(modsDir))
|
||||||
Directory.Delete(modsDir, true);
|
Directory.Delete(modsDir, true);
|
||||||
var pluginsDir = Path.Combine(App.VRChatInstallDirectory, "Plugins");
|
var pluginsDir = Path.Combine(App.VRChatInstallDirectory, "Plugins");
|
||||||
|
if (Directory.Exists(pluginsDir))
|
||||||
Directory.Delete(pluginsDir, true);
|
Directory.Delete(pluginsDir, true);
|
||||||
|
|
||||||
Directory.CreateDirectory(modsDir);
|
Directory.CreateDirectory(modsDir);
|
||||||
|
|
|
@ -51,5 +51,5 @@ using System.Windows;
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.1.20.1029")]
|
[assembly: AssemblyVersion("1.1.26.1029")]
|
||||||
[assembly: AssemblyFileVersion("1.1.20.1029+vrc")]
|
[assembly: AssemblyFileVersion("1.1.26.1029+vrc")]
|
||||||
|
|
Loading…
Reference in a new issue