using System;
using System.Collections;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("StorageSorter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("StorageSorter")]
[assembly: AssemblyTitle("StorageSorter")]
[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 StorageSorter
{
internal static class Loc
{
public const string Auto = "Auto";
public const string Fallback = "en";
private static readonly Dictionary<string, Dictionary<string, string>> Tables = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
{
["en"] = new Dictionary<string, string>
{
["host_only"] = "Only the host can sort the storage.",
["no_shelves"] = "No storage shelves found.",
["aborted"] = "Storage sort aborted (check the BepInEx log).",
["already_sorted"] = "Storage is already sorted.",
["error"] = "An error occurred while sorting the storage (check the BepInEx log).",
["sorted"] = "Storage sorted{1}: {0} slot(s) updated{2}",
["sorted.category"] = " (category shelves first)",
["sorted.merged"] = ", boxes {0} → {1}",
["lost"] = "Warning: {0} box(es) could not be placed. Check the BepInEx log."
},
["ja"] = new Dictionary<string, string>
{
["host_only"] = "倉庫の並び替えはホストのみ実行できます。",
["no_shelves"] = "倉庫の棚が見つかりません。",
["aborted"] = "倉庫の並び替えを中止しました(BepInExのログを確認してください)。",
["already_sorted"] = "倉庫はすでに整理されています。",
["error"] = "倉庫の並び替え中にエラーが発生しました(BepInExのログを確認してください)。",
["sorted"] = "倉庫を並び替えました{1}: {0} スロット更新{2}",
["sorted.category"] = "(カテゴリ棚優先)",
["sorted.merged"] = "、箱 {0}→{1}",
["lost"] = "注意: {0} 箱を配置できませんでした。BepInExのログを確認してください。"
}
};
public static IEnumerable<string> Available => Tables.Keys.OrderBy<string, string>((string k) => k, StringComparer.OrdinalIgnoreCase);
public static string Current
{
get
{
string text = Plugin.Language?.Value ?? "Auto";
if (!string.Equals(text, "Auto", StringComparison.OrdinalIgnoreCase) && Tables.ContainsKey(text))
{
return text;
}
if (!GameIsJapanese())
{
return "en";
}
return "ja";
}
}
public static void LoadExternal(string pluginDir)
{
string path = Path.Combine(pluginDir, "lang");
if (!Directory.Exists(path))
{
return;
}
string[] files = Directory.GetFiles(path, "*.txt");
foreach (string text in files)
{
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
if (fileNameWithoutExtension.StartsWith("_") || fileNameWithoutExtension.Length == 0)
{
continue;
}
try
{
if (!Tables.TryGetValue(fileNameWithoutExtension, out var value))
{
value = (Tables[fileNameWithoutExtension] = new Dictionary<string, string>());
}
int num = 0;
string[] array = File.ReadAllLines(text, Encoding.UTF8);
for (int j = 0; j < array.Length; j++)
{
string text2 = array[j].Trim();
if (text2.Length == 0 || text2.StartsWith("#"))
{
continue;
}
int num2 = text2.IndexOf('=');
if (num2 > 0)
{
string key = text2.Substring(0, num2).Trim();
string text3 = text2.Substring(num2 + 1).Trim();
if (text3.Length >= 2 && text3[0] == '"' && text3[text3.Length - 1] == '"')
{
text3 = text3.Substring(1, text3.Length - 2);
}
value[key] = text3.Replace("\\n", "\n");
num++;
}
}
Plugin.Log.LogInfo((object)$"Loaded language file '{fileNameWithoutExtension}' ({num} entries).");
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Could not read language file " + text + ": " + ex.Message));
}
}
}
public static string T(string key, params object[] args)
{
string value = null;
if (Tables.TryGetValue(Current, out var value2))
{
value2.TryGetValue(key, out value);
}
if (value == null)
{
Tables["en"].TryGetValue(key, out value);
}
if (value == null)
{
return key;
}
if (args == null || args.Length == 0)
{
return value;
}
try
{
return string.Format(value, args);
}
catch (FormatException)
{
return value;
}
}
private static bool GameIsJapanese()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Invalid comparison between Unknown and I4
LocalizationManager instance = LocalizationManager.instance;
if ((Object)(object)instance == (Object)null || instance.LocalizationDictionary == null || instance.LocalizationDictionary.Count == 0)
{
return (int)Application.systemLanguage == 22;
}
int num = 0;
foreach (string value in instance.LocalizationDictionary.Values)
{
if (value != null && value.Any((char c) => c >= '\u3040' && c <= 'ヿ'))
{
return true;
}
if (++num >= 300)
{
break;
}
}
return false;
}
}
internal static class Notifier
{
private static FieldInfo _cooldownField;
private static bool _resolved;
public static void Show(string message)
{
Plugin.Log.LogInfo((object)("[Notify] " + message));
GameCanvas instance = GameCanvas.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
try
{
if (!_resolved)
{
_resolved = true;
_cooldownField = typeof(GameCanvas).GetField("inCooldown", BindingFlags.Instance | BindingFlags.NonPublic);
}
_cooldownField?.SetValue(instance, false);
instance.CreateCanvasNotification("`" + message);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Notification failed: " + ex.Message));
}
}
}
internal static class OaoBridge
{
public const string OaoGuid = "com.ddqminik.supermarkettogether.orderandorganize";
private static bool _resolved;
private static object _manager;
private static MethodInfo _getCategory;
public static bool Available
{
get
{
Resolve();
if (_manager != null)
{
return _getCategory != null;
}
return false;
}
}
public static int? GetCategory(Data_Container container)
{
if (!Available)
{
return null;
}
try
{
return (int?)_getCategory.Invoke(_manager, new object[1] { container });
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("OrderAndOrganize category lookup failed: " + ex.Message));
return null;
}
}
private static void Resolve()
{
if (_resolved && _manager != null)
{
return;
}
_resolved = true;
try
{
if (!Chainloader.PluginInfos.TryGetValue("com.ddqminik.supermarkettogether.orderandorganize", out var value) || (Object)(object)value.Instance == (Object)null)
{
return;
}
_manager = AccessTools.Field(((object)value.Instance).GetType(), "_categoryShelfManager")?.GetValue(value.Instance);
if (_manager != null)
{
_getCategory = AccessTools.Method(_manager.GetType(), "GetCategory", new Type[1] { typeof(Data_Container) }, (Type[])null);
if (_getCategory != null)
{
Plugin.Log.LogInfo((object)"OrderAndOrganize category shelves detected.");
}
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Could not link to OrderAndOrganize: " + ex.Message));
_manager = null;
}
}
}
[BepInPlugin("penguin4glte.supermarkettogether.storagesorter", "StorageSorter", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "penguin4glte.supermarkettogether.storagesorter";
public const string PluginName = "StorageSorter";
public const string PluginVersion = "1.0.0";
internal static ManualLogSource Log;
internal static ConfigEntry<KeyboardShortcut> SortHotkey;
internal static ConfigEntry<bool> MergeBoxes;
internal static ConfigEntry<bool> UseCategoryShelves;
internal static ConfigEntry<string> Language;
private Harmony _harmony;
private float _lastSortTime = -999f;
private void Awake()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Expected O, but got Unknown
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Loc.LoadExternal(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
SortHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "SortHotkey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Key that sorts the storage (host only).\n倉庫の並び替えを実行するキー(ホストのみ)。");
MergeBoxes = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MergeBoxes", true, "Combine partially filled boxes of the same product up to the per-box limit. The total item count never changes.\n同じ商品で中身が中途半端な箱を、1箱の上限まで寄せてまとめます。商品の総数は変わりません。");
UseCategoryShelves = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseCategoryShelves", true, "Fill shelves that have an OrderAndOrganize category with that category first.\nOrderAndOrganize でカテゴリを設定した棚に、そのカテゴリの商品を優先して入れます。");
Language = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Language", "Auto", new ConfigDescription("Message language. Auto = Japanese if the game is in Japanese, otherwise English. Add more languages as lang/<code>.txt in the plugin folder.\nメッセージの言語。Auto = ゲームが日本語なら日本語、それ以外は英語。", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[1] { "Auto" }.Concat(Loc.Available).ToArray()), Array.Empty<object>()));
_harmony = new Harmony("penguin4glte.supermarkettogether.storagesorter");
_harmony.PatchAll(typeof(SortGuardPatches));
Log.LogInfo((object)string.Format("{0} {1} loaded. Hotkey: {2}", "StorageSorter", "1.0.0", SortHotkey.Value));
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void Update()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: 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)
//IL_001b: Invalid comparison between Unknown and I4
KeyboardShortcut value = SortHotkey.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && (int)Cursor.lockState == 1 && !StorageSortRunner.IsSorting && !(Time.unscaledTime - _lastSortTime < 2f) && !((Object)(object)NPC_Manager.Instance == (Object)null) && !((Object)(object)ProductListing.Instance == (Object)null) && !((Object)(object)NPC_Manager.Instance.storageOBJ == (Object)null))
{
if (!NetworkServer.active)
{
Notifier.Show(Loc.T("host_only"));
return;
}
_lastSortTime = Time.unscaledTime;
((MonoBehaviour)this).StartCoroutine(StorageSortRunner.Run());
}
}
}
[HarmonyPatch]
internal static class SortGuardPatches
{
[HarmonyPatch(typeof(NPC_Manager), "GetFreeStorageRow")]
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void FreeRowPostfix(ref int __result)
{
if (StorageSortRunner.IsSorting)
{
__result = -1;
}
}
[HarmonyPatch(typeof(NPC_Manager), "GetStorageRowWithBoxToMerge")]
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void MergeRowPostfix(ref int __result)
{
if (StorageSortRunner.IsSorting)
{
__result = -1;
}
}
[HarmonyPatch(typeof(Data_Container), "GetStorageBox")]
[HarmonyPrefix]
[HarmonyPriority(800)]
private static bool GetStorageBoxPrefix()
{
return !StorageSortRunner.IsSorting;
}
[HarmonyPatch(typeof(Data_Container), "BoxItemFromStorageTray")]
[HarmonyPrefix]
[HarmonyPriority(800)]
private static bool TrayPrefix()
{
return !StorageSortRunner.IsSorting;
}
}
public sealed class SlotInfo
{
public int ShelfOrder;
public int SlotIndex;
public int? Category;
public int Pid;
public int Count;
public bool Locked;
public object Tag;
public bool HasBox
{
get
{
if (Pid >= 0)
{
return Count >= 0;
}
return false;
}
}
}
public struct SlotContent : IEquatable<SlotContent>
{
public int Pid;
public int Count;
public static readonly SlotContent Empty = new SlotContent(-1, -1);
public bool IsEmpty
{
get
{
if (Pid == -1)
{
return Count == -1;
}
return false;
}
}
public SlotContent(int pid, int count)
{
Pid = pid;
Count = count;
}
public bool Equals(SlotContent o)
{
if (Pid == o.Pid)
{
return Count == o.Count;
}
return false;
}
public override bool Equals(object o)
{
if (o is SlotContent o2)
{
return Equals(o2);
}
return false;
}
public override int GetHashCode()
{
return (Pid * 397) ^ Count;
}
public override string ToString()
{
if (!IsEmpty)
{
return $"P{Pid}x{Count}";
}
return "(empty)";
}
}
public sealed class PlanResult
{
public Dictionary<SlotInfo, SlotContent> Target = new Dictionary<SlotInfo, SlotContent>();
public int BoxesBefore;
public int BoxesAfter;
public int UnitsBefore;
public int UnitsAfter;
public int ChangedSlots;
public string Error;
}
public static class StoragePlanner
{
private sealed class Box
{
public int Pid;
public int Count;
public int Group;
}
public static PlanResult Plan(IList<SlotInfo> slots, Func<int, int> groupOf, Func<int, int> maxPerBox, bool merge)
{
PlanResult result = new PlanResult();
List<SlotInfo> list = slots.Where((SlotInfo s) => !s.Locked).ToList();
List<Box> list2 = new List<Box>();
foreach (SlotInfo item in list.Where((SlotInfo s) => s.HasBox))
{
list2.Add(new Box
{
Pid = item.Pid,
Count = item.Count,
Group = groupOf(item.Pid)
});
}
result.BoxesBefore = list2.Count;
result.UnitsBefore = list2.Sum((Box b) => b.Count);
if (merge)
{
List<Box> list3 = new List<Box>();
foreach (IGrouping<int, Box> item2 in from b in list2
group b by b.Pid)
{
int num = Math.Max(1, maxPerBox(item2.Key));
int num2 = item2.Where((Box b) => b.Count > 0).Sum((Box b) => b.Count);
int num3 = item2.First().Group;
int num4 = item2.Count((Box b) => b.Count > 0);
if ((num2 + num - 1) / num > num4)
{
list3.AddRange(item2.Where((Box b) => b.Count > 0));
}
else
{
while (num2 > 0)
{
int num5 = Math.Min(num, num2);
list3.Add(new Box
{
Pid = item2.Key,
Count = num5,
Group = num3
});
num2 -= num5;
}
}
list3.AddRange(item2.Where((Box b) => b.Count == 0));
}
list2 = list3;
}
list2 = (from b in list2
orderby b.Group, b.Pid, b.Count descending
select b).ToList();
result.BoxesAfter = list2.Count;
result.UnitsAfter = list2.Sum((Box b) => b.Count);
List<List<SlotInfo>> list4 = (from s in list
group s by s.ShelfOrder into g
orderby g.Key
select g.OrderBy((SlotInfo s) => s.SlotIndex).ToList()).ToList();
foreach (SlotInfo item3 in list)
{
result.Target[item3] = SlotContent.Empty;
}
LinkedList<Box> linkedList = new LinkedList<Box>(list2);
Dictionary<List<SlotInfo>, int> freeSlots = new Dictionary<List<SlotInfo>, int>();
foreach (List<SlotInfo> item4 in list4)
{
freeSlots[item4] = 0;
}
foreach (List<SlotInfo> item5 in list4.Where((List<SlotInfo> sh) => sh[0].Category.HasValue))
{
int value = item5[0].Category.Value;
LinkedListNode<Box> linkedListNode = linkedList.First;
while (linkedListNode != null && freeSlots[item5] < item5.Count)
{
LinkedListNode<Box>? next = linkedListNode.Next;
if (linkedListNode.Value.Group == value)
{
Put(item5, linkedListNode.Value);
linkedList.Remove(linkedListNode);
}
linkedListNode = next;
}
}
bool[] array = new bool[2] { false, true };
foreach (bool pass in array)
{
foreach (List<SlotInfo> item6 in list4.Where((List<SlotInfo> sh) => sh[0].Category.HasValue == pass))
{
while (linkedList.Count > 0 && freeSlots[item6] < item6.Count)
{
Put(item6, linkedList.First.Value);
linkedList.RemoveFirst();
}
}
}
if (linkedList.Count > 0)
{
result.Error = $"{linkedList.Count} box(es) did not fit (this should not happen).";
return result;
}
if (result.UnitsAfter != result.UnitsBefore)
{
result.Error = $"Unit count mismatch {result.UnitsBefore} -> {result.UnitsAfter}.";
return result;
}
result.ChangedSlots = list.Count((SlotInfo s) => !result.Target[s].Equals(new SlotContent(s.Pid, s.Count)));
return result;
void Put(List<SlotInfo> shelf, Box b)
{
int index = freeSlots[shelf]++;
result.Target[shelf[index]] = new SlotContent(b.Pid, b.Count);
}
}
}
internal static class StorageSortRunner
{
private sealed class SlotRef
{
public Data_Container Container;
public int Index;
}
public static bool IsSorting { get; private set; }
public static IEnumerator Run()
{
IsSorting = true;
List<KeyValuePair<SlotInfo, SlotContent>> toFill = null;
PlanResult plan = null;
bool flag = false;
List<SlotInfo> list = new List<SlotInfo>();
try
{
List<SlotInfo> list2 = Snapshot();
if (list2.Count == 0)
{
Notifier.Show(Loc.T("no_shelves"));
yield break;
}
Dictionary<int, int> groups = BuildProductGroups();
ProductData[] products = ProductListing.Instance.productsData;
plan = StoragePlanner.Plan(list2, (int pid) => (!groups.TryGetValue(pid, out var value)) ? int.MaxValue : value, (int pid) => products[pid].maxItemsPerBox, Plugin.MergeBoxes.Value);
if (plan.Error != null)
{
Plugin.Log.LogError((object)("Sort aborted: " + plan.Error));
Notifier.Show(Loc.T("aborted"));
yield break;
}
if (plan.ChangedSlots == 0)
{
Notifier.Show(Loc.T("already_sorted"));
yield break;
}
toFill = new List<KeyValuePair<SlotInfo, SlotContent>>();
foreach (KeyValuePair<SlotInfo, SlotContent> item in plan.Target)
{
SlotInfo key = item.Key;
SlotContent o = new SlotContent(key.Pid, key.Count);
if (!item.Value.Equals(o))
{
if (!o.IsEmpty)
{
list.Add(key);
Write(key, SlotContent.Empty);
}
if (!item.Value.IsEmpty)
{
toFill.Add(item);
}
}
}
flag = true;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Sort failed: " + ex));
foreach (SlotInfo item2 in list)
{
try
{
Write(item2, new SlotContent(item2.Pid, item2.Count));
}
catch (Exception ex2)
{
Plugin.Log.LogError((object)("Restore failed: " + ex2.Message));
}
}
Notifier.Show(Loc.T("error"));
}
finally
{
if (!flag)
{
IsSorting = false;
}
}
if (!flag)
{
yield break;
}
yield return (object)new WaitForSecondsRealtime(0.3f);
try
{
List<SlotContent> list3 = new List<SlotContent>();
foreach (KeyValuePair<SlotInfo, SlotContent> item3 in toFill)
{
if (Read(item3.Key).IsEmpty)
{
Write(item3.Key, item3.Value);
}
else
{
list3.Add(item3.Value);
}
}
int num = 0;
if (list3.Count > 0)
{
List<SlotInfo> list4 = plan.Target.Keys.Where((SlotInfo s) => Read(s).IsEmpty).ToList();
foreach (SlotContent item4 in list3)
{
if (list4.Count == 0)
{
num++;
continue;
}
Write(list4[0], item4);
list4.RemoveAt(0);
}
Plugin.Log.LogWarning((object)$"{list3.Count} box(es) re-homed because their slot was taken during the sort; {num} could not be placed.");
}
string text = ((plan.BoxesAfter < plan.BoxesBefore) ? Loc.T("sorted.merged", plan.BoxesBefore, plan.BoxesAfter) : "");
string text2 = ((Plugin.UseCategoryShelves.Value && OaoBridge.Available) ? Loc.T("sorted.category") : "");
Notifier.Show(Loc.T("sorted", plan.ChangedSlots, text2, text));
Plugin.Log.LogInfo((object)$"Sorted storage: boxes {plan.BoxesBefore}->{plan.BoxesAfter}, units {plan.UnitsBefore}, changed {plan.ChangedSlots}, lost {num}");
if (num > 0)
{
Notifier.Show(Loc.T("lost", num));
}
}
catch (Exception ex3)
{
Plugin.Log.LogError((object)("Sort failed during refill: " + ex3));
Notifier.Show(Loc.T("error"));
}
finally
{
IsSorting = false;
}
}
private static List<SlotInfo> Snapshot()
{
//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)
List<SlotInfo> list = new List<SlotInfo>();
NPC_Manager instance = NPC_Manager.Instance;
Transform transform = instance.storageOBJ.transform;
Vector3 refPoint = instance.storageDistanceReferencePoint;
int num = ProductListing.Instance.productsData.Length;
bool value = Plugin.UseCategoryShelves.Value;
List<Data_Container> list2 = new List<Data_Container>();
for (int i = 0; i < transform.childCount; i++)
{
Data_Container component = ((Component)transform.GetChild(i)).GetComponent<Data_Container>();
if ((Object)(object)component != (Object)null && component.containerClass == 69 && (Object)(object)((Component)component).transform.Find("BoxContainer") != (Object)null)
{
list2.Add(component);
}
}
list2 = list2.OrderBy((Data_Container c) => Vector3.Distance(refPoint, ((Component)c).transform.position)).ToList();
for (int num2 = 0; num2 < list2.Count; num2++)
{
Data_Container val = list2[num2];
int? category = (value ? OaoBridge.GetCategory(val) : ((int?)null));
int[] productInfoArray = val.productInfoArray;
Transform val2 = ((Component)val).transform.Find("BoxContainer");
int num3 = Math.Min(productInfoArray.Length / 2, val2.childCount);
for (int num4 = 0; num4 < num3; num4++)
{
int num5 = productInfoArray[num4 * 2];
int count = productInfoArray[num4 * 2 + 1];
list.Add(new SlotInfo
{
ShelfOrder = num2,
SlotIndex = num4,
Category = category,
Pid = num5,
Count = count,
Locked = (num5 >= num || num5 < -1),
Tag = new SlotRef
{
Container = val,
Index = num4
}
});
}
}
return list;
}
private static Dictionary<int, int> BuildProductGroups()
{
Dictionary<int, int> dictionary = new Dictionary<int, int>();
ProductListing instance = ProductListing.Instance;
if (instance.tiers == null || instance.productGroups == null)
{
return dictionary;
}
for (int i = 0; i < instance.tiers.Length && i < instance.productGroups.Length; i++)
{
string[] array = (instance.tiers[i] ?? "").Split(new char[1] { '-' });
if (array.Length != 2 || !int.TryParse(array[0], out var result) || !int.TryParse(array[1], out var result2))
{
continue;
}
int num = instance.productGroups[i];
if (num >= 0)
{
for (int j = result; j <= result2; j++)
{
dictionary[j] = num;
}
}
}
return dictionary;
}
private static SlotContent Read(SlotInfo s)
{
SlotRef slotRef = (SlotRef)s.Tag;
if ((Object)(object)slotRef.Container == (Object)null)
{
return new SlotContent(int.MinValue, int.MinValue);
}
int[] productInfoArray = slotRef.Container.productInfoArray;
return new SlotContent(productInfoArray[slotRef.Index * 2], productInfoArray[slotRef.Index * 2 + 1]);
}
private static void Write(SlotInfo s, SlotContent v)
{
SlotRef slotRef = (SlotRef)s.Tag;
if (!((Object)(object)slotRef.Container == (Object)null))
{
slotRef.Container.EmployeeUpdateArrayValuesStorage(slotRef.Index * 2, v.Pid, v.Count);
}
}
}
}