using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("LethalCasinoDoubleDown")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalCasinoDoubleDown")]
[assembly: AssemblyTitle("LethalCasinoDoubleDown")]
[assembly: AssemblyVersion("1.0.0.0")]
public static class PluginInfo
{
public const string PLUGIN_GUID = "Papkasse_Manden.Double_Down_In_Lethal_Casino";
public const string PLUGIN_NAME = "Double_Down_In_Lethal_Casino";
public const string PLUGIN_VERSION = "4.0.2";
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("Papkasse_Manden.Double_Down_In_Lethal_Casino", "Double_Down_In_Lethal_Casino", "4.0.2")]
public class BlackjackDoubleDownMod : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("Papkasse_Manden.Double_Down_In_Lethal_Casino");
public static ManualLogSource Log { get; private set; }
public static ConfigEntry<KeyboardShortcut> DoubleDownKey { get; private set; }
private void Awake()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"Plugin Papkasse_Manden.Double_Down_In_Lethal_Casino is loading...");
DoubleDownKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "DoubleDownKey", new KeyboardShortcut((KeyCode)117, Array.Empty<KeyCode>()), "Key to perform Double Down action in Blackjack");
ApplyAllPatches();
Log.LogInfo((object)"Plugin Papkasse_Manden.Double_Down_In_Lethal_Casino v4.0.2 loaded successfully");
}
private void ApplyAllPatches()
{
if (!BlackjackReflectionCache.Initialize(Log))
{
Log.LogError((object)"Failed to initialize reflection cache. Aborting patches.");
return;
}
CustomScrapControllerPatcher.ApplyPatches(harmony, Log);
BlackjackDoubleDownPatcher.ApplyPatches(harmony, Log);
BlackjackMultiplyScrapValuesPatcher.ApplyPatches(harmony, Log);
BlackjackProcessResultsPatcher.ApplyPatches(harmony, Log);
JoinGameServerRpcPatcher.ApplyPatches(harmony, Log);
}
}
internal static class BlackjackReflectionCache
{
public static Type BlackjackType { get; private set; }
public static Type CustomScrapControllerType { get; private set; }
public static FieldInfo GameInProgressField { get; private set; }
public static FieldInfo GamblingPlayersField { get; private set; }
public static FieldInfo GambledScrapField { get; private set; }
public static FieldInfo PlayerCardsField { get; private set; }
public static FieldInfo PlayerCompletedTurnField { get; private set; }
public static FieldInfo OriginalScrapValueField { get; private set; }
public static FieldInfo LockFromGamblingField { get; private set; }
public static FieldInfo DelayedTasksField { get; private set; }
public static FieldInfo DelayedTasksQueuedField { get; private set; }
public static MethodInfo DestroyBetControlsClientRpcMethod { get; private set; }
public static MethodInfo TakeTurnAsPlayerServerRpcMethod { get; private set; }
public static MethodInfo ShowWarningMessageClientRpcMethod { get; private set; }
public static MethodInfo MultiplyScrapValuesMethod { get; private set; }
public static MethodInfo UpdateScrapValueClientRpcMethod { get; private set; }
public static MethodInfo JoinGameServerRpcMethod { get; private set; }
public static MethodInfo JoinGameSuccessfulClientRpcMethod { get; private set; }
public static bool Initialize(ManualLogSource log)
{
try
{
BlackjackType = AccessTools.TypeByName("LethalCasino.Custom.Blackjack");
CustomScrapControllerType = AccessTools.TypeByName("LethalCasino.Custom.CustomScrapController");
if (BlackjackType == null || CustomScrapControllerType == null)
{
log.LogError((object)"Required LethalCasino types not found. Is LethalCasino installed?");
return false;
}
GameInProgressField = GetField(BlackjackType, "gameInProgress");
GamblingPlayersField = GetField(BlackjackType, "gamblingPlayers");
GambledScrapField = GetField(BlackjackType, "gambledScrap");
PlayerCardsField = GetField(BlackjackType, "playerCards");
PlayerCompletedTurnField = GetField(BlackjackType, "playerCompletedTurn");
DelayedTasksField = GetField(BlackjackType, "delayedTasks");
DelayedTasksQueuedField = GetField(BlackjackType, "delayedTasksQueued");
OriginalScrapValueField = GetField(CustomScrapControllerType, "originalScrapValue");
LockFromGamblingField = GetField(CustomScrapControllerType, "lockFromGambling");
TakeTurnAsPlayerServerRpcMethod = GetMethod(BlackjackType, "TakeTurnAsPlayerServerRpc", new Type[3]
{
typeof(NetworkBehaviourReference),
typeof(int),
typeof(string)
});
ShowWarningMessageClientRpcMethod = GetMethod(BlackjackType, "ShowWarningMessageClientRpc", new Type[4]
{
typeof(NetworkBehaviourReference),
typeof(string),
typeof(string),
typeof(bool)
});
MultiplyScrapValuesMethod = GetMethod(BlackjackType, "MultiplyScrapValues", new Type[3]
{
typeof(List<GrabbableObject>),
typeof(float),
typeof(bool)
});
UpdateScrapValueClientRpcMethod = GetMethod(BlackjackType, "UpdateScrapValueClientRpc", new Type[3]
{
typeof(NetworkBehaviourReference),
typeof(int),
typeof(bool)
});
JoinGameServerRpcMethod = GetMethod(BlackjackType, "JoinGameServerRpc", new Type[2]
{
typeof(NetworkBehaviourReference),
typeof(int)
});
DestroyBetControlsClientRpcMethod = GetMethod(BlackjackType, "DestroyBetControlsClientRpc", new Type[1] { typeof(int) });
JoinGameSuccessfulClientRpcMethod = GetMethod(BlackjackType, "JoinGameSuccessfulClientRpc", new Type[3]
{
typeof(NetworkBehaviourReference),
typeof(int),
typeof(int)
});
return ValidateReflection(log);
}
catch (Exception arg)
{
log.LogError((object)$"Failed to initialize reflection cache: {arg}");
return false;
}
}
private static FieldInfo GetField(Type type, string fieldName)
{
FieldInfo fieldInfo = AccessTools.Field(type, fieldName);
if (fieldInfo == null)
{
BlackjackDoubleDownMod.Log.LogWarning((object)("Field '" + fieldName + "' not found in " + type.Name));
}
return fieldInfo;
}
private static MethodInfo GetMethod(Type type, string methodName, Type[] parameters = null)
{
MethodInfo methodInfo = AccessTools.Method(type, methodName, parameters, (Type[])null);
if (methodInfo == null)
{
BlackjackDoubleDownMod.Log.LogWarning((object)("Method '" + methodName + "' not found in " + type.Name));
}
return methodInfo;
}
private static bool ValidateReflection(ManualLogSource log)
{
(FieldInfo, string)[] array = new(FieldInfo, string)[7]
{
(GameInProgressField, "gameInProgress"),
(GamblingPlayersField, "gamblingPlayers"),
(GambledScrapField, "gambledScrap"),
(PlayerCardsField, "playerCards"),
(PlayerCompletedTurnField, "playerCompletedTurn"),
(OriginalScrapValueField, "originalScrapValue"),
(LockFromGamblingField, "lockFromGambling")
};
(MethodInfo, string)[] array2 = new(MethodInfo, string)[7]
{
(TakeTurnAsPlayerServerRpcMethod, "TakeTurnAsPlayerServerRpc"),
(ShowWarningMessageClientRpcMethod, "ShowWarningMessageClientRpc"),
(MultiplyScrapValuesMethod, "MultiplyScrapValues"),
(UpdateScrapValueClientRpcMethod, "UpdateScrapValueClientRpc"),
(JoinGameServerRpcMethod, "JoinGameServerRpc"),
(JoinGameSuccessfulClientRpcMethod, "JoinGameSuccessfulClientRpc"),
(DestroyBetControlsClientRpcMethod, "DestroyBetControlsClientRpc")
};
bool result = true;
(FieldInfo, string)[] array3 = array;
for (int i = 0; i < array3.Length; i++)
{
var (fieldInfo, text) = array3[i];
if (fieldInfo == null)
{
log.LogError((object)("Required field '" + text + "' not found"));
result = false;
}
}
(MethodInfo, string)[] array4 = array2;
for (int j = 0; j < array4.Length; j++)
{
var (methodInfo, text2) = array4[j];
if (methodInfo == null)
{
log.LogError((object)("Required method '" + text2 + "' not found"));
result = false;
}
}
return result;
}
}
internal static class CustomScrapControllerPatcher
{
private static Dictionary<object, int> gambledValues = new Dictionary<object, int>();
public static void ApplyPatches(Harmony harmony, ManualLogSource log)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(BlackjackReflectionCache.CustomScrapControllerType, "__initializeVariables", (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(CustomScrapControllerPatcher), "InitializeVariables_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
log.LogInfo((object)"CustomScrapController __initializeVariables method patched");
}
else
{
log.LogWarning((object)"Could not find __initializeVariables method in CustomScrapController");
}
}
catch (Exception arg)
{
log.LogError((object)$"Failed to patch CustomScrapController: {arg}");
}
}
[HarmonyPostfix]
public static void InitializeVariables_Postfix(object __instance)
{
try
{
gambledValues[__instance] = 0;
BlackjackDoubleDownMod.Log.LogDebug((object)"Initialized gambledValue to 0 for scrap");
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in InitializeVariables_Postfix: {arg}");
}
}
public static int GetGambledValue(object customScrapController)
{
int value;
return gambledValues.TryGetValue(customScrapController, out value) ? value : 0;
}
public static void SetGambledValue(object customScrapController, int value)
{
gambledValues[customScrapController] = value;
}
public static void ClearAllGambledValues()
{
gambledValues.Clear();
}
}
internal static class BlackjackMultiplyScrapValuesPatcher
{
public static void ApplyPatches(Harmony harmony, ManualLogSource log)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
try
{
MethodInfo multiplyScrapValuesMethod = BlackjackReflectionCache.MultiplyScrapValuesMethod;
if (multiplyScrapValuesMethod != null)
{
harmony.Patch((MethodBase)multiplyScrapValuesMethod, new HarmonyMethod(typeof(BlackjackMultiplyScrapValuesPatcher), "MultiplyScrapValues_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
log.LogInfo((object)"Blackjack MultiplyScrapValues method patched successfully");
}
else
{
log.LogWarning((object)"Could not find MultiplyScrapValues method in Blackjack");
}
}
catch (Exception arg)
{
log.LogError((object)$"Failed to patch MultiplyScrapValues: {arg}");
}
}
[HarmonyPrefix]
public static bool MultiplyScrapValues_Prefix(object __instance, List<GrabbableObject> scrapItems, float multiplier, bool disablePoofsOnZero, ref int __result)
{
//IL_0507: Unknown result type (might be due to invalid IL or missing references)
try
{
int playerIndexForScrap = GetPlayerIndexForScrap(__instance, scrapItems);
BlackjackDoubleDownMod.Log.LogInfo((object)$"===== MultiplyScrapValues called for playerposition {playerIndexForScrap} =====");
if (multiplier == 0f && playerIndexForScrap != -1 && BustTracking.IsPlayerAlreadyBusted(playerIndexForScrap))
{
BlackjackDoubleDownMod.Log.LogInfo((object)"SKIPPING duplicate bust processing caused by ProcessResults");
__result = 0;
return false;
}
if (multiplier == 0f && playerIndexForScrap != -1 && !BustTracking.IsPlayerAlreadyBusted(playerIndexForScrap))
{
BustTracking.MarkPlayerBusted(playerIndexForScrap);
BlackjackDoubleDownMod.Log.LogInfo((object)$"MARKED player {playerIndexForScrap} as busted");
}
BlackjackDoubleDownMod.Log.LogInfo((object)$"Multiplier: {multiplier}, ScrapItems Count: {scrapItems?.Count}");
List<GrabbableObject>[] array = (List<GrabbableObject>[])BlackjackReflectionCache.GambledScrapField.GetValue(__instance);
for (int i = 0; i < array.Length; i++)
{
if (array[i] == null || array[i].Count <= 0)
{
continue;
}
BlackjackDoubleDownMod.Log.LogInfo((object)$"gambledScrapArray[{i}] has {array[i].Count} items");
foreach (GrabbableObject item in array[i])
{
if ((Object)(object)item != (Object)null)
{
BlackjackDoubleDownMod.Log.LogInfo((object)$" - {item.itemProperties.itemName} (Value: {item.scrapValue})");
}
}
}
int num = 0;
foreach (GrabbableObject scrapItem in scrapItems)
{
if ((Object)(object)scrapItem == (Object)null)
{
continue;
}
BlackjackDoubleDownMod.Log.LogInfo((object)$"Processing scrap item: {scrapItem.itemProperties.itemName}, Current Value: {scrapItem.scrapValue}");
Component component = ((Component)scrapItem).GetComponent(BlackjackReflectionCache.CustomScrapControllerType);
if ((Object)(object)component == (Object)null)
{
BlackjackDoubleDownMod.Log.LogWarning((object)"No CustomScrapController found!");
continue;
}
int num2 = CustomScrapControllerPatcher.GetGambledValue(component);
int num3 = (int)BlackjackReflectionCache.OriginalScrapValueField.GetValue(component);
if (num3 < num2)
{
num2 = num3;
}
BlackjackDoubleDownMod.Log.LogInfo((object)$"OriginalValue: {num3}, GambledValue: {num2}");
int num4;
if (num2 > 0)
{
if (multiplier == 0f)
{
num4 = Math.Max(0, num3 - num2);
BlackjackDoubleDownMod.Log.LogInfo((object)$"DoubleDown LOSS Calculation: {num3} - {num2} = {num4}");
}
else if (multiplier == 2f)
{
num4 = num3 + num2;
BlackjackDoubleDownMod.Log.LogInfo((object)$"DoubleDown WIN Calculation: {num3} + {num2} = {num4}");
}
else if (multiplier == 2.5f)
{
num4 = num3 + (int)((float)num2 * 1.5f);
BlackjackDoubleDownMod.Log.LogInfo((object)$"DoubleDown BLACKJACK Calculation: {num3} + ({num2} * 1.5) = {num4}");
}
else
{
num4 = num3;
BlackjackDoubleDownMod.Log.LogInfo((object)$"DoubleDown TIE - Keeping original value: {num4}");
}
}
else if (multiplier == 0f)
{
num4 = 0;
BlackjackDoubleDownMod.Log.LogInfo((object)$"Normal LOSS Calculation: {num3} = {num4}");
}
else if (multiplier == 2f)
{
num4 = (int)((float)num3 * 2f);
BlackjackDoubleDownMod.Log.LogInfo((object)$"Normal WIN Calculation: {num3} * 2 = {num4}");
}
else if (multiplier == 2.5f)
{
num4 = (int)((float)num3 * 2.5f);
BlackjackDoubleDownMod.Log.LogInfo((object)$"Normal BLACKJACK Calculation: {num3} * 2.5 = {num4}");
}
else
{
num4 = num3;
BlackjackDoubleDownMod.Log.LogInfo((object)$"Normal TIE - Keeping original value: {num4}");
}
int num5 = num4 - num3;
num += num5;
BlackjackDoubleDownMod.Log.LogInfo((object)$"Profit for this item: {num5}");
if (num4 != scrapItem.scrapValue)
{
BlackjackDoubleDownMod.Log.LogInfo((object)$"Value changed! Updating from {scrapItem.scrapValue} to {num4}");
BlackjackReflectionCache.UpdateScrapValueClientRpcMethod.Invoke(__instance, new object[3]
{
(object)new NetworkBehaviourReference((NetworkBehaviour)(object)scrapItem),
num4,
false
});
}
else
{
BlackjackDoubleDownMod.Log.LogInfo((object)$"No value change needed. Current: {scrapItem.scrapValue}, New: {num4}");
}
}
BlackjackDoubleDownMod.Log.LogInfo((object)$"Total Profit: {num}");
__result = num;
return false;
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in MultiplyScrapValues_Prefix: {arg}");
return true;
}
}
private static int GetPlayerIndexForScrap(object blackjackInstance, List<GrabbableObject> scrapItems)
{
List<GrabbableObject>[] array = (List<GrabbableObject>[])BlackjackReflectionCache.GambledScrapField.GetValue(blackjackInstance);
for (int i = 0; i < array.Length; i++)
{
if (array[i] == scrapItems)
{
return i;
}
}
return -1;
}
}
internal static class BlackjackDoubleDownPatcher
{
private static int lastItemSlot = -1;
private static float lastHintTime = 0f;
public static void ApplyPatches(Harmony harmony, ManualLogSource log)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(BlackjackReflectionCache.BlackjackType, "Update", (Type[])null, (Type[])null);
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(BlackjackDoubleDownPatcher), "Update_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
MethodInfo methodInfo2 = AccessTools.Method(BlackjackReflectionCache.BlackjackType, "CreateBetControlsClientRpc", new Type[2]
{
typeof(int),
typeof(NetworkBehaviourReference)
}, (Type[])null);
harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(BlackjackDoubleDownPatcher), "CreateBetControls_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
log.LogInfo((object)"Double Down patches applied successfully");
}
catch (Exception arg)
{
log.LogError((object)$"Failed to apply patches: {arg}");
}
}
[HarmonyPrefix]
public static void Update_Prefix(object __instance)
{
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
try
{
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
if ((Object)(object)localPlayerController == (Object)null || !(bool)BlackjackReflectionCache.GameInProgressField.GetValue(__instance))
{
return;
}
int hoveredPlayerIndex = GetHoveredPlayerIndex();
if (hoveredPlayerIndex != -1 && IsHoveringOverBetControls(localPlayerController) && !((Object)(object)localPlayerController.hoveringOverTrigger == (Object)null))
{
CheckForItemSwitchAndUpdateHint(__instance, localPlayerController, hoveredPlayerIndex);
KeyboardShortcut value = BlackjackDoubleDownMod.DoubleDownKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && CanDoubleDown(__instance, localPlayerController, hoveredPlayerIndex))
{
PerformDoubleDown(__instance, localPlayerController, hoveredPlayerIndex);
}
}
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in Update_Prefix: {arg}");
}
}
private static bool IsHoveringOverBetControls(PlayerControllerB player)
{
InteractTrigger hoveringOverTrigger = player.hoveringOverTrigger;
int result;
if (hoveringOverTrigger != null)
{
GameObject gameObject = ((Component)hoveringOverTrigger).gameObject;
if (((gameObject == null) ? null : ((Object)gameObject).name?.Contains("Hit")).GetValueOrDefault())
{
result = 1;
goto IL_009e;
}
}
InteractTrigger hoveringOverTrigger2 = player.hoveringOverTrigger;
if (hoveringOverTrigger2 == null)
{
result = 0;
}
else
{
GameObject gameObject2 = ((Component)hoveringOverTrigger2).gameObject;
result = (((gameObject2 == null) ? null : ((Object)gameObject2).name?.Contains("Stand")).GetValueOrDefault() ? 1 : 0);
}
goto IL_009e;
IL_009e:
return (byte)result != 0;
}
[HarmonyPostfix]
public static void CreateBetControls_Postfix(object __instance, int playerIdx, NetworkBehaviourReference playerRef)
{
//IL_005c: 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)
try
{
if (ShouldShowDoubleDownHint())
{
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
PlayerControllerB val = default(PlayerControllerB);
if (!((Object)(object)localPlayerController == (Object)null) && ((NetworkBehaviourReference)(ref playerRef)).TryGet<PlayerControllerB>(ref val, (NetworkManager)null) && !((Object)(object)val != (Object)(object)localPlayerController) && CanDoubleDown(__instance, localPlayerController, playerIdx))
{
KeyboardShortcut value = BlackjackDoubleDownMod.DoubleDownKey.Value;
string text = ((object)(KeyboardShortcut)(ref value)).ToString();
HUDManager.Instance.DisplayTip("Double Down Hint", "Press [" + text + "] to double your bet and receive one card.", false, false, "LC_Tip1");
}
}
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in CreateBetControls_Postfix: {arg}");
}
}
private static void CheckForItemSwitchAndUpdateHint(object blackjackInstance, PlayerControllerB player, int playerIndex)
{
//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)
try
{
if (player.currentItemSlot != lastItemSlot)
{
lastItemSlot = player.currentItemSlot;
if (CanDoubleDown(blackjackInstance, player, playerIndex))
{
KeyboardShortcut value = BlackjackDoubleDownMod.DoubleDownKey.Value;
string text = ((object)(KeyboardShortcut)(ref value)).ToString();
HUDManager.Instance.DisplayTip("Double Down Hint", "Press [" + text + "] to double your bet and receive one card.", false, false, "LC_Tip1");
}
}
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in CheckForItemSwitchAndUpdateHint: {arg}");
}
}
private static bool ShouldShowDoubleDownHint()
{
if (Time.time - lastHintTime > 20f)
{
lastHintTime = Time.time;
return true;
}
return false;
}
private static int GetLocalPlayerIndex(object blackjackInstance, PlayerControllerB localPlayer)
{
PlayerControllerB[] array = (PlayerControllerB[])BlackjackReflectionCache.GamblingPlayersField.GetValue(blackjackInstance);
for (int i = 0; i < array.Length; i++)
{
if ((Object)(object)array[i] == (Object)(object)localPlayer)
{
return i;
}
}
return -1;
}
private static int GetHoveredPlayerIndex()
{
PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
if ((Object)(object)val == (Object)null || (Object)(object)val.hoveringOverTrigger == (Object)null)
{
return -1;
}
GameObject gameObject = ((Component)val.hoveringOverTrigger).gameObject;
if ((Object)(object)gameObject == (Object)null)
{
return -1;
}
Transform val2 = gameObject.transform;
while ((Object)(object)val2 != (Object)null)
{
if (((Object)val2).name.StartsWith("Player") && ((Object)val2).name.EndsWith("HandPosition"))
{
string s = ((Object)val2).name.Substring(6, 1);
if (int.TryParse(s, out var result))
{
return result - 1;
}
}
val2 = val2.parent;
}
return -1;
}
private static bool CanDoubleDown(object blackjackInstance, PlayerControllerB player, int playerIndex)
{
bool[] array = (bool[])BlackjackReflectionCache.PlayerCompletedTurnField.GetValue(blackjackInstance);
if (array[playerIndex])
{
return false;
}
IList list = (IList)BlackjackReflectionCache.PlayerCardsField.GetValue(blackjackInstance);
if (!(list[playerIndex] is IList list2) || list2.Count != 2)
{
return false;
}
GrabbableObject val = player.ItemSlots[player.currentItemSlot];
if ((Object)(object)val == (Object)null)
{
return false;
}
Component component = ((Component)val).GetComponent(BlackjackReflectionCache.CustomScrapControllerType);
if ((Object)(object)component == (Object)null)
{
return false;
}
if (val.scrapValue <= 0)
{
return false;
}
return true;
}
private static void PerformDoubleDown(object blackjackInstance, PlayerControllerB player, int playerIndex)
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
try
{
BlackjackDoubleDownMod.Log.LogInfo((object)$"Starting double down locally, for {player.playerUsername} at position {playerIndex}");
GrabbableObject val = player.ItemSlots[player.currentItemSlot];
NetworkBehaviourReference val2 = default(NetworkBehaviourReference);
((NetworkBehaviourReference)(ref val2))..ctor((NetworkBehaviour)(object)player);
int num = playerIndex - 1000;
BlackjackReflectionCache.JoinGameServerRpcMethod.Invoke(blackjackInstance, new object[2] { val2, num });
BlackjackDoubleDownMod.Log.LogInfo((object)"Double down request sent");
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in PerformDoubleDown: {arg}");
}
}
}
internal static class BustTracking
{
private static HashSet<int> alreadyBustedPlayers = new HashSet<int>();
public static void MarkPlayerBusted(int playerIdx)
{
alreadyBustedPlayers.Add(playerIdx);
}
public static bool IsPlayerAlreadyBusted(int playerIdx)
{
return alreadyBustedPlayers.Contains(playerIdx);
}
public static void Clear()
{
alreadyBustedPlayers.Clear();
}
}
internal static class BlackjackProcessResultsPatcher
{
public static void ApplyPatches(Harmony harmony, ManualLogSource log)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
//IL_0054: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(BlackjackReflectionCache.BlackjackType, "ProcessResults", (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(BlackjackProcessResultsPatcher), "ProcessResults_Prefix", (Type[])null), new HarmonyMethod(typeof(BlackjackProcessResultsPatcher), "ProcessResults_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
log.LogInfo((object)"ProcessResults patched for bust tracking cleanup");
}
}
catch (Exception arg)
{
log.LogError((object)$"Failed to patch ProcessResults: {arg}");
}
}
[HarmonyPrefix]
public static void ProcessResults_Prefix(object __instance)
{
try
{
PlayerControllerB[] array = (PlayerControllerB[])BlackjackReflectionCache.GamblingPlayersField.GetValue(__instance);
for (int i = 0; i < array.Length; i++)
{
if ((Object)(object)array[i] != (Object)null && BustTracking.IsPlayerAlreadyBusted(i))
{
BlackjackDoubleDownMod.Log.LogInfo((object)$"Removing player {i} from ProcessResults - double down bust");
array[i] = null;
}
}
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in ProcessResults_Prefix: {arg}");
}
}
[HarmonyPostfix]
public static void ProcessResults_Postfix()
{
BustTracking.Clear();
CustomScrapControllerPatcher.ClearAllGambledValues();
BlackjackDoubleDownMod.Log.LogInfo((object)"Cleared bust tracking AFTER ProcessResults");
}
}
internal static class JoinGameServerRpcPatcher
{
public static void ApplyPatches(Harmony harmony, ManualLogSource log)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(BlackjackReflectionCache.BlackjackType, "JoinGameServerRpc", new Type[2]
{
typeof(NetworkBehaviourReference),
typeof(int)
}, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(JoinGameServerRpcPatcher), "JoinGameServerRpc_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
log.LogInfo((object)"JoinGameServerRpc patched for double down support");
}
else
{
log.LogError((object)"Could not find JoinGameServerRpc method to patch!");
}
}
catch (Exception arg)
{
log.LogError((object)$"Failed to patch JoinGameServerRpc: {arg}");
}
}
[HarmonyPrefix]
public static bool JoinGameServerRpc_Prefix(object __instance, NetworkBehaviourReference playerRef, int playerIdx)
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
try
{
BlackjackDoubleDownMod.Log.LogInfo((object)$"Running JoinGameServerRPC {playerIdx}");
if (playerIdx >= -100)
{
return true;
}
object obj = ((__instance is NetworkBehaviour) ? __instance : null);
if (obj != null && ((NetworkBehaviour)obj).IsServer)
{
BlackjackDoubleDownMod.Log.LogInfo((object)"SERVER: Handling double down logic");
int playerIdx2 = playerIdx + 1000;
HandleDoubleDownOnServer(__instance, playerRef, playerIdx2);
return false;
}
BlackjackDoubleDownMod.Log.LogInfo((object)"CLIENT: sending joinGameServerRPC double down to host");
return true;
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in JoinGameServerRpc_Prefix: {arg}");
return true;
}
}
private static void HandleDoubleDownOnServer(object __instance, NetworkBehaviourReference playerRef, int playerIdx)
{
//IL_029a: Unknown result type (might be due to invalid IL or missing references)
//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
//IL_032b: Unknown result type (might be due to invalid IL or missing references)
try
{
BlackjackDoubleDownMod.Log.LogInfo((object)$"SERVER: Handling double down for player {playerIdx}");
PlayerControllerB val = default(PlayerControllerB);
if (!((NetworkBehaviourReference)(ref playerRef)).TryGet<PlayerControllerB>(ref val, (NetworkManager)null))
{
BlackjackDoubleDownMod.Log.LogError((object)"Failed to get player controller from NetworkBehaviourReference");
return;
}
GrabbableObject val2 = val.ItemSlots[val.currentItemSlot];
if ((Object)(object)val2 == (Object)null)
{
BlackjackDoubleDownMod.Log.LogError((object)"No held item found for double down");
return;
}
Component component = ((Component)val2).GetComponent(BlackjackReflectionCache.CustomScrapControllerType);
if ((Object)(object)component == (Object)null)
{
BlackjackDoubleDownMod.Log.LogError((object)"No CustomScrapController found on held item");
return;
}
if ((bool)BlackjackReflectionCache.LockFromGamblingField.GetValue(component))
{
BlackjackReflectionCache.ShowWarningMessageClientRpcMethod.Invoke(__instance, new object[4] { val, "Cannot bet", "Scrap is already being gambled", true });
return;
}
BlackjackReflectionCache.LockFromGamblingField.SetValue(component, true);
List<GrabbableObject>[] array = (List<GrabbableObject>[])BlackjackReflectionCache.GambledScrapField.GetValue(__instance);
if (array == null || playerIdx < 0 || playerIdx >= array.Length)
{
BlackjackDoubleDownMod.Log.LogError((object)"Invalid gambledScrap array or player index");
return;
}
int scrapValue = val2.scrapValue;
BlackjackReflectionCache.OriginalScrapValueField.SetValue(component, val2.scrapValue);
BlackjackDoubleDownMod.Log.LogInfo((object)"Updated originalScrapValue field");
int num = 0;
foreach (GrabbableObject item in array[playerIdx])
{
if ((Object)(object)item != (Object)null)
{
Component component2 = ((Component)item).GetComponent(BlackjackReflectionCache.CustomScrapControllerType);
if ((Object)(object)component2 != (Object)null)
{
int num2 = (int)BlackjackReflectionCache.OriginalScrapValueField.GetValue(component2);
num += num2;
}
}
}
int num3 = ((num <= scrapValue) ? num : scrapValue);
CustomScrapControllerPatcher.SetGambledValue(component, num3);
array[playerIdx].Add(val2);
int num4 = num + num3;
BlackjackDoubleDownMod.Log.LogInfo((object)$"Double down total bet amount: {num4}");
PlayerControllerB[] array2 = (PlayerControllerB[])BlackjackReflectionCache.GamblingPlayersField.GetValue(__instance);
if (array2 == null || playerIdx >= array2.Length)
{
BlackjackDoubleDownMod.Log.LogError((object)"Invalid gamblingPlayers array");
return;
}
BlackjackReflectionCache.JoinGameSuccessfulClientRpcMethod?.Invoke(__instance, new object[3]
{
(object)new NetworkBehaviourReference((NetworkBehaviour)(object)val),
playerIdx,
num4
});
BlackjackReflectionCache.DestroyBetControlsClientRpcMethod?.Invoke(__instance, new object[1] { playerIdx });
BlackjackReflectionCache.TakeTurnAsPlayerServerRpcMethod?.Invoke(__instance, new object[3]
{
(object)new NetworkBehaviourReference((NetworkBehaviour)(object)val),
playerIdx,
"hit"
});
BlackjackReflectionCache.TakeTurnAsPlayerServerRpcMethod?.Invoke(__instance, new object[3]
{
(object)new NetworkBehaviourReference((NetworkBehaviour)(object)val),
playerIdx,
"stand"
});
BlackjackDoubleDownMod.Log.LogInfo((object)$"Double down completed successfully for player {playerIdx}");
}
catch (Exception arg)
{
BlackjackDoubleDownMod.Log.LogError((object)$"Error in HandleDoubleDownOnServer: {arg}");
}
}
}