using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.DroneTech.Weapon;
using Microsoft.CodeAnalysis;
using On;
using On.EntityStates.DroneTech.Weapon;
using OperatorQueueControl.Core;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;
[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("OperatorQueueControl")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e72b8852648bfaa0e251c764feeb4ce094d6f6d5")]
[assembly: AssemblyProduct("OperatorQueueControl")]
[assembly: AssemblyTitle("OperatorQueueControl")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 OperatorQueueControl
{
internal static class Log
{
private static ManualLogSource _logSource;
internal static void Init(ManualLogSource logSource)
{
_logSource = logSource;
}
[Conditional("DEBUG")]
internal static void Info(object data)
{
ManualLogSource logSource = _logSource;
if (logSource != null)
{
logSource.LogInfo(data);
}
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("shay.OperatorQueueControl", "Operator Queue Control", "1.4.0")]
public sealed class OperatorQueueControlPlugin : BaseUnityPlugin
{
private enum DroneControlActionType : byte
{
Skip = 1,
ToggleLock
}
private readonly struct ActionResult
{
public bool Success { get; }
public string Message { get; }
private ActionResult(bool success, string message)
{
Success = success;
Message = message;
}
public static ActionResult SuccessResult(string message)
{
return new ActionResult(success: true, message);
}
public static ActionResult Failure(string message)
{
return new ActionResult(success: false, message);
}
}
private sealed class DroneControlRequestMessage : MessageBase
{
public byte Action;
public NetworkInstanceId BodyNetId;
public override void Serialize(NetworkWriter writer)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
writer.Write(Action);
writer.Write(BodyNetId);
}
public override void Deserialize(NetworkReader reader)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
Action = reader.ReadByte();
BodyNetId = reader.ReadNetworkId();
}
}
private sealed class DroneControlResponseMessage : MessageBase
{
public bool Success;
public string Message = string.Empty;
public override void Serialize(NetworkWriter writer)
{
writer.Write(Success);
writer.Write(Message ?? string.Empty);
}
public override void Deserialize(NetworkReader reader)
{
Success = reader.ReadBoolean();
Message = reader.ReadString();
}
public static DroneControlResponseMessage Create(bool success, string message)
{
return new DroneControlResponseMessage
{
Success = success,
Message = (message ?? string.Empty)
};
}
}
public const string PluginAuthor = "shay";
public const string PluginId = "OperatorQueueControl";
public const string PluginDisplayName = "Operator Queue Control";
public const string PluginGUID = "shay.OperatorQueueControl";
public const string PluginVersion = "1.4.0";
private const string OperatorBodyName = "DroneTechBody";
private const string RiskOfOptionsGuid = "com.rune580.riskofoptions";
private const short DroneControlRequestMessageType = 32001;
private const short DroneControlResponseMessageType = 32002;
private const DroneControlInputMode InputMode = 1;
private static readonly FieldInfo DroneTechUiField = typeof(DroneTechController).GetField("UI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private readonly DroneQueueEngine _queueEngine = new DroneQueueEngine();
private ConfigEntry<bool> _enableSkipKeybind;
private ConfigEntry<KeyboardShortcut> _skipKeybind;
private ConfigEntry<bool> _enableLockKeybind;
private ConfigEntry<KeyboardShortcut> _lockToggleKeybind;
private ConfigEntry<bool> _showFeedback;
private readonly Dictionary<int, DroneLockState> _lockStatesByController = new Dictionary<int, DroneLockState>();
private readonly HashSet<int> _controllersInAdminOverride = new HashSet<int>();
private bool _serverRequestHandlerRegistered;
private bool _clientResponseHandlerRegistered;
private void Awake()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
Log.Init(((BaseUnityPlugin)this).Logger);
BindConfig();
RegisterRiskOfOptions();
DroneTechController.ReturnDrone += new hook_ReturnDrone(DroneTechController_ReturnDrone);
Activate.OnEnter += new hook_OnEnter(Activate_OnEnter);
Run.onRunStartGlobal += OnRunStartGlobal;
Run.onRunDestroyGlobal += OnRunDestroyGlobal;
}
private void OnDestroy()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
DroneTechController.ReturnDrone -= new hook_ReturnDrone(DroneTechController_ReturnDrone);
Activate.OnEnter -= new hook_OnEnter(Activate_OnEnter);
Run.onRunStartGlobal -= OnRunStartGlobal;
Run.onRunDestroyGlobal -= OnRunDestroyGlobal;
}
private void Update()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
EnsureNetworkHandlersRegistered();
if (_enableLockKeybind.Value && IsShortcutPressed(_lockToggleKeybind.Value))
{
ToggleDroneLock();
}
if (_enableSkipKeybind.Value && IsShortcutPressed(_skipKeybind.Value))
{
TrySkipCurrentDrone();
}
MaintainLockedCurrentDrone();
}
private void TrySkipCurrentDrone()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if (!TryGetLocalOperatorController(out var controller, out var reason))
{
Feedback(reason);
return;
}
DroneControlInputDecision val = DroneControlAuthorityPolicy.Evaluate((DroneControlInputMode)1, NetworkServer.active, NetworkClient.active);
if ((int)val.Route == 2)
{
if (!TrySendClientActionRequest(controller, DroneControlActionType.Skip, out var reason2))
{
Feedback(reason2);
}
return;
}
if ((int)val.Route == 0)
{
Feedback(val.Message);
return;
}
ActionResult actionResult = ApplySkipToController(controller, feedbackRequested: true);
if (!actionResult.Success && !string.IsNullOrWhiteSpace(actionResult.Message))
{
Feedback(actionResult.Message);
}
}
private void ToggleDroneLock()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if (!TryGetLocalOperatorController(out var controller, out var reason))
{
Feedback(reason);
return;
}
DroneControlInputDecision val = DroneControlAuthorityPolicy.Evaluate((DroneControlInputMode)1, NetworkServer.active, NetworkClient.active);
if ((int)val.Route == 2)
{
if (!TrySendClientActionRequest(controller, DroneControlActionType.ToggleLock, out var reason2))
{
Feedback(reason2);
}
return;
}
if ((int)val.Route == 0)
{
Feedback(val.Message);
return;
}
ActionResult actionResult = ApplyToggleLockToController(controller, feedbackRequested: true);
if (!actionResult.Success && !string.IsNullOrWhiteSpace(actionResult.Message))
{
Feedback(actionResult.Message);
}
}
private ActionResult ApplySkipToController(DroneTechController controller, bool feedbackRequested)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)controller))
{
return ActionResult.Failure("Operator drone controller not found.");
}
DroneLockState lockState = GetLockState(((Object)controller).GetInstanceID());
SkipResult val = _queueEngine.Skip(lockState, (IReadOnlyList<DroneId>)BuildQueueIds(controller.DroneQueue));
if (!val.Success)
{
return ActionResult.Failure(val.Message);
}
ApplyQueueOrder(controller, val.Queue);
SetCurrentDroneFromQueueHead(controller);
TryRefreshDroneQueueUi(controller);
if (feedbackRequested)
{
if (TryGetOwnedDroneById(controller, val.SkippedDrone, out var droneInfo))
{
Feedback("Moved " + GetDroneLabel(droneInfo) + " to the back of the queue.");
}
else
{
Feedback(val.Message);
}
}
return ActionResult.SuccessResult(val.Message);
}
private ActionResult ApplyToggleLockToController(DroneTechController controller, bool feedbackRequested)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: 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_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)controller))
{
return ActionResult.Failure("Operator drone controller not found.");
}
int instanceID = ((Object)controller).GetInstanceID();
DroneLockState lockState = GetLockState(instanceID);
ToggleLockResult val = _queueEngine.ToggleLock(lockState, GetDroneId(controller.CurrentDrone), (IReadOnlyList<DroneId>)BuildQueueIds(controller.DroneQueue));
if (!val.Success)
{
return ActionResult.Failure(val.Message);
}
DroneLockState val2 = lockState;
SetLockState(instanceID, val.LockState);
ApplyQueueOrder(controller, val.Queue);
TryRefreshDroneQueueUi(controller);
DroneLockState lockState2 = GetLockState(instanceID);
if (((DroneLockState)(ref lockState2)).IsEnabled)
{
if (!TryGetOwnedDroneById(controller, ((DroneLockState)(ref lockState2)).LockedDroneId, out var droneInfo))
{
ClearLock(instanceID, "Locked drone is no longer available. Lock disabled.");
return ActionResult.Failure("Locked drone is no longer available. Lock disabled.");
}
SetCurrentDroneImmediate(controller, droneInfo);
if (feedbackRequested)
{
Feedback("Locked drone: " + GetDroneLabel(droneInfo));
}
return ActionResult.SuccessResult("Locked drone: " + GetDroneLabel(droneInfo));
}
SetCurrentDroneFromQueueHead(controller);
if (((DroneLockState)(ref val2)).IsEnabled && feedbackRequested)
{
Feedback("Drone lock disabled.");
}
return ActionResult.SuccessResult("Drone lock disabled.");
}
private void EnsureNetworkHandlersRegistered()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
if (NetworkServer.active && !_serverRequestHandlerRegistered)
{
NetworkServer.RegisterHandler((short)32001, new NetworkMessageDelegate(OnDroneControlRequestMessage));
_serverRequestHandlerRegistered = true;
}
else if (!NetworkServer.active)
{
_serverRequestHandlerRegistered = false;
}
NetworkClient val = NetworkManager.singleton?.client;
if (val != null && !_clientResponseHandlerRegistered)
{
val.RegisterHandler((short)32002, new NetworkMessageDelegate(OnDroneControlResponseMessage));
_clientResponseHandlerRegistered = true;
}
else if (val == null)
{
_clientResponseHandlerRegistered = false;
}
}
private bool TrySendClientActionRequest(DroneTechController controller, DroneControlActionType action, out string reason)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
reason = string.Empty;
if (!Object.op_Implicit((Object)(object)controller))
{
reason = "Operator drone controller not found.";
return false;
}
CharacterBody component = ((Component)controller).GetComponent<CharacterBody>();
NetworkIdentity val = (Object.op_Implicit((Object)(object)component) ? ((Component)component).GetComponent<NetworkIdentity>() : null);
if (!Object.op_Implicit((Object)(object)val) || val.netId == NetworkInstanceId.Invalid)
{
reason = "Unable to identify local Operator network body.";
return false;
}
NetworkClient val2 = NetworkManager.singleton?.client;
if (val2 == null || !val2.isConnected)
{
reason = "No active network client connection. Host the run or connect to a host.";
return false;
}
DroneControlRequestMessage droneControlRequestMessage = new DroneControlRequestMessage
{
Action = (byte)action,
BodyNetId = val.netId
};
val2.Send((short)32001, (MessageBase)(object)droneControlRequestMessage);
return true;
}
private void OnDroneControlRequestMessage(NetworkMessage netMsg)
{
if (NetworkServer.active)
{
DroneControlRequestMessage request = netMsg.ReadMessage<DroneControlRequestMessage>();
DroneControlResponseMessage droneControlResponseMessage = HandleServerActionRequest(netMsg.conn, request);
NetworkConnection conn = netMsg.conn;
if (conn != null)
{
conn.Send((short)32002, (MessageBase)(object)droneControlResponseMessage);
}
}
}
private DroneControlResponseMessage HandleServerActionRequest(NetworkConnection senderConnection, DroneControlRequestMessage request)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
if (!TryResolveAuthorizedController(senderConnection, request.BodyNetId, out var controller, out var reason))
{
return DroneControlResponseMessage.Create(success: false, reason);
}
return (DroneControlActionType)request.Action switch
{
DroneControlActionType.Skip => BuildResponse(ApplySkipToController(controller, feedbackRequested: false)),
DroneControlActionType.ToggleLock => BuildResponse(ApplyToggleLockToController(controller, feedbackRequested: false)),
_ => DroneControlResponseMessage.Create(success: false, "Unknown drone control action requested."),
};
}
private static DroneControlResponseMessage BuildResponse(ActionResult result)
{
return DroneControlResponseMessage.Create(result.Success, result.Message);
}
private bool TryResolveAuthorizedController(NetworkConnection senderConnection, NetworkInstanceId bodyNetId, out DroneTechController controller, out string reason)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
controller = null;
reason = string.Empty;
if (senderConnection == null)
{
reason = "Missing network sender connection.";
return false;
}
GameObject val = Util.FindNetworkObject(bodyNetId);
CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CharacterBody>() : null);
if (!IsOperatorBody(val2))
{
reason = "The requested body is not a valid Operator body.";
return false;
}
NetworkUser val3 = TryGetNetworkUserFromConnection(senderConnection);
if (!Object.op_Implicit((Object)(object)val3) || (Object)(object)val3.master != (Object)(object)val2.master)
{
reason = "You do not own that Operator body.";
return false;
}
controller = ((Component)val2).GetComponent<DroneTechController>();
if (!Object.op_Implicit((Object)(object)controller))
{
reason = "Operator drone controller not found on requested body.";
return false;
}
return true;
}
private static NetworkUser TryGetNetworkUserFromConnection(NetworkConnection connection)
{
if (((connection != null) ? connection.playerControllers : null) == null)
{
return null;
}
for (int i = 0; i < connection.playerControllers.Count; i++)
{
GameObject gameObject = connection.playerControllers[i].gameObject;
if (Object.op_Implicit((Object)(object)gameObject))
{
NetworkUser component = gameObject.GetComponent<NetworkUser>();
if (Object.op_Implicit((Object)(object)component))
{
return component;
}
}
}
return null;
}
private void OnDroneControlResponseMessage(NetworkMessage netMsg)
{
DroneControlResponseMessage droneControlResponseMessage = netMsg.ReadMessage<DroneControlResponseMessage>();
if (!string.IsNullOrWhiteSpace(droneControlResponseMessage.Message))
{
Feedback(droneControlResponseMessage.Message);
}
}
private void DroneTechController_ReturnDrone(orig_ReturnDrone orig, DroneTechController self, DroneInfo droneInfo)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
orig.Invoke(self, droneInfo);
if (!NetworkServer.active || !Object.op_Implicit((Object)(object)self))
{
return;
}
int instanceID = ((Object)self).GetInstanceID();
DroneLockState lockState = GetLockState(instanceID);
if (!((DroneLockState)(ref lockState)).IsEnabled || !_controllersInAdminOverride.Contains(instanceID))
{
return;
}
ReturnDroneResult val = _queueEngine.HandleReturn(lockState, true, (IReadOnlyList<DroneId>)BuildQueueIds(self.DroneQueue));
SetLockState(instanceID, val.LockState);
if (val.QueueChanged)
{
ApplyQueueOrder(self, val.Queue);
TryRefreshDroneQueueUi(self);
}
DroneLockState lockState2 = GetLockState(instanceID);
if (((DroneLockState)(ref lockState2)).IsEnabled)
{
if (TryGetOwnedDroneById(self, ((DroneLockState)(ref lockState2)).LockedDroneId, out var droneInfo2))
{
SetCurrentDroneImmediate(self, droneInfo2);
}
else
{
ClearLock(instanceID, "Locked drone is no longer available. Lock disabled.");
}
}
}
private void Activate_OnEnter(orig_OnEnter orig, Activate self)
{
DroneTechController val = ResolveControllerForAdminOverride(self);
int num = (Object.op_Implicit((Object)(object)val) ? ((Object)val).GetInstanceID() : int.MinValue);
if (num != int.MinValue)
{
_controllersInAdminOverride.Add(num);
}
try
{
PrepareLockedDroneForAdminOverride(val);
orig.Invoke(self);
}
finally
{
if (num != int.MinValue)
{
_controllersInAdminOverride.Remove(num);
}
}
}
private DroneTechController ResolveControllerForAdminOverride(Activate state)
{
if (Object.op_Implicit((Object)(object)state?.droneController))
{
return state.droneController;
}
CharacterBody val = ((state != null) ? ((EntityState)state).characterBody : null);
if (Object.op_Implicit((Object)(object)val))
{
DroneTechController component = ((Component)val).GetComponent<DroneTechController>();
if (Object.op_Implicit((Object)(object)component))
{
return component;
}
}
return ResolveTrackedControllerFallback();
}
private DroneTechController ResolveTrackedControllerFallback()
{
LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
if (!Object.op_Implicit((Object)(object)val))
{
return null;
}
return ((Component)val).GetComponent<DroneTechController>();
}
private void PrepareLockedDroneForAdminOverride(DroneTechController controller)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active || !Object.op_Implicit((Object)(object)controller))
{
return;
}
int instanceID = ((Object)controller).GetInstanceID();
DroneLockState lockState = GetLockState(instanceID);
if (((DroneLockState)(ref lockState)).IsEnabled)
{
if (!TryGetOwnedDroneById(controller, ((DroneLockState)(ref lockState)).LockedDroneId, out var droneInfo))
{
ClearLock(instanceID, "Locked drone is no longer available. Lock disabled.");
}
else
{
EnsureDroneAtQueueHead(controller, droneInfo);
}
}
}
private static List<DroneId> BuildQueueIds(List<DroneInfo> queue)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
List<DroneId> list = new List<DroneId>(queue.Count);
foreach (DroneInfo item in queue)
{
DroneId droneId = GetDroneId(item);
if (((DroneId)(ref droneId)).IsValid)
{
list.Add(droneId);
}
}
return list;
}
private static void ApplyQueueOrder(DroneTechController controller, IReadOnlyList<DroneId> queueOrder)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)controller))
{
return;
}
Dictionary<DroneId, DroneInfo> dictionary = new Dictionary<DroneId, DroneInfo>();
foreach (DroneInfo item in controller.DroneQueue)
{
DroneId droneId = GetDroneId(item);
if (((DroneId)(ref droneId)).IsValid && !dictionary.ContainsKey(droneId))
{
dictionary.Add(droneId, item);
}
}
if (dictionary.Count != queueOrder.Count)
{
return;
}
List<DroneInfo> list = new List<DroneInfo>(queueOrder.Count);
foreach (DroneId item2 in queueOrder)
{
if (!dictionary.TryGetValue(item2, out var value))
{
return;
}
list.Add(value);
}
controller.DroneQueue.Clear();
controller.DroneQueue.AddRange(list);
}
private static void SetCurrentDroneFromQueueHead(DroneTechController controller)
{
if (Object.op_Implicit((Object)(object)controller))
{
if (controller.DroneQueue.Count > 0)
{
SetCurrentDroneImmediate(controller, controller.DroneQueue[0]);
}
else
{
SetCurrentDroneImmediate(controller, null);
}
}
}
private static void SetCurrentDroneImmediate(DroneTechController controller, DroneInfo droneInfo)
{
if (Object.op_Implicit((Object)(object)controller))
{
controller.SetCurrentDrone(droneInfo);
}
}
private static bool EnsureDroneAtQueueHead(DroneTechController controller, DroneInfo droneInfo)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)controller) || (Object)(object)droneInfo?.commandReceiver == (Object)null)
{
return false;
}
DroneId val = ((controller.DroneQueue.Count > 0) ? GetDroneId(controller.DroneQueue[0]) : DroneId.None);
DroneId droneId = GetDroneId(droneInfo);
int num = 0;
for (int num2 = controller.DroneQueue.Count - 1; num2 >= 0; num2--)
{
if (GetDroneId(controller.DroneQueue[num2]) == droneId)
{
controller.DroneQueue.RemoveAt(num2);
num++;
}
}
if (droneInfo.commandReceiver.IsReady())
{
controller.DroneQueue.Insert(0, droneInfo);
SetCurrentDroneImmediate(controller, droneInfo);
DroneId val2 = ((controller.DroneQueue.Count > 0) ? GetDroneId(controller.DroneQueue[0]) : DroneId.None);
if (num <= 1)
{
return val != val2;
}
return true;
}
return false;
}
private static void TryRefreshDroneQueueUi(DroneTechController controller)
{
if (Object.op_Implicit((Object)(object)controller))
{
object? obj = DroneTechUiField?.GetValue(controller);
DroneTechSurvivorUIController val = (DroneTechSurvivorUIController)((obj is DroneTechSurvivorUIController) ? obj : null);
if (val != null)
{
val.TryUpdateIcons(controller.DroneQueue, controller.AllDrones);
}
}
}
private static bool TryGetOwnedDroneById(DroneTechController controller, DroneId droneId, out DroneInfo droneInfo)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
droneInfo = null;
if (!Object.op_Implicit((Object)(object)controller) || !((DroneId)(ref droneId)).IsValid)
{
return false;
}
foreach (DroneInfo allDrone in controller.AllDrones)
{
if (!(GetDroneId(allDrone) != droneId))
{
droneInfo = allDrone;
return true;
}
}
return false;
}
private bool TryGetLocalOperatorController(out DroneTechController controller, out string reason)
{
controller = null;
reason = string.Empty;
LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
if (firstLocalUser == null)
{
reason = "No local user found.";
return false;
}
CharacterBody cachedBody = firstLocalUser.cachedBody;
if (!Object.op_Implicit((Object)(object)cachedBody))
{
reason = "No active character body.";
return false;
}
if (!IsOperatorBody(cachedBody))
{
reason = "You need to be playing Operator to use this.";
return false;
}
controller = ((Component)cachedBody).GetComponent<DroneTechController>();
if (!Object.op_Implicit((Object)(object)controller))
{
reason = "Operator drone controller not found on this body.";
return false;
}
return true;
}
private void BindConfig()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
_enableSkipKeybind = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableSkipKeybind", true, "Enable the skip current drone keybind.");
_skipKeybind = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "SkipKeybind", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), "Moves the current next-up drone to the back of the queue.");
_enableLockKeybind = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableLockKeybind", true, "Enable the lock current drone keybind.");
_lockToggleKeybind = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "LockToggleKeybind", new KeyboardShortcut((KeyCode)118, Array.Empty<KeyCode>()), "Toggle locking ADMIN-OVERRIDE to the current next-up drone.");
_showFeedback = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowFeedback", false, "Show chat feedback when actions are triggered.");
}
private void RegisterRiskOfOptions()
{
if (!Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
{
return;
}
try
{
Type type = Type.GetType("RiskOfOptions.ModSettingsManager, RiskOfOptions");
Type type2 = Type.GetType("RiskOfOptions.Options.CheckBoxOption, RiskOfOptions");
Type type3 = Type.GetType("RiskOfOptions.Options.KeyBindOption, RiskOfOptions");
if (!(type == null) && !(type2 == null) && !(type3 == null))
{
InvokeRiskOfOptionsMethod(type, "SetModDescription", "Rebind skip/lock controls and toggle feedback without editing config files.");
AddRiskOfOptionsOption(type, CreateRiskOfOptionsOption(type2, _enableSkipKeybind));
AddRiskOfOptionsOption(type, CreateRiskOfOptionsOption(type3, _skipKeybind));
AddRiskOfOptionsOption(type, CreateRiskOfOptionsOption(type2, _enableLockKeybind));
AddRiskOfOptionsOption(type, CreateRiskOfOptionsOption(type3, _lockToggleKeybind));
AddRiskOfOptionsOption(type, CreateRiskOfOptionsOption(type2, _showFeedback));
}
}
catch (Exception)
{
}
}
private static void AddRiskOfOptionsOption(Type modSettingsManagerType, object optionInstance)
{
if (optionInstance != null)
{
InvokeRiskOfOptionsMethod(modSettingsManagerType, "AddOption", optionInstance);
}
}
private static object CreateRiskOfOptionsOption(Type optionType, object configEntry)
{
ConstructorInfo[] constructors = optionType.GetConstructors();
foreach (ConstructorInfo constructorInfo in constructors)
{
ParameterInfo[] parameters = constructorInfo.GetParameters();
if (parameters.Length == 1 && parameters[0].ParameterType.IsInstanceOfType(configEntry))
{
return constructorInfo.Invoke(new object[1] { configEntry });
}
}
return null;
}
private static void InvokeRiskOfOptionsMethod(Type managerType, string methodName, params object[] arguments)
{
MethodInfo[] methods = managerType.GetMethods(BindingFlags.Static | BindingFlags.Public);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.Name != methodName)
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length != arguments.Length)
{
continue;
}
bool flag = true;
for (int j = 0; j < parameters.Length; j++)
{
object obj = arguments[j];
if (obj == null)
{
if (parameters[j].ParameterType.IsValueType)
{
flag = false;
break;
}
}
else if (!parameters[j].ParameterType.IsInstanceOfType(obj))
{
flag = false;
break;
}
}
if (flag)
{
methodInfo.Invoke(null, arguments);
break;
}
}
}
private void OnRunStartGlobal(Run _)
{
ClearRunState();
}
private void OnRunDestroyGlobal(Run _)
{
ClearRunState();
}
private void ClearRunState()
{
_lockStatesByController.Clear();
_controllersInAdminOverride.Clear();
}
private void MaintainLockedCurrentDrone()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active || !TryGetLocalOperatorController(out var controller, out var _))
{
return;
}
int instanceID = ((Object)controller).GetInstanceID();
DroneLockState lockState = GetLockState(instanceID);
if (!((DroneLockState)(ref lockState)).IsEnabled)
{
return;
}
if (!TryGetOwnedDroneById(controller, ((DroneLockState)(ref lockState)).LockedDroneId, out var droneInfo))
{
ClearLock(instanceID, "Locked drone is no longer available. Lock disabled.");
return;
}
bool num = EnsureDroneAtQueueHead(controller, droneInfo);
SetCurrentDroneImmediate(controller, droneInfo);
if (num)
{
TryRefreshDroneQueueUi(controller);
}
}
private DroneLockState GetLockState(int controllerId)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
if (_lockStatesByController.TryGetValue(controllerId, out var value))
{
return value;
}
return DroneLockState.Disabled;
}
private void SetLockState(int controllerId, DroneLockState lockState)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
if (((DroneLockState)(ref lockState)).IsEnabled)
{
_lockStatesByController[controllerId] = lockState;
}
else
{
_lockStatesByController.Remove(controllerId);
}
}
private void ClearLock(int controllerId, string reason = "")
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
DroneLockState lockState = GetLockState(controllerId);
bool isEnabled = ((DroneLockState)(ref lockState)).IsEnabled;
_lockStatesByController.Remove(controllerId);
if (isEnabled && !string.IsNullOrWhiteSpace(reason))
{
Feedback(reason);
}
}
private static bool IsOperatorBody(CharacterBody body)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)body))
{
return false;
}
return body.bodyIndex == BodyCatalog.FindBodyIndex("DroneTechBody");
}
private void Feedback(string message)
{
if (_showFeedback.Value)
{
Chat.AddMessage("[Operator Queue Control] " + message);
}
}
private static bool IsShortcutPressed(KeyboardShortcut shortcut)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey))
{
return false;
}
foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
{
if (!Input.GetKey(modifier))
{
return false;
}
}
return true;
}
private static DroneId GetDroneId(DroneInfo droneInfo)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)droneInfo?.commandReceiver == (Object)null)
{
return DroneId.None;
}
return new DroneId(((Object)((Component)droneInfo.commandReceiver).gameObject).GetInstanceID());
}
private static string GetDroneLabel(DroneInfo droneInfo)
{
if ((Object)(object)droneInfo?.commandReceiver == (Object)null)
{
return "Unknown Drone";
}
CharacterBody characterBody = droneInfo.commandReceiver.characterBody;
if (Object.op_Implicit((Object)(object)characterBody))
{
string @string = Language.GetString(characterBody.baseNameToken);
if (!string.IsNullOrWhiteSpace(@string) && @string != characterBody.baseNameToken)
{
return @string;
}
if (!string.IsNullOrWhiteSpace(characterBody.baseNameToken))
{
return characterBody.baseNameToken;
}
return ((Object)characterBody).name;
}
return ((Object)droneInfo.commandReceiver).name;
}
}
}