Decompiled source of Flashcard v0.3.3

plugins/Flashcard/me.loaforc.Flashcard.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Flashcard.Config;
using Flashcard.Networking;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MyceliumNetworking;
using Photon.Pun;
using Steamworks;
using Unity.Collections;
using UnityEngine;
using Zorro.Core.Serizalization;
using Zorro.PhotonUtility;
using Zorro.Recorder;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("MyceliumNetworkingForCW")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("me.loaforc.Flashcard")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.3.0")]
[assembly: AssemblyInformationalVersion("0.3.3")]
[assembly: AssemblyProduct("Flashcard")]
[assembly: AssemblyTitle("me.loaforc.Flashcard")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 Flashcard
{
	[BepInPlugin("me.loaforc.Flashcard", "Flashcard", "0.3.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class FlashcardPlugin : BaseUnityPlugin
	{
		internal static uint networkID = 102873u;

		public static FlashcardPlugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony Harmony { get; private set; }

		internal static FlashcardConfig config { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Logger.LogInfo((object)"Initing Config.");
			config = new FlashcardConfig(((BaseUnityPlugin)this).Config);
			Logger.LogInfo((object)"Running Harmony Patches");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "me.loaforc.Flashcard");
			Logger.LogInfo((object)"Setting up FlashcardVideoUploader");
			new FlashcardVideoUploader();
			Logger.LogInfo((object)"me.loaforc.Flashcard:0.3.3 has loaded!");
			LogVerbose("Awake", "Flashcard loaded with verbose logging!");
		}

		internal static void LogVerbose(string origin, string message)
		{
			if (config.DEBUGGING_VERBOSE_LOGGING.Value)
			{
				Logger.LogInfo((object)("[" + origin + "] " + message));
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "me.loaforc.Flashcard";

		public const string PLUGIN_NAME = "Flashcard";

		public const string PLUGIN_VERSION = "0.3.3";
	}
}
namespace Flashcard.Patches
{
	[HarmonyPatch(typeof(FfmpegEncoder))]
	internal static class FFmpegEncoderPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Encode")]
		private static void UpdateEncoderFramerate(ref byte framerate)
		{
			framerate = (byte)FlashcardPlugin.config.RECORDING_CLIP_FRAMERATE.Value;
		}

		[HarmonyPrefix]
		[HarmonyPatch("RunFfmpeg")]
		private static void UpdateQualityPreset(ref string arguments)
		{
			if (!(FlashcardPlugin.config.RECORDING_CLIP_QUALITY.Value == ""))
			{
				string text = FlashcardPlugin.config.RECORDING_CLIP_QUALITY.Value.ToLower();
				if (text.Contains("-") || text.Contains(" "))
				{
					FlashcardPlugin.Logger.LogError((object)("Invalid clip quality: " + text));
				}
				if (!text.EndsWith("k") && !text.EndsWith("m"))
				{
					FlashcardPlugin.Logger.LogError((object)("Invalid clip quality: " + text));
				}
				if (int.TryParse(text.Replace("k", ""), out var result))
				{
					arguments = arguments.Replace("-preset ultrafast", $"-preset ultrafast -b:v {result}k");
					FlashcardPlugin.Logger.LogInfo((object)"Updated Ffmpeg arguments");
				}
				else if (int.TryParse(text.Replace("m", ""), out result))
				{
					arguments = arguments.Replace("-preset ultrafast", $"-preset ultrafast -b:v {result}M");
					FlashcardPlugin.Logger.LogInfo((object)"Updated Ffmpeg arguments");
				}
				else
				{
					FlashcardPlugin.Logger.LogError((object)("Failed to parse clip quality as integer: " + text));
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhotonSendVideoHandler))]
	internal class PhotonSendVideoHandlerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("SendVideoThroughPhoton")]
		internal static void ReallyReallyForceVideoSharingOverSteamNetwork(PhotonSendVideoHandler __instance, ref bool isReRequest)
		{
			isReRequest = false;
			__instance.m_UseSteamNetwork = true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("RecieveClipChunk")]
		internal static void LogRecieveClipChunk(SendVideoChunkPackage package)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			FlashcardPlugin.LogVerbose("RecieveClipChunk", $"Recieved a chunk of a video! Chunk '{package.ChunkIndex}' for clip '{package.ClipID}'");
		}

		[HarmonyPostfix]
		[HarmonyPatch("SendVideoChunks")]
		internal static void FlashcardSendVideoChunks(ref IEnumerator __result, List<byte[]> videoChunks, ClipID clipID, VideoHandle videoID, ContentBuffer contentBuffer, bool isReRequest)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			__result = FlashcardVideoUploader.Instance.SendVideoChunks(videoChunks, clipID, videoID, contentBuffer, isReRequest);
		}
	}
	[HarmonyPatch(typeof(RecordingsHandler))]
	internal static class RecordingHandlerPatch
	{
		[HarmonyPatch("StartRecording")]
		[HarmonyPostfix]
		private static void LogStartRecording()
		{
			FlashcardPlugin.LogVerbose("RecordingHandlerPatch", "RecordingsHandler.StartRecording!!!");
		}
	}
	[HarmonyPatch(typeof(SurfaceNetworkHandler))]
	internal static class SurfaceNetworkHandlerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("InitSurface")]
		internal static void SpawnOnStartRun()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				SpawnExtraCamera();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnSlept")]
		internal static void SpawnOnNewDay()
		{
			if (PhotonNetwork.IsMasterClient && Object.FindObjectsOfType<VideoCamera>().Length < 2)
			{
				SpawnExtraCamera();
			}
		}

		private static void SpawnExtraCamera()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			if (PhotonNetwork.IsMasterClient && !(FlashcardPlugin.config.UPGRADES_EXTRA_CAMERA.Value == "disabled"))
			{
				FlashcardPlugin.Logger.LogInfo((object)"Spawning extra camera!");
				PickupHandler.CreatePickup((byte)1, new ItemInstanceData(Guid.NewGuid()), new Vector3(-14.842f, 2.418f, 8.776f), Quaternion.Euler(0f, -67.18f, 0f));
			}
		}
	}
	[HarmonyPatch(typeof(VideoCamera))]
	public class VideoCameraPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch("ConfigItem")]
		private static IEnumerable<CodeInstruction> UpdateFilmAmount(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_002b: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)90f, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(VideoInfoEntry), "timeLeft"), (string)null)
			}).SetOperandAndAdvance((object)FlashcardPlugin.config.RECORDING_CLIP_LENGTH.Value).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)90f, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(VideoInfoEntry), "maxTime"), (string)null)
			})
				.SetOperandAndAdvance((object)FlashcardPlugin.config.RECORDING_CLIP_LENGTH.Value)
				.InstructionEnumeration();
		}

		[HarmonyTranspiler]
		[HarmonyPatch("StartRecording")]
		private static IEnumerable<CodeInstruction> UpdateVideoResolution(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(VideoRecorder), "frameRate"), (string)null)
			}).SetOperandAndAdvance((object)FlashcardPlugin.config.RECORDING_CLIP_FRAMERATE.Value).InstructionEnumeration();
		}
	}
}
namespace Flashcard.Networking
{
	internal class FlashcardVideoUploader
	{
		internal static FlashcardVideoUploader Instance;

		private uint NetworkID => FlashcardPlugin.networkID;

		internal FlashcardVideoUploader()
		{
			MyceliumNetwork.RegisterNetworkObject((object)this, NetworkID, 0);
			Instance = this;
		}

		internal IEnumerator SendVideoChunks(List<byte[]> videoChunks, ClipID clipID, VideoHandle videoID, ContentBuffer contentBuffer, bool isReRequest)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			FlashcardPlugin.LogVerbose("Uploading", $"Sending Video Chunks! VideoID: {clipID.id}");
			for (ushort chunkIndex = 0; chunkIndex < videoChunks.Count; chunkIndex++)
			{
				byte[] videoChunkData = videoChunks[chunkIndex];
				SendVideoChunkPackage val = new SendVideoChunkPackage
				{
					ChunkCount = (ushort)videoChunks.Count,
					VideoChunkData = videoChunkData,
					ChunkIndex = chunkIndex,
					VideoHandle = videoID,
					ClipID = clipID
				};
				if (chunkIndex == 0)
				{
					BinarySerializer val2 = new BinarySerializer(512, (Allocator)4);
					contentBuffer.Serialize(val2);
					val.ContentEventData = val2.buffer;
				}
				NativeArray<byte> buffer = ((CustomCommandPackage<CustomCommandType>)(object)val).Serialize().buffer;
				byte[] array = new byte[buffer.Length];
				ByteArrayConvertion.MoveToByteArray<byte>(ref buffer, ref array);
				buffer.Dispose();
				for (int i = 0; i < MyceliumNetwork.Players.Length; i++)
				{
					if (!(MyceliumNetwork.Players[i] == SteamUser.GetSteamID()))
					{
						MyceliumNetwork.RPCTarget(NetworkID, "RPC_RecieveChunk", MyceliumNetwork.Players[i], (ReliableType)1, new object[1] { array });
					}
				}
				FlashcardPlugin.LogVerbose("Uploading", $"Uploaded a chunk! VideoID: {clipID.id}, chunkIndex: {chunkIndex}");
				yield return (object)new WaitForSeconds(FlashcardPlugin.config.UPLOADING_DELAY_BETWEEN_PACKETS.Value);
			}
		}

		[CustomRPC]
		private void RPC_RecieveChunk(byte[] data)
		{
			//IL_0024: 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_002b: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			FlashcardPlugin.LogVerbose("Uploading", "Recieved Video Chunk! Deserializing and giving it back to PhotonSendVideoHandler.");
			NativeArray<byte> val = default(NativeArray<byte>);
			val..ctor(data.Length, (Allocator)2, (NativeArrayOptions)1);
			ByteArrayConvertion.MoveFromByteArray<byte>(ref data, ref val);
			BinaryDeserializer val2 = new BinaryDeserializer(val);
			SendVideoChunkPackage val3 = new SendVideoChunkPackage();
			((CustomCommandPackage<CustomCommandType>)(object)val3).DeserializeData(val2);
			val2.Dispose();
			RetrievableSingleton<PhotonSendVideoHandler>.Instance.RecieveClipChunk(val3);
		}
	}
}
namespace Flashcard.Config
{
	internal class FlashcardConfig
	{
		internal ConfigEntry<string> UPGRADES_EXTRA_CAMERA;

		internal ConfigEntry<float> RECORDING_CLIP_LENGTH;

		internal ConfigEntry<int> RECORDING_CLIP_FRAMERATE;

		internal ConfigEntry<string> RECORDING_CLIP_QUALITY;

		internal ConfigEntry<int> UPLOADING_PACKET_SIZE;

		internal ConfigEntry<float> UPLOADING_DELAY_BETWEEN_PACKETS;

		internal ConfigEntry<bool> DEBUGGING_VERBOSE_LOGGING;

		internal FlashcardConfig(ConfigFile cfgFile)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			UPGRADES_EXTRA_CAMERA = cfgFile.Bind<string>("Upgrades", "ExtraCamera", "disabled", new ConfigDescription("Should allow the Extra Camera Upgrade?", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "disabled", "always" }), Array.Empty<object>()));
			RECORDING_CLIP_LENGTH = cfgFile.Bind<float>("Recording", "ClipLength", 120f, "How many seconds should the camera be allowed to record?" + Environment.NewLine + "ContentWarning's default is 90.");
			RECORDING_CLIP_FRAMERATE = cfgFile.Bind<int>("Recording", "ClipFramerate", 24, "What framerate should the camera record at? Might cause issues extracting if not everybody is at the same framereate.\nIt's not recommended to set this above 30, doing so will lead to crazy sizes.");
			RECORDING_CLIP_QUALITY = cfgFile.Bind<string>("Recording", "ClipQuality", "512k", "What bitrate should the video get encoded in?\nThis drastically effects the file quality. Vanilla videos are about 4mb in size after completion, Flashcard defaults can increase it to about 8mb.\nSet to empty to disable change the quality.\nAnything above 2000k/2M is excessive and shouldn't be used.");
			UPLOADING_DELAY_BETWEEN_PACKETS = cfgFile.Bind<float>("Uploading", "DelayBetweenPackets", 0.5f, "The delay between the packets for video chunk data being sent.");
			DEBUGGING_VERBOSE_LOGGING = cfgFile.Bind<bool>("Debugging", "VerboseLogging", false, "Whether flashcard should increase it's logs. Useful for debugging issues.");
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}