Decompiled source of CloudSyncGraphicsFix v1.0.0

BepInEx/plugins/CloudSyncGraphicsFix/CloudSyncGraphicsFix.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RoR2;
using RoR2.ConVar;
using UnityEngine;
using Zio;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Xander Frangos")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CloudSyncGraphicsFix")]
[assembly: AssemblyTitle("CloudSyncGraphicsFix")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CloudSyncGraphicsFix
{
	[BepInPlugin("xanderfrangos.cloudsyncgraphicsfix", "Cloud Sync Graphics Fix", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal const string Guid = "xanderfrangos.cloudsyncgraphicsfix";

		internal const string Version = "1.0.0";

		private const string DefaultDeviceConVars = "resolution, window_mode, vsync_count, fps_max, resolution_scale, r_shadows, r_softparticles, r_foliagewind, r_lod_bias, r_lod_max, master_texture_limit, anisotropic_filtering, shadow_resolution, shadow_cascades, shadow_distance, pp_aa, pp_motionblur, pp_sobel_outline, pp_bloom, pp_ao, pp_screendistortion, gamma, hud_scale, vfxbudget_particle_cost_bias, corpses_max, corpses_disposal";

		private static ConfigEntry<string> extraDeviceConVars;

		private static ConfigEntry<string> syncedConVars;

		private static ManualLogSource log;

		private static string DeviceFilePath => Path.Combine(Application.dataPath, "Config", "cloudsyncgraphicsfix.device.cfg");

		private void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			log = ((BaseUnityPlugin)this).Logger;
			extraDeviceConVars = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ExtraDeviceConVars", "", "Comma-separated console variables to keep per device in addition to the built-in list: resolution, window_mode, vsync_count, fps_max, resolution_scale, r_shadows, r_softparticles, r_foliagewind, r_lod_bias, r_lod_max, master_texture_limit, anisotropic_filtering, shadow_resolution, shadow_cascades, shadow_distance, pp_aa, pp_motionblur, pp_sobel_outline, pp_bloom, pp_ao, pp_screendistortion, gamma, hud_scale, vfxbudget_particle_cost_bias, corpses_max, corpses_disposal");
			syncedConVars = ((BaseUnityPlugin)this).Config.Bind<string>("General", "SyncedConVars", "", "Comma-separated console variables from the built-in list to keep syncing through Steam Cloud instead.");
			try
			{
				Harmony val = new Harmony("xanderfrangos.cloudsyncgraphicsfix");
				val.Patch((MethodBase)AccessTools.Method(typeof(Console), "LoadUserConfigFile", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "LoadUserConfigFilePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)AccessTools.Method(typeof(Console), "SaveArchiveConVars", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "SaveArchiveConVarsPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex)
			{
				log.LogError((object)("Patching failed; graphics settings will sync as usual. " + ex));
			}
		}

		private static bool LoadUserConfigFilePrefix(string path)
		{
			string text;
			try
			{
				text = ReadText((IFileSystem)(object)RoR2Application.cloudStorage, path);
				if (text == null)
				{
					return true;
				}
				if (!File.Exists(DeviceFilePath))
				{
					SaveDeviceFile();
				}
			}
			catch (Exception ex)
			{
				log.LogError((object)("Reading device settings failed; loading the cloud config unchanged. " + ex));
				return true;
			}
			Console.instance.SubmitCmd((NetworkUser)null, RemoveDeviceConVars(text), false);
			ApplyDeviceFile();
			return false;
		}

		private static void SaveArchiveConVarsPostfix()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SaveDeviceFile();
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				UserProfile val = ((firstLocalUser != null) ? firstLocalUser.userProfile : null);
				if (val == null)
				{
					return;
				}
				string text = ((object)(UPathExtensions.GetDirectory(val.filePath) / UPath.op_Implicit("config.cfg"))/*cast due to .constrained prefix*/).ToString();
				string text2 = ReadText((IFileSystem)(object)RoR2Application.cloudStorage, text);
				if (text2 == null)
				{
					return;
				}
				using Stream stream = RoR2Application.cloudStorage.OpenFile(UPath.op_Implicit(text), FileMode.Create, FileAccess.Write, FileShare.None);
				if (stream == null)
				{
					return;
				}
				using StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8);
				streamWriter.Write(RemoveDeviceConVars(text2));
			}
			catch (Exception ex)
			{
				log.LogError((object)("Saving device settings failed. " + ex));
			}
		}

		private static void SaveDeviceFile()
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (string item in DeviceConVarNames())
			{
				BaseConVar val = Console.instance.FindConVar(item);
				if (val != null)
				{
					stringBuilder.Append(item).Append(' ').Append(val.GetString())
						.Append(";\r\n");
				}
			}
			string text = DeviceFilePath + ".tmp";
			Directory.CreateDirectory(Path.GetDirectoryName(DeviceFilePath));
			File.WriteAllText(text, stringBuilder.ToString());
			if (File.Exists(DeviceFilePath))
			{
				File.Replace(text, DeviceFilePath, null);
			}
			else
			{
				File.Move(text, DeviceFilePath);
			}
		}

		private static void ApplyDeviceFile()
		{
			if (!File.Exists(DeviceFilePath))
			{
				return;
			}
			HashSet<string> hashSet = DeviceConVarNames();
			foreach (string item in Statements(File.ReadAllText(DeviceFilePath)))
			{
				string text = NameOf(item);
				BaseConVar val = (hashSet.Contains(text) ? Console.instance.FindConVar(text) : null);
				if (val == null)
				{
					continue;
				}
				string text2 = item.Substring(text.Length).Trim().Trim('"');
				try
				{
					if (val.GetString() != text2)
					{
						val.SetString(text2);
					}
				}
				catch (Exception ex)
				{
					log.LogWarning((object)("Could not apply " + text + " " + text2 + ": " + ex.Message));
				}
			}
		}

		private static string RemoveDeviceConVars(string text)
		{
			HashSet<string> names = DeviceConVarNames();
			return string.Concat(from s in Statements(text)
				where !names.Contains(NameOf(s))
				select s + ";\r\n");
		}

		private static HashSet<string> DeviceConVarNames()
		{
			HashSet<string> hashSet = ParseNames("resolution, window_mode, vsync_count, fps_max, resolution_scale, r_shadows, r_softparticles, r_foliagewind, r_lod_bias, r_lod_max, master_texture_limit, anisotropic_filtering, shadow_resolution, shadow_cascades, shadow_distance, pp_aa, pp_motionblur, pp_sobel_outline, pp_bloom, pp_ao, pp_screendistortion, gamma, hud_scale, vfxbudget_particle_cost_bias, corpses_max, corpses_disposal");
			hashSet.UnionWith(ParseNames(extraDeviceConVars.Value));
			hashSet.ExceptWith(ParseNames(syncedConVars.Value));
			return hashSet;
		}

		private static HashSet<string> ParseNames(string list)
		{
			return new HashSet<string>(from n in list.Split(',')
				select n.Trim().ToLowerInvariant() into n
				where n.Length > 0
				select n);
		}

		private static string NameOf(string statement)
		{
			int i;
			for (i = 0; i < statement.Length && !char.IsWhiteSpace(statement[i]); i++)
			{
			}
			return statement.Substring(0, i).ToLowerInvariant();
		}

		private static IEnumerable<string> Statements(string text)
		{
			StringBuilder current = new StringBuilder();
			bool quoted = false;
			string text2 = text + "\n";
			foreach (char c in text2)
			{
				if (c == '"')
				{
					quoted = !quoted;
				}
				if (quoted || (c != ';' && c != '\n' && c != '\r'))
				{
					current.Append(c);
					continue;
				}
				string text3 = current.ToString().Trim();
				current.Clear();
				if (text3.Length > 0)
				{
					yield return text3;
				}
			}
		}

		private static string ReadText(IFileSystem fileSystem, string path)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (fileSystem == null)
			{
				return null;
			}
			using Stream stream = fileSystem.OpenFile(UPath.op_Implicit(path), FileMode.Open, FileAccess.Read, FileShare.None);
			if (stream == null)
			{
				return null;
			}
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}
	}
}