|
| 1 | +using HarmonyLib; |
| 2 | +using ResoniteModLoader; |
| 3 | +using FrooxEngine; |
| 4 | +using SkyFrost.Base; |
| 5 | +using System; |
| 6 | +using System.Reflection; |
| 7 | + |
| 8 | +namespace FckSessionCapture; |
| 9 | + |
| 10 | +public class FckSessionCapture : ResoniteMod { |
| 11 | + public override string Name => "FckSessionCapture"; |
| 12 | + public override string Author => "NalaTheThird"; |
| 13 | + public override string Version => "1.0.1"; |
| 14 | + public override string Link => "https://github.com/nalathethird/FckSessionCapture"; |
| 15 | + |
| 16 | + [AutoRegisterConfigKey] |
| 17 | + private static readonly ModConfigurationKey<bool> enabled = |
| 18 | + new ModConfigurationKey<bool>("enabled", "Enable FckSessionCapture mod", () => true); |
| 19 | + |
| 20 | + [AutoRegisterConfigKey] |
| 21 | + private static readonly ModConfigurationKey<bool> captureInPrivate = |
| 22 | + new ModConfigurationKey<bool>("capture_in_private_session", "Allow capture in private sessions", () => false); |
| 23 | + |
| 24 | + [AutoRegisterConfigKey] |
| 25 | + private static readonly ModConfigurationKey<bool> captureInContactsOnly = |
| 26 | + new ModConfigurationKey<bool>("capture_in_contactsonly_session", "Allow capture in contacts-only sessions", () => false); |
| 27 | + |
| 28 | + [AutoRegisterConfigKey] |
| 29 | + private static readonly ModConfigurationKey<bool> captureInContactsPlus = |
| 30 | + new ModConfigurationKey<bool>("capture_in_contactsplus_session", "Allow capture in contacts+ sessions", () => false); |
| 31 | + |
| 32 | + [AutoRegisterConfigKey] |
| 33 | + private static readonly ModConfigurationKey<bool> captureInRegisteredUsers = |
| 34 | + new ModConfigurationKey<bool>("capture_in_registeredusers_session", "Allow capture in registered users sessions", () => false); |
| 35 | + |
| 36 | + [AutoRegisterConfigKey] |
| 37 | + private static readonly ModConfigurationKey<bool> captureInLAN = |
| 38 | + new ModConfigurationKey<bool>("capture_in_lan_session", "Allow capture in LAN (local network) sessions", () => false); |
| 39 | + |
| 40 | + [AutoRegisterConfigKey] |
| 41 | + private static readonly ModConfigurationKey<bool> captureInPublic = |
| 42 | + new ModConfigurationKey<bool>("capture_in_public_session", "Allow capture in public sessions (Anyone)", () => false); |
| 43 | + |
| 44 | + [AutoRegisterConfigKey] |
| 45 | + private static readonly ModConfigurationKey<bool> captureLocal = |
| 46 | + new ModConfigurationKey<bool>( |
| 47 | + "capture_local_session", |
| 48 | + "Allow local session capture (only visible to people inside the session; block to maximize privacy).", |
| 49 | + () => true |
| 50 | + ); |
| 51 | + |
| 52 | + private static ModConfiguration Config; |
| 53 | + |
| 54 | + public override void OnEngineInit() { |
| 55 | + Msg("FckSessionCapture: OnEngineInit called."); |
| 56 | + Config = GetConfiguration(); |
| 57 | + Config.Save(true); |
| 58 | + |
| 59 | + var harmony = new Harmony("com.nalathethird.fcksessioncapture"); |
| 60 | + harmony.PatchAll(); |
| 61 | + Msg("FckSessionCapture: Harmony patches applied."); |
| 62 | + } |
| 63 | + |
| 64 | + [HarmonyPatch(typeof(SessionThumbnailData), "StartUpload")] |
| 65 | + class SessionThumbnailData_StartUpload_Patch { |
| 66 | + static bool Prefix(SessionThumbnailData __instance) { |
| 67 | + Msg("FckSessionCapture: StartUpload Prefix entered."); |
| 68 | + |
| 69 | + if (Config == null) { |
| 70 | + Error("FckSessionCapture: Config is null! Allowing upload."); |
| 71 | + return true; |
| 72 | + } |
| 73 | + |
| 74 | + bool modEnabled = Config.GetValue(enabled); |
| 75 | + bool allowPrivate = Config.GetValue(captureInPrivate); |
| 76 | + bool allowContacts = Config.GetValue(captureInContactsOnly); |
| 77 | + bool allowContactsPlus = Config.GetValue(captureInContactsPlus); |
| 78 | + bool allowRegisteredUsers = Config.GetValue(captureInRegisteredUsers); |
| 79 | + bool allowLAN = Config.GetValue(captureInLAN); |
| 80 | + bool allowPublic = Config.GetValue(captureInPublic); |
| 81 | + bool allowLocal = Config.GetValue(captureLocal); |
| 82 | + |
| 83 | + Msg($"FckSessionCapture: Config - enabled={modEnabled}, private={allowPrivate}, contacts={allowContacts}, contactsPlus={allowContactsPlus}, registeredUsers={allowRegisteredUsers}, lan={allowLAN}, public={allowPublic}, local={allowLocal}"); |
| 84 | + |
| 85 | + if (!modEnabled) { |
| 86 | + Msg("FckSessionCapture: Mod is disabled, allowing upload."); |
| 87 | + return true; |
| 88 | + } |
| 89 | + |
| 90 | + var world = __instance.World; |
| 91 | + if (world == null) { |
| 92 | + Error("FckSessionCapture: __instance.World is null! Allowing upload."); |
| 93 | + return true; |
| 94 | + } |
| 95 | + |
| 96 | + // Only block user's active session |
| 97 | + if (world.Focus != World.WorldFocus.Focused) { |
| 98 | + Msg($"FckSessionCapture: World '{world.Name}' is not focused (Focus={world.Focus}), allowing upload."); |
| 99 | + return true; |
| 100 | + } |
| 101 | + |
| 102 | + var accessLevel = world.AccessLevel; |
| 103 | + Msg($"FckSessionCapture: World '{world.Name}' (AccessLevel={accessLevel}, Focused={world.Focus == World.WorldFocus.Focused})"); |
| 104 | + |
| 105 | + // Block or allow based on session type and config |
| 106 | + switch (accessLevel) { |
| 107 | + case SessionAccessLevel.Private: |
| 108 | + if (!allowPrivate) { |
| 109 | + Warn("Blocked session thumbnail upload in private session."); |
| 110 | + if (!allowLocal) { |
| 111 | + Warn("Also blocking local session capture in private session."); |
| 112 | + __instance.InvalidateThumbnail(); |
| 113 | + } |
| 114 | + return false; |
| 115 | + } |
| 116 | + break; |
| 117 | + case SessionAccessLevel.Contacts: |
| 118 | + if (!allowContacts) { |
| 119 | + Warn("Blocked session thumbnail upload in contacts-only session."); |
| 120 | + if (!allowLocal) { |
| 121 | + Warn("Also blocking local session capture in contacts-only session."); |
| 122 | + __instance.InvalidateThumbnail(); |
| 123 | + } |
| 124 | + return false; |
| 125 | + } |
| 126 | + break; |
| 127 | + case SessionAccessLevel.ContactsPlus: |
| 128 | + if (!allowContactsPlus) { |
| 129 | + Warn("Blocked session thumbnail upload in contacts+ session."); |
| 130 | + if (!allowLocal) { |
| 131 | + Warn("Also blocking local session capture in contacts+ session."); |
| 132 | + __instance.InvalidateThumbnail(); |
| 133 | + } |
| 134 | + return false; |
| 135 | + } |
| 136 | + break; |
| 137 | + case SessionAccessLevel.RegisteredUsers: |
| 138 | + if (!allowRegisteredUsers) { |
| 139 | + Warn("Blocked session thumbnail upload in registered users session."); |
| 140 | + if (!allowLocal) { |
| 141 | + Warn("Also blocking local session capture in registered users session."); |
| 142 | + __instance.InvalidateThumbnail(); |
| 143 | + } |
| 144 | + return false; |
| 145 | + } |
| 146 | + break; |
| 147 | + case SessionAccessLevel.LAN: |
| 148 | + if (!allowLAN) { |
| 149 | + Warn("Blocked session thumbnail upload in LAN session."); |
| 150 | + if (!allowLocal) { |
| 151 | + Warn("Also blocking local session capture in LAN session."); |
| 152 | + __instance.InvalidateThumbnail(); |
| 153 | + } |
| 154 | + return false; |
| 155 | + } |
| 156 | + break; |
| 157 | + case SessionAccessLevel.Anyone: |
| 158 | + if (!allowPublic) { |
| 159 | + Warn("Blocked session thumbnail upload in public (Anyone) session."); |
| 160 | + if (!allowLocal) { |
| 161 | + Warn("Also blocking local session capture in public session."); |
| 162 | + __instance.InvalidateThumbnail(); |
| 163 | + } |
| 164 | + return false; |
| 165 | + } |
| 166 | + break; |
| 167 | + default: |
| 168 | + Msg("FckSessionCapture: Unknown session type, allowing upload."); |
| 169 | + break; |
| 170 | + } |
| 171 | + |
| 172 | + // If upload is allowed, but local capture is not, clear the local thumbnail |
| 173 | + if (!allowLocal) { |
| 174 | + Warn("Blocking local session capture (even though upload is allowed)."); |
| 175 | + __instance.InvalidateThumbnail(); |
| 176 | + } |
| 177 | + |
| 178 | + Msg("FckSessionCapture: StartUpload Prefix exiting, allowing upload."); |
| 179 | + return true; |
| 180 | + } |
| 181 | + } |
| 182 | +} |
0 commit comments