using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MarketCompass.Api;
using MarketCompass.Configuration;
using MarketCompass.Localization;
using MarketCompass.Network;
using MarketCompass.UI;
using MarketCompass.Utils;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MarketCompass")]
[assembly: AssemblyDescription("MarketCompass mod for Old Market Simulator by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("MarketCompass")]
[assembly: AssemblyCopyright("Copyright © 2025 Ice Box Studio All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("A3C8F8F1-9B0E-4B8E-9FAB-347D0B6D5231")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MarketCompass
{
[BepInPlugin("IceBoxStudio.MarketCompass", "MarketCompass", "1.0.0")]
public class MarketCompass : BaseUnityPlugin
{
private static MarketCompass _instance;
private Harmony _harmony;
private bool patchesApplied;
public static MarketCompass Instance => _instance;
internal static ManualLogSource Logger { get; private set; }
private void Awake()
{
_instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
try
{
Logger.LogInfo((object)"=============================================");
Logger.LogInfo((object)("MarketCompass " + LocalizationManager.Instance.GetLocalizedText("plugin.initializing")));
Logger.LogInfo((object)(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
ApplyPatches();
Logger.LogInfo((object)("MarketCompass " + LocalizationManager.Instance.GetLocalizedText("plugin.initialized")));
Logger.LogInfo((object)"=============================================");
}
catch (Exception ex)
{
Logger.LogError((object)("MarketCompass 初始化错误: " + ex.Message + "\n" + ex.StackTrace));
}
}
private void ApplyPatches()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
if (!patchesApplied)
{
try
{
_harmony = new Harmony("IceBoxStudio.MarketCompass");
_harmony.PatchAll();
patchesApplied = true;
return;
}
catch (Exception ex)
{
Logger.LogError((object)("MarketCompass 应用补丁错误: " + ex.Message + "\n" + ex.StackTrace));
return;
}
}
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped"));
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "IceBoxStudio.MarketCompass";
public const string PLUGIN_NAME = "MarketCompass";
public const string PLUGIN_VERSION = "1.0.0";
public const string PLUGIN_AUTHOR = "Ice Box Studio";
public const string PLUGIN_DESCRIPTION = "在 HUD 上显示指南针用于其他玩家和 NPC 的位置。";
}
}
namespace MarketCompass.Utils
{
public class EventPropsObserver : MonoBehaviour
{
private bool _scheduled;
private void Start()
{
if ((Object)(object)CompassHUD.Instance != (Object)null)
{
CompassHUD.Instance.ScheduleRescanSingle(delegate
{
_scheduled = false;
});
}
}
private void OnTransformChildrenChanged()
{
if (!((Object)(object)CompassHUD.Instance == (Object)null) && !_scheduled)
{
_scheduled = true;
CompassHUD.Instance.ScheduleRescanSingle(delegate
{
_scheduled = false;
});
}
}
}
public class CompassNPCManager
{
public struct NPCInfo
{
public Transform Transform;
public string Name;
public NPCType Type;
public Vector3 Position;
}
public enum NPCType
{
SeedSeller,
Recycler,
Pier,
AnimalDealer,
Breeder,
Lumberjack,
Engineer,
Decorator,
Clothier,
Employee,
Official,
Architect,
Museum,
Curator,
Caravan,
Plautia,
FarmFest,
HerbFest,
WaterLanternFest,
NewYear,
BlacksmithFestOne,
BlacksmithFestTwo,
Sakura,
PrimevalFestival,
IndependenceFest,
QixiFest,
KingdomFest,
GhostFest,
SilkRoadFestOne,
SilkRoadFestTwo,
SaturnFestProps,
LegionsDaysProps,
FlowerFestivalProps,
MarsDayProps,
LudiRomaniProps,
WartimesProps,
TradeFestPropsFabius,
TradeFestPropsMerchant,
HarvestFestProps,
AncestorFestProps,
Unknown
}
private readonly List<NPCInfo> _foundNPCs = new List<NPCInfo>();
private readonly Dictionary<string, List<(string name, NPCType type)>> _npcNameRegistry = new Dictionary<string, List<(string, NPCType)>>
{
{
"Any",
new List<(string, NPCType)>
{
("Garden Supply", NPCType.SeedSeller),
("Junkman", NPCType.Recycler),
("OrderMan", NPCType.Pier),
("Animal Market", NPCType.AnimalDealer),
("BREEDER", NPCType.Breeder),
("Lumberjack", NPCType.Lumberjack),
("Engineer", NPCType.Engineer),
("DecorationStore", NPCType.Decorator),
("Clothing Store", NPCType.Clothier),
("EmployeeStation", NPCType.Employee),
("State Officer", NPCType.Official),
("Architect", NPCType.Architect),
("Museum", NPCType.Museum),
("Curator", NPCType.Curator),
("Caravan", NPCType.Caravan),
("Plautia", NPCType.Plautia),
("woman-farm-wellies", NPCType.FarmFest),
("Characters_Knight-errant_Fmale", NPCType.HerbFest),
("Character_Male_Scholar_01", NPCType.WaterLanternFest),
("Character_Male_Official_01", NPCType.NewYear),
("Characters_Monk", NPCType.BlacksmithFestOne),
("Characters_Guard", NPCType.BlacksmithFestTwo),
("Characters_Guard", NPCType.Sakura),
("Character_Male_Beggar_01", NPCType.PrimevalFestival),
("Characters_Guard (2)", NPCType.IndependenceFest),
("Character_Female_Noblewoman_01", NPCType.QixiFest),
("Characters_Guard (2)", NPCType.KingdomFest),
("Character_Male_Scholar_01", NPCType.GhostFest),
("Character_Male_Farmer_01", NPCType.SilkRoadFestOne),
("Character_Female_Hotel Owner_01", NPCType.SilkRoadFestTwo),
("Cornelia", NPCType.SaturnFestProps),
("Marcus", NPCType.LegionsDaysProps),
("Livia", NPCType.FlowerFestivalProps),
("Decimus", NPCType.MarsDayProps),
("Quintus", NPCType.LudiRomaniProps),
("Domitia", NPCType.WartimesProps),
("Fabius", NPCType.TradeFestPropsFabius),
("Merchant", NPCType.TradeFestPropsMerchant),
("Marcia", NPCType.HarvestFestProps),
("Verginia", NPCType.AncestorFestProps)
}
},
{
"BazaarRome2",
new List<(string, NPCType)>
{
("BREEDER", NPCType.Breeder),
("CURATOR", NPCType.Curator),
("Plautia", NPCType.Plautia)
}
}
};
private readonly Dictionary<string, List<string>> _sceneBlacklist = new Dictionary<string, List<string>> {
{
"BazaarRome2",
new List<string> { "Animal Market", "Museum", "Caravan" }
} };
public void ScanForNPCs()
{
//IL_0077: 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_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
_foundNPCs.Clear();
GameObject val = GameObject.Find("Stores");
if ((Object)(object)val != (Object)null)
{
foreach (Transform item3 in val.transform)
{
Transform val2 = item3;
NPCType type = DetermineNPCType(val2);
AddNPC(val2, ((Object)val2).name, type);
}
}
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
if (_npcNameRegistry.TryGetValue(name, out List<(string, NPCType)> value))
{
foreach (var item4 in value)
{
string item = item4.Item1;
NPCType item2 = item4.Item2;
GameObject val3 = GameObject.Find(item);
if ((Object)(object)val3 != (Object)null)
{
AddNPC(val3.transform, item, item2);
}
}
}
if ((Object)(object)val == (Object)null)
{
foreach (var (text, type2) in _npcNameRegistry["Any"])
{
switch (text)
{
case "woman-farm-wellies":
case "Characters_Knight-errant_Fmale":
case "Character_Male_Scholar_01":
case "Character_Male_Official_01":
case "Characters_Monk":
case "Characters_Guard":
case "Characters_Guard (2)":
case "Character_Male_Beggar_01":
case "Character_Female_Noblewoman_01":
case "Character_Male_Farmer_01":
case "Character_Female_Hotel Owner_01":
case "Cornelia":
case "Marcus":
case "Livia":
case "Decimus":
case "Quintus":
case "Domitia":
case "Fabius":
case "Merchant":
case "Marcia":
case "Verginia":
continue;
}
GameObject val4 = GameObject.Find(text);
if ((Object)(object)val4 != (Object)null)
{
AddNPC(val4.transform, text, type2);
}
}
}
GameManager val5 = Object.FindObjectOfType<GameManager>();
if (!((Object)(object)val5 != (Object)null) || !((Object)(object)val5.eventProps != (Object)null))
{
return;
}
Transform[] componentsInChildren = ((Component)val5.eventProps.transform).GetComponentsInChildren<Transform>(true);
foreach (Transform val6 in componentsInChildren)
{
NPCType nPCType = DetermineNPCType(val6);
if (nPCType != NPCType.Unknown)
{
AddNPC(val6, ((Object)val6).name, nPCType);
}
}
}
private NPCType DetermineNPCType(Transform candidate)
{
string name = ((Object)candidate).name;
if (name.Contains("Garden Supply"))
{
return NPCType.SeedSeller;
}
if (name.Contains("Junkman"))
{
return NPCType.Recycler;
}
if (name.Contains("OrderMan"))
{
return NPCType.Pier;
}
if (name.Contains("Animal Market"))
{
return NPCType.AnimalDealer;
}
if (name.Contains("Lumberjack"))
{
return NPCType.Lumberjack;
}
if (name.Contains("Engineer"))
{
return NPCType.Engineer;
}
if (name.Contains("DecorationStore"))
{
return NPCType.Decorator;
}
if (name.Contains("Clothing Store"))
{
return NPCType.Clothier;
}
if (name.Contains("EmployeeStation"))
{
return NPCType.Employee;
}
if (name.Contains("State Officer"))
{
return NPCType.Official;
}
if (name.Contains("Architect"))
{
return NPCType.Architect;
}
if (name.Contains("Museum"))
{
return NPCType.Museum;
}
if (name.Contains("Caravan"))
{
return NPCType.Caravan;
}
if (name.Contains("woman-farm-wellies") && IsUnderEventStrict(candidate, "Farm&AnimalFest"))
{
return NPCType.FarmFest;
}
if (name.Contains("Characters_Knight-errant_Fmale") && IsUnderEventStrict(candidate, "HerbFest"))
{
return NPCType.HerbFest;
}
if (name.Contains("Character_Male_Scholar_01"))
{
if (IsUnderEventStrict(candidate, "Water Lantern Fest"))
{
return NPCType.WaterLanternFest;
}
if (IsUnderEventStrict(candidate, "Ghost Fest"))
{
return NPCType.GhostFest;
}
}
if (name.Contains("Character_Male_Official_01") && IsUnderEventStrict(candidate, "New Year"))
{
return NPCType.NewYear;
}
if (name.Contains("Characters_Monk") && IsUnderEventStrict(candidate, "Blacksmith Fest"))
{
return NPCType.BlacksmithFestOne;
}
if (name.Contains("Characters_Guard"))
{
if (IsUnderEventStrict(candidate, "Blacksmith Fest"))
{
return NPCType.BlacksmithFestTwo;
}
if (IsUnderEventStrict(candidate, "Sakura"))
{
return NPCType.Sakura;
}
}
if (name.Contains("Character_Male_Beggar_01") && IsUnderEventStrict(candidate, "Primeval Festival"))
{
return NPCType.PrimevalFestival;
}
if (name.Contains("Characters_Guard (2)"))
{
if (IsUnderEventStrict(candidate, "IndependenceFest"))
{
return NPCType.IndependenceFest;
}
if (IsUnderEventStrict(candidate, "Kingdom Fest"))
{
return NPCType.KingdomFest;
}
}
if (name.Contains("Character_Female_Noblewoman_01") && IsUnderEventStrict(candidate, "Qixi Fest") && HasHeartGlasses(candidate))
{
return NPCType.QixiFest;
}
if ((name.Contains("Character_Male_Farmer_01") || name.Contains("Character_Male_Farmer_02")) && IsUnderEventStrict(candidate, "Silk Road Fest"))
{
return NPCType.SilkRoadFestOne;
}
if (name.Contains("Character_Female_Hotel Owner_01") && IsUnderEventStrict(candidate, "Silk Road Fest"))
{
return NPCType.SilkRoadFestTwo;
}
if (name.Contains("Cornelia") && IsUnderEventStrict(candidate, "SaturnFestProps"))
{
return NPCType.SaturnFestProps;
}
if (name.Contains("Marcus") && IsUnderEventStrict(candidate, "LegionsDaysProps"))
{
return NPCType.LegionsDaysProps;
}
if (name.Contains("Livia") && IsUnderEventStrict(candidate, "FlowerFestivalProps"))
{
return NPCType.FlowerFestivalProps;
}
if (name.Contains("Decimus") && IsUnderEventStrict(candidate, "MarsDayProps"))
{
return NPCType.MarsDayProps;
}
if (name.Contains("Quintus") && IsUnderEventStrict(candidate, "LudiRomaniProps"))
{
return NPCType.LudiRomaniProps;
}
if (name.Contains("Domitia") && IsUnderEventStrict(candidate, "WartimesProps"))
{
return NPCType.WartimesProps;
}
if (name.Contains("Fabius") && IsUnderEventStrict(candidate, "TradeFestProps"))
{
return NPCType.TradeFestPropsFabius;
}
if (name.Contains("Merchant") && IsUnderEventStrict(candidate, "TradeFestProps"))
{
return NPCType.TradeFestPropsMerchant;
}
if (name.Contains("Marcia") && IsUnderEventStrict(candidate, "HarvestFestProps"))
{
return NPCType.HarvestFestProps;
}
if (name.Contains("Verginia") && IsUnderEventStrict(candidate, "AncestorFestProps"))
{
return NPCType.AncestorFestProps;
}
return NPCType.Unknown;
}
private bool IsUnderEventStrict(Transform t, string exactName)
{
Transform val = t;
while ((Object)(object)val != (Object)null)
{
if (string.Equals(StripCloneSuffix(((Object)val).name), exactName, StringComparison.Ordinal))
{
return true;
}
val = val.parent;
}
return false;
}
private string StripCloneSuffix(string name)
{
if (name != null && name.EndsWith("(Clone)", StringComparison.Ordinal))
{
return name.Substring(0, name.Length - "(Clone)".Length).TrimEnd(Array.Empty<char>());
}
return name;
}
private bool HasHeartGlasses(Transform root)
{
Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
string name = ((Object)componentsInChildren[i]).name;
if (!string.IsNullOrEmpty(name) && string.Equals(name, "glasses-heart-c", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private void AddNPC(Transform t, string name, NPCType type)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
string name2 = ((Scene)(ref activeScene)).name;
if (_sceneBlacklist.TryGetValue(name2, out var value))
{
foreach (string item in value)
{
if (name.Contains(item))
{
return;
}
}
}
Vector3 bestNPCPosition = GetBestNPCPosition(t);
Transform targetTransform = GetBestNPCTransform(t);
if (!_foundNPCs.Exists((NPCInfo n) => (Object)(object)n.Transform == (Object)(object)t) && !_foundNPCs.Exists((NPCInfo n) => (Object)(object)n.Transform == (Object)(object)targetTransform))
{
_foundNPCs.Add(new NPCInfo
{
Transform = targetTransform,
Name = name,
Type = type,
Position = bestNPCPosition
});
}
}
private Transform GetBestNPCTransform(Transform root)
{
return root;
}
private Vector3 GetBestNPCPosition(Transform root)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
SkinnedMeshRenderer componentInChildren = ((Component)root).GetComponentInChildren<SkinnedMeshRenderer>();
if ((Object)(object)componentInChildren != (Object)null)
{
Bounds bounds = ((Renderer)componentInChildren).bounds;
return ((Bounds)(ref bounds)).center;
}
return root.position;
}
private Transform FindChildRecursive(Transform parent, string keyword)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
foreach (Transform item in parent)
{
Transform val = item;
if (((Object)val).name.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0)
{
return val;
}
Transform val2 = FindChildRecursive(val, keyword);
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
return null;
}
public List<NPCInfo> GetNPCs()
{
_foundNPCs.RemoveAll((NPCInfo n) => (Object)(object)n.Transform == (Object)null);
return _foundNPCs;
}
}
}
namespace MarketCompass.UI
{
public class CompassHUD : MonoBehaviour
{
[CompilerGenerated]
private sealed class <SingleScanRoutine>d__12 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public CompassHUD <>4__this;
public Action onCompleted;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SingleScanRoutine>d__12(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
int num = <>1__state;
CompassHUD compassHUD = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
compassHUD._npcManager?.ScanForNPCs();
compassHUD._rescanCoroutine = null;
onCompleted?.Invoke();
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <SingleScanRoutineWithDelay>d__13 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float delaySeconds;
public CompassHUD <>4__this;
public Action onCompleted;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SingleScanRoutineWithDelay>d__13(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
int num = <>1__state;
CompassHUD compassHUD = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
if (delaySeconds > 0f)
{
<>2__current = (object)new WaitForSeconds(delaySeconds);
<>1__state = 1;
return true;
}
break;
case 1:
<>1__state = -1;
break;
}
compassHUD._npcManager?.ScanForNPCs();
compassHUD._rescanCoroutine = null;
onCompleted?.Invoke();
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private bool _isNetworkBound;
private NetworkManager _boundNetworkManager;
private CompassNPCManager _npcManager;
private Coroutine _rescanCoroutine;
private Texture2D _compassBackground;
private Texture2D _playerIcon;
private Texture2D _indicatorTexture;
private Texture2D _externalMarkerIcon;
private Dictionary<CompassNPCManager.NPCType, Texture2D> _npcIcons;
private bool _hasLoggedMissingPlayer;
private GUIStyle _textStyle;
private Font _gameFont;
private readonly Dictionary<int, string> _directions = new Dictionary<int, string>
{
{ 0, "compass.N" },
{ 45, "compass.NE" },
{ 90, "compass.E" },
{ 135, "compass.SE" },
{ 180, "compass.S" },
{ 225, "compass.SW" },
{ 270, "compass.W" },
{ 315, "compass.NW" }
};
private readonly Dictionary<CompassNPCManager.NPCType, long> _npcNameIds = new Dictionary<CompassNPCManager.NPCType, long>
{
{
CompassNPCManager.NPCType.SeedSeller,
16056656363966464L
},
{
CompassNPCManager.NPCType.Recycler,
36361828344451072L
},
{
CompassNPCManager.NPCType.Pier,
16056274690691072L
},
{
CompassNPCManager.NPCType.AnimalDealer,
25455517276753920L
},
{
CompassNPCManager.NPCType.Breeder,
210249756352462852L
},
{
CompassNPCManager.NPCType.Lumberjack,
16056114128539648L
},
{
CompassNPCManager.NPCType.Engineer,
63143313185361920L
},
{
CompassNPCManager.NPCType.Decorator,
16055743041687552L
},
{
CompassNPCManager.NPCType.Clothier,
49981228624564224L
},
{
CompassNPCManager.NPCType.Employee,
16057080919805952L
},
{
CompassNPCManager.NPCType.Official,
16055893273268224L
},
{
CompassNPCManager.NPCType.Architect,
16055953692217344L
},
{
CompassNPCManager.NPCType.Museum,
136323097201135616L
},
{
CompassNPCManager.NPCType.Curator,
210249756352462849L
},
{
CompassNPCManager.NPCType.Caravan,
210249756352463039L
},
{
CompassNPCManager.NPCType.Plautia,
210336787878154240L
},
{
CompassNPCManager.NPCType.FarmFest,
16405809245900800L
},
{
CompassNPCManager.NPCType.HerbFest,
17487577394892800L
},
{
CompassNPCManager.NPCType.WaterLanternFest,
103796580965601280L
},
{
CompassNPCManager.NPCType.NewYear,
103796656790228992L
},
{
CompassNPCManager.NPCType.BlacksmithFestOne,
103796674456637440L
},
{
CompassNPCManager.NPCType.BlacksmithFestTwo,
103796674456637440L
},
{
CompassNPCManager.NPCType.Sakura,
104360126644408320L
},
{
CompassNPCManager.NPCType.PrimevalFestival,
16406657774571520L
},
{
CompassNPCManager.NPCType.IndependenceFest,
16406306174455808L
},
{
CompassNPCManager.NPCType.QixiFest,
104360290029326336L
},
{
CompassNPCManager.NPCType.KingdomFest,
104360313177690112L
},
{
CompassNPCManager.NPCType.GhostFest,
104360356714565632L
},
{
CompassNPCManager.NPCType.SilkRoadFestOne,
104360417141903360L
},
{
CompassNPCManager.NPCType.SilkRoadFestTwo,
104360417141903360L
},
{
CompassNPCManager.NPCType.SaturnFestProps,
210249756352463023L
},
{
CompassNPCManager.NPCType.LegionsDaysProps,
210249756352463024L
},
{
CompassNPCManager.NPCType.FlowerFestivalProps,
210249756352463026L
},
{
CompassNPCManager.NPCType.MarsDayProps,
210249756352463027L
},
{
CompassNPCManager.NPCType.LudiRomaniProps,
210249756352463028L
},
{
CompassNPCManager.NPCType.WartimesProps,
210249756352463029L
},
{
CompassNPCManager.NPCType.TradeFestPropsFabius,
210249756352463030L
},
{
CompassNPCManager.NPCType.TradeFestPropsMerchant,
210249756352463077L
},
{
CompassNPCManager.NPCType.HarvestFestProps,
210249756352463031L
},
{
CompassNPCManager.NPCType.AncestorFestProps,
210249756352463032L
}
};
private readonly Dictionary<long, string> _cachedGameStrings = new Dictionary<long, string>();
private readonly HashSet<long> _loadingStringIds = new HashSet<long>();
private readonly Dictionary<CompassNPCManager.NPCType, CompassNPCManager.NPCType> _npcPrefixMap = new Dictionary<CompassNPCManager.NPCType, CompassNPCManager.NPCType>
{
{
CompassNPCManager.NPCType.Breeder,
CompassNPCManager.NPCType.AnimalDealer
},
{
CompassNPCManager.NPCType.Curator,
CompassNPCManager.NPCType.Museum
},
{
CompassNPCManager.NPCType.Plautia,
CompassNPCManager.NPCType.Caravan
}
};
private readonly Dictionary<CompassNPCManager.NPCType, long> _npcPrefixIdMap = new Dictionary<CompassNPCManager.NPCType, long>
{
{
CompassNPCManager.NPCType.SaturnFestProps,
210249756352463073L
},
{
CompassNPCManager.NPCType.LegionsDaysProps,
210249756352463074L
},
{
CompassNPCManager.NPCType.FlowerFestivalProps,
16406125144100864L
},
{
CompassNPCManager.NPCType.MarsDayProps,
210249756352463075L
},
{
CompassNPCManager.NPCType.LudiRomaniProps,
210249756352463076L
},
{
CompassNPCManager.NPCType.WartimesProps,
17488805013147648L
},
{
CompassNPCManager.NPCType.TradeFestPropsFabius,
210249756352463077L
},
{
CompassNPCManager.NPCType.HarvestFestProps,
210249756352463078L
},
{
CompassNPCManager.NPCType.AncestorFestProps,
210249756352463079L
}
};
public static CompassHUD Instance { get; private set; }
private void Awake()
{
if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
{
Object.Destroy((Object)(object)this);
return;
}
Instance = this;
_npcManager = new CompassNPCManager();
GenerateCompassTextures();
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void Update()
{
if ((Object)(object)NetworkManager.Singleton != (Object)null && !_isNetworkBound)
{
BindNetworkManager();
}
else if ((Object)(object)NetworkManager.Singleton == (Object)null && _isNetworkBound)
{
UnbindNetworkManager();
}
}
public void ScheduleRescan()
{
if (_rescanCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_rescanCoroutine);
}
_rescanCoroutine = ((MonoBehaviour)this).StartCoroutine(SingleScanRoutine(null));
}
public void ScheduleRescanSingle(Action onCompleted)
{
if (_rescanCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_rescanCoroutine);
}
_rescanCoroutine = ((MonoBehaviour)this).StartCoroutine(SingleScanRoutine(onCompleted));
}
[IteratorStateMachine(typeof(<SingleScanRoutine>d__12))]
private IEnumerator SingleScanRoutine(Action onCompleted)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SingleScanRoutine>d__12(0)
{
<>4__this = this,
onCompleted = onCompleted
};
}
[IteratorStateMachine(typeof(<SingleScanRoutineWithDelay>d__13))]
private IEnumerator SingleScanRoutineWithDelay(float delaySeconds, Action onCompleted)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SingleScanRoutineWithDelay>d__13(0)
{
<>4__this = this,
delaySeconds = delaySeconds,
onCompleted = onCompleted
};
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
SceneManager.sceneLoaded -= OnSceneLoaded;
UnbindNetworkManager();
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (_npcManager != null)
{
_npcManager.ScanForNPCs();
EnsureEventPropsObserver();
}
}
private void BindNetworkManager()
{
_boundNetworkManager = NetworkManager.Singleton;
if ((Object)(object)_boundNetworkManager != (Object)null)
{
_boundNetworkManager.OnClientStarted += OnClientStarted;
_boundNetworkManager.OnClientStopped += OnClientStopped;
_isNetworkBound = true;
if (_boundNetworkManager.IsClient || _boundNetworkManager.IsServer)
{
OnClientStarted();
}
}
}
private void UnbindNetworkManager()
{
if ((Object)(object)_boundNetworkManager != (Object)null)
{
_boundNetworkManager.OnClientStarted -= OnClientStarted;
_boundNetworkManager.OnClientStopped -= OnClientStopped;
}
CompassNetworkManager.Shutdown();
_boundNetworkManager = null;
_isNetworkBound = false;
}
private void OnClientStarted()
{
CompassNetworkManager.Initialize();
_npcManager?.ScanForNPCs();
EnsureEventPropsObserver();
}
public void EnsureEventPropsObserver()
{
GameManager val = Object.FindObjectOfType<GameManager>();
if ((Object)(object)val != (Object)null && (Object)(object)val.eventProps != (Object)null && (Object)(object)val.eventProps.GetComponent<EventPropsObserver>() == (Object)null)
{
val.eventProps.AddComponent<EventPropsObserver>();
}
}
private void OnClientStopped(bool _)
{
CompassNetworkManager.Shutdown();
}
private string GetLocalizedNPCName(CompassNPCManager.NPCType type, string defaultName)
{
string localizedBasicName = GetLocalizedBasicName(type, defaultName);
if (_npcPrefixMap.TryGetValue(type, out var value))
{
string localizedBasicName2 = GetLocalizedBasicName(value, null);
if (!string.IsNullOrEmpty(localizedBasicName2))
{
return localizedBasicName2 + " - " + localizedBasicName;
}
}
if (_npcPrefixIdMap.TryGetValue(type, out var value2))
{
string localizedText = GetLocalizedText(value2);
if (!string.IsNullOrEmpty(localizedText))
{
return localizedText + " - " + localizedBasicName;
}
}
return localizedBasicName;
}
private string GetLocalizedBasicName(CompassNPCManager.NPCType type, string defaultName)
{
if (_npcNameIds.TryGetValue(type, out var value))
{
return GetLocalizedText(value, defaultName);
}
return defaultName;
}
private string GetLocalizedText(long id, string defaultText = null)
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (_cachedGameStrings.TryGetValue(id, out var value))
{
return value;
}
if (!_loadingStringIds.Contains(id))
{
_loadingStringIds.Add(id);
try
{
AsyncOperationHandle<string> localizedStringAsync = LocalizationSettings.StringDatabase.GetLocalizedStringAsync(TableReference.op_Implicit("Translations"), TableEntryReference.op_Implicit(id), (Locale)null, (FallbackBehavior)0, Array.Empty<object>());
localizedStringAsync.Completed += delegate(AsyncOperationHandle<string> handle)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Invalid comparison between Unknown and I4
if ((int)handle.Status == 1)
{
string text = handle.Result;
if (id == 210249756352463039L)
{
text = Regex.Replace(text, "\\d", "").Trim();
}
_cachedGameStrings[id] = text;
}
else if (!string.IsNullOrEmpty(defaultText))
{
_cachedGameStrings[id] = defaultText;
}
_loadingStringIds.Remove(id);
};
}
catch
{
_loadingStringIds.Remove(id);
}
}
return defaultText;
}
private void LoadGameFont()
{
if (!((Object)(object)UIManager.Instance != (Object)null))
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(typeof(UIManager), "textCoins");
if (!(fieldInfo != null))
{
return;
}
object value = fieldInfo.GetValue(UIManager.Instance);
if (value != null)
{
TextMeshProUGUI val = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null);
if (val != null && (Object)(object)((TMP_Text)val).font != (Object)null && (Object)(object)((TMP_Text)val).font.sourceFontFile != (Object)null)
{
_gameFont = ((TMP_Text)val).font.sourceFontFile;
}
}
}
private void GenerateCompassTextures()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: 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_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Expected O, but got Unknown
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Expected O, but got Unknown
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_028c: Unknown result type (might be due to invalid IL or missing references)
//IL_0285: Unknown result type (might be due to invalid IL or missing references)
int num = 1024;
int num2 = 48;
_compassBackground = new Texture2D(num, num2);
Color clear = Color.clear;
for (int i = 0; i < num2; i++)
{
for (int j = 0; j < num; j++)
{
_compassBackground.SetPixel(j, i, clear);
}
}
Color white = Color.white;
Color val = default(Color);
((Color)(ref val))..ctor(1f, 1f, 1f, 0.6f);
float num3 = (float)num / 360f;
for (int k = 0; k < 360; k += 5)
{
int num4 = Mathf.RoundToInt((float)k * num3);
Color val2 = val;
int num5;
int num6;
if (k % 90 == 0)
{
num5 = 15;
num6 = 3;
val2 = white;
}
else if (k % 45 == 0)
{
num5 = 10;
num6 = 2;
val2 = white;
}
else if (k % 15 == 0)
{
num5 = 7;
num6 = 1;
}
else
{
num5 = 4;
num6 = 1;
((Color)(ref val2))..ctor(1f, 1f, 1f, 0.3f);
}
for (int l = 0; l < num6; l++)
{
for (int m = 0; m < num5; m++)
{
int num7 = (num4 + l) % num;
_compassBackground.SetPixel(num7, m, val2);
}
}
}
_compassBackground.Apply();
((Texture)_compassBackground).wrapMode = (TextureWrapMode)0;
_playerIcon = LoadNPCIcon("icon_player.png");
int num8 = 16;
int num9 = 12;
_indicatorTexture = new Texture2D(num8, num9);
Color val3 = default(Color);
((Color)(ref val3))..ctor(1f, 0.8f, 0f, 1f);
for (int n = 0; n < num9; n++)
{
for (int num10 = 0; num10 < num8; num10++)
{
float num11 = (float)n / (float)(num9 - 1) * ((float)num8 / 2f);
if (Mathf.Abs((float)num10 - (float)num8 / 2f) <= num11)
{
_indicatorTexture.SetPixel(num10, n, val3);
}
else
{
_indicatorTexture.SetPixel(num10, n, Color.clear);
}
}
}
_indicatorTexture.Apply();
int num12 = 16;
int num13 = 16;
_externalMarkerIcon = new Texture2D(num12, num13);
Color val4 = default(Color);
((Color)(ref val4))..ctor(0f, 0.85f, 1f, 1f);
float num14 = (float)(num12 - 1) / 2f;
float num15 = num14 * num14;
for (int num16 = 0; num16 < num13; num16++)
{
for (int num17 = 0; num17 < num12; num17++)
{
float num18 = (float)num17 - num14;
float num19 = (float)num16 - num14;
float num20 = num18 * num18 + num19 * num19;
_externalMarkerIcon.SetPixel(num17, num16, (num20 <= num15) ? val4 : Color.clear);
}
}
_externalMarkerIcon.Apply();
_npcIcons = new Dictionary<CompassNPCManager.NPCType, Texture2D>
{
[CompassNPCManager.NPCType.SeedSeller] = LoadNPCIcon("icon_seed_seller.png"),
[CompassNPCManager.NPCType.Recycler] = LoadNPCIcon("icon_recycler.png"),
[CompassNPCManager.NPCType.Pier] = LoadNPCIcon("icon_pier.png"),
[CompassNPCManager.NPCType.AnimalDealer] = LoadNPCIcon("icon_animal_dealer.png"),
[CompassNPCManager.NPCType.Breeder] = LoadNPCIcon("icon_animal_dealer.png"),
[CompassNPCManager.NPCType.Lumberjack] = LoadNPCIcon("icon_lumberjack.png"),
[CompassNPCManager.NPCType.Engineer] = LoadNPCIcon("icon_engineer.png"),
[CompassNPCManager.NPCType.Decorator] = LoadNPCIcon("icon_decorator.png"),
[CompassNPCManager.NPCType.Clothier] = LoadNPCIcon("icon_clothier.png"),
[CompassNPCManager.NPCType.Employee] = LoadNPCIcon("icon_employee.png"),
[CompassNPCManager.NPCType.Official] = LoadNPCIcon("icon_official.png"),
[CompassNPCManager.NPCType.Architect] = LoadNPCIcon("icon_architect.png"),
[CompassNPCManager.NPCType.Museum] = LoadNPCIcon("icon_museum.png"),
[CompassNPCManager.NPCType.Curator] = LoadNPCIcon("icon_museum.png"),
[CompassNPCManager.NPCType.Caravan] = LoadNPCIcon("icon_caravan.png"),
[CompassNPCManager.NPCType.Plautia] = LoadNPCIcon("icon_caravan.png"),
[CompassNPCManager.NPCType.FarmFest] = LoadNPCIcon("icon_farm_fest.png"),
[CompassNPCManager.NPCType.HerbFest] = LoadNPCIcon("icon_herb_fest.png"),
[CompassNPCManager.NPCType.WaterLanternFest] = LoadNPCIcon("icon_water_lantern_fest.png"),
[CompassNPCManager.NPCType.NewYear] = LoadNPCIcon("icon_new_year.png"),
[CompassNPCManager.NPCType.BlacksmithFestOne] = LoadNPCIcon("icon_blacksmith_fest.png"),
[CompassNPCManager.NPCType.BlacksmithFestTwo] = LoadNPCIcon("icon_blacksmith_fest.png"),
[CompassNPCManager.NPCType.Sakura] = LoadNPCIcon("icon_sakura.png"),
[CompassNPCManager.NPCType.PrimevalFestival] = LoadNPCIcon("icon_primeval_festival.png"),
[CompassNPCManager.NPCType.IndependenceFest] = LoadNPCIcon("icon_independence_fest.png"),
[CompassNPCManager.NPCType.QixiFest] = LoadNPCIcon("icon_qixi_fest.png"),
[CompassNPCManager.NPCType.KingdomFest] = LoadNPCIcon("icon_kingdom_fest.png"),
[CompassNPCManager.NPCType.GhostFest] = LoadNPCIcon("icon_ghost_fest.png"),
[CompassNPCManager.NPCType.SilkRoadFestOne] = LoadNPCIcon("icon_silk_road_fest.png"),
[CompassNPCManager.NPCType.SilkRoadFestTwo] = LoadNPCIcon("icon_silk_road_fest.png"),
[CompassNPCManager.NPCType.SaturnFestProps] = LoadNPCIcon("icon_saturn_fest.png"),
[CompassNPCManager.NPCType.LegionsDaysProps] = LoadNPCIcon("icon_legions_days.png"),
[CompassNPCManager.NPCType.FlowerFestivalProps] = LoadNPCIcon("icon_flower_fest.png"),
[CompassNPCManager.NPCType.MarsDayProps] = LoadNPCIcon("icon_mars_day.png"),
[CompassNPCManager.NPCType.LudiRomaniProps] = LoadNPCIcon("icon_ludi_romani.png"),
[CompassNPCManager.NPCType.WartimesProps] = LoadNPCIcon("icon_war_times.png"),
[CompassNPCManager.NPCType.TradeFestPropsFabius] = LoadNPCIcon("icon_trade_fest.png"),
[CompassNPCManager.NPCType.TradeFestPropsMerchant] = LoadNPCIcon("icon_trade_fest.png"),
[CompassNPCManager.NPCType.HarvestFestProps] = LoadNPCIcon("icon_harvest_fest.png"),
[CompassNPCManager.NPCType.AncestorFestProps] = LoadNPCIcon("icon_ancestor_fest.png")
};
}
private Texture2D LoadNPCIcon(string filename)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
string name = "MarketCompass.Assets.Icons." + filename;
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
if (stream != null)
{
byte[] array = new byte[stream.Length];
stream.Read(array, 0, (int)stream.Length);
Texture2D val = new Texture2D(2, 2);
if (ImageConversion.LoadImage(val, array))
{
((Texture)val).filterMode = (FilterMode)0;
return val;
}
}
}
return null;
}
private void OnGUI()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
if ((int)Event.current.type != 7)
{
return;
}
if ((Object)(object)_gameFont == (Object)null)
{
LoadGameFont();
}
if (_textStyle == null)
{
_textStyle = new GUIStyle(GUI.skin.label)
{
alignment = (TextAnchor)1,
fontSize = 12,
fontStyle = (FontStyle)1
};
_textStyle.normal.textColor = Color.white;
if ((Object)(object)_gameFont != (Object)null)
{
_textStyle.font = _gameFont;
}
}
else if ((Object)(object)_textStyle.font == (Object)null && (Object)(object)_gameFont != (Object)null)
{
_textStyle.font = _gameFont;
}
Transform localPlayerTransform = GetLocalPlayerTransform();
if ((Object)(object)localPlayerTransform == (Object)null)
{
if (!_hasLoggedMissingPlayer && Time.frameCount % 300 == 0)
{
_hasLoggedMissingPlayer = true;
}
return;
}
if (_hasLoggedMissingPlayer)
{
_hasLoggedMissingPlayer = false;
}
DrawCompass(localPlayerTransform);
}
private Transform GetLocalPlayerTransform()
{
if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.LocalClient != null && (Object)(object)NetworkManager.Singleton.LocalClient.PlayerObject != (Object)null)
{
return ((Component)NetworkManager.Singleton.LocalClient.PlayerObject).transform;
}
return null;
}
private void DrawCompass(Transform player)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
float y = player.eulerAngles.y;
float num = 180f;
float num2 = 600f;
float num3 = 48f;
float num4 = ((float)Screen.width - num2) / 2f;
float num5 = 10f;
float num6 = num / 360f;
float num7 = y / 360f - num6 / 2f;
Rect val = default(Rect);
((Rect)(ref val))..ctor(num4, num5, num2, num3);
Rect val2 = default(Rect);
((Rect)(ref val2))..ctor(num7, 0f, num6, 1f);
GUI.DrawTextureWithTexCoords(val, (Texture)(object)_compassBackground, val2);
DrawDirectionLabels(val, num, y);
float num8 = 16f;
float num9 = 12f;
GUI.DrawTexture(new Rect(num4 + (num2 - num8) / 2f, num5 + num3 + 2f, num8, num9), (Texture)(object)_indicatorTexture);
DrawOtherPlayers(player, val, num);
DrawNPCs(player, val, num);
DrawExternalMarkers(player, val, num);
}
private void DrawExternalMarkers(Transform localPlayer, Rect compassRect, float visibleFOV)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//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)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Expected O, but got Unknown
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_022c: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
ExternalMarkerAPI.ExternalMarker[] allMarkers = ExternalMarkerAPI.GetAllMarkers();
if (allMarkers == null || allMarkers.Length == 0)
{
return;
}
float y = localPlayer.eulerAngles.y;
ExternalMarkerAPI.ExternalMarker[] array = allMarkers;
Rect val2 = default(Rect);
Rect val4 = default(Rect);
for (int i = 0; i < array.Length; i++)
{
ExternalMarkerAPI.ExternalMarker externalMarker = array[i];
Vector3 val = externalMarker.Position - localPlayer.position;
val.y = 0f;
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
continue;
}
float num = Vector3.SignedAngle(Vector3.forward, val, Vector3.up);
float num2 = Mathf.DeltaAngle(y, num);
if (!(Mathf.Abs(num2) > visibleFOV / 2f))
{
float num3 = (num2 + visibleFOV / 2f) / visibleFOV;
float num4 = ((Rect)(ref compassRect)).x + num3 * ((Rect)(ref compassRect)).width;
float num5 = 18f;
((Rect)(ref val2))..ctor(num4 - num5 / 2f, ((Rect)(ref compassRect)).y + ((Rect)(ref compassRect)).height - num5 - 2f, num5, num5);
if ((Object)(object)_externalMarkerIcon != (Object)null)
{
GUI.DrawTexture(val2, (Texture)(object)_externalMarkerIcon);
}
float num6 = Vector3.Distance(localPlayer.position, externalMarker.Position);
if (num6 <= ConfigManager.NPCNameDistance.Value)
{
string arg = (string.IsNullOrEmpty(externalMarker.Name) ? externalMarker.Id : externalMarker.Name);
string text = $"{arg}\n{num6:F0}m";
Vector2 val3 = _textStyle.CalcSize(new GUIContent(text));
((Rect)(ref val4))..ctor(num4 - val3.x / 2f, ((Rect)(ref compassRect)).y + ((Rect)(ref compassRect)).height + 5f, val3.x, val3.y);
Color textColor = _textStyle.normal.textColor;
_textStyle.normal.textColor = Color.black;
GUI.Label(new Rect(((Rect)(ref val4)).x + 1f, ((Rect)(ref val4)).y + 1f, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height), text, _textStyle);
_textStyle.normal.textColor = new Color(0.9f, 0.9f, 0.9f);
GUI.Label(val4, text, _textStyle);
_textStyle.normal.textColor = textColor;
}
}
}
}
private void DrawNPCs(Transform localPlayer, Rect compassRect, float visibleFOV)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: 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_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Expected O, but got Unknown
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_023e: Unknown result type (might be due to invalid IL or missing references)
//IL_026a: Unknown result type (might be due to invalid IL or missing references)
//IL_0274: Unknown result type (might be due to invalid IL or missing references)
//IL_028e: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
if (_npcManager == null)
{
return;
}
List<CompassNPCManager.NPCInfo> nPCs = _npcManager.GetNPCs();
float y = localPlayer.eulerAngles.y;
Rect val2 = default(Rect);
Rect val4 = default(Rect);
foreach (CompassNPCManager.NPCInfo item in nPCs)
{
if ((Object)(object)item.Transform == (Object)null)
{
continue;
}
bool flag = IsFestivalNPC(item.Type);
if ((flag && !ConfigManager.ShowFestivalNPCs.Value) || (!flag && !ConfigManager.ShowNPCs.Value))
{
continue;
}
Vector3 val = item.Position - localPlayer.position;
val.y = 0f;
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
continue;
}
float num = Vector3.SignedAngle(Vector3.forward, val, Vector3.up);
float num2 = Mathf.DeltaAngle(y, num);
if (Mathf.Abs(num2) <= visibleFOV / 2f)
{
float num3 = (num2 + visibleFOV / 2f) / visibleFOV;
float num4 = ((Rect)(ref compassRect)).x + num3 * ((Rect)(ref compassRect)).width;
float num5 = 20f;
((Rect)(ref val2))..ctor(num4 - num5 / 2f, ((Rect)(ref compassRect)).y + ((Rect)(ref compassRect)).height - num5 - 2f, num5, num5);
if (_npcIcons.TryGetValue(item.Type, out var value) && (Object)(object)value != (Object)null)
{
GUI.DrawTexture(val2, (Texture)(object)value);
}
float num6 = Vector3.Distance(localPlayer.position, item.Position);
if (num6 <= ConfigManager.NPCNameDistance.Value)
{
string localizedNPCName = GetLocalizedNPCName(item.Type, item.Name);
string text = $"{localizedNPCName}\n{num6:F0}m";
Vector2 val3 = _textStyle.CalcSize(new GUIContent(text));
((Rect)(ref val4))..ctor(num4 - val3.x / 2f, ((Rect)(ref compassRect)).y + ((Rect)(ref compassRect)).height + 5f, val3.x, val3.y);
Color textColor = _textStyle.normal.textColor;
_textStyle.normal.textColor = Color.black;
GUI.Label(new Rect(((Rect)(ref val4)).x + 1f, ((Rect)(ref val4)).y + 1f, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height), text, _textStyle);
_textStyle.normal.textColor = new Color(0.9f, 0.9f, 0.9f);
GUI.Label(val4, text, _textStyle);
_textStyle.normal.textColor = textColor;
}
}
}
}
private bool IsFestivalNPC(CompassNPCManager.NPCType type)
{
if (type >= CompassNPCManager.NPCType.FarmFest)
{
return type < CompassNPCManager.NPCType.Unknown;
}
return false;
}
private void DrawDirectionLabels(Rect compassRect, float visibleFOV, float playerAngle)
{
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Expected O, but got Unknown
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
Rect val2 = default(Rect);
foreach (KeyValuePair<int, string> direction in _directions)
{
float num = direction.Key;
string value = direction.Value;
string localizedText = LocalizationManager.Instance.GetLocalizedText(value);
float num2 = Mathf.DeltaAngle(playerAngle, num);
if (Mathf.Abs(num2) <= visibleFOV / 2f)
{
float num3 = (num2 + visibleFOV / 2f) / visibleFOV;
float num4 = ((Rect)(ref compassRect)).x + num3 * ((Rect)(ref compassRect)).width;
bool flag = direction.Key % 90 == 0;
_textStyle.fontSize = (flag ? 20 : 14);
_textStyle.fontStyle = (FontStyle)(flag ? 1 : 0);
_textStyle.normal.textColor = (flag ? new Color(1f, 0.84f, 0f) : new Color(0.9f, 0.9f, 0.8f, 0.9f));
Vector2 val = _textStyle.CalcSize(new GUIContent(localizedText));
float num5 = ((Rect)(ref compassRect)).y + 5f;
((Rect)(ref val2))..ctor(num4 - val.x / 2f, num5, val.x, val.y);
Color textColor = _textStyle.normal.textColor;
_textStyle.normal.textColor = new Color(0f, 0f, 0f, 0.8f);
GUI.Label(new Rect(((Rect)(ref val2)).x + 1f, ((Rect)(ref val2)).y + 1f, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height), localizedText, _textStyle);
_textStyle.normal.textColor = textColor;
GUI.Label(val2, localizedText, _textStyle);
_textStyle.fontSize = 12;
_textStyle.fontStyle = (FontStyle)1;
_textStyle.normal.textColor = Color.white;
}
}
}
private void DrawOtherPlayers(Transform localPlayer, Rect compassRect, float visibleFOV)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Expected O, but got Unknown
//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0237: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
//IL_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_0298: Unknown result type (might be due to invalid IL or missing references)
//IL_029f: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
if (!ConfigManager.ShowPlayers.Value || (Object)(object)NetworkManager.Singleton == (Object)null || NetworkManager.Singleton.SpawnManager == null)
{
return;
}
HashSet<NetworkObject> spawnedObjectsList = NetworkManager.Singleton.SpawnManager.SpawnedObjectsList;
float y = localPlayer.eulerAngles.y;
Rect val2 = default(Rect);
Rect val4 = default(Rect);
foreach (NetworkObject item in spawnedObjectsList)
{
if ((Object)(object)item == (Object)null || !item.IsPlayerObject || item.OwnerClientId == NetworkManager.Singleton.LocalClientId || (Object)(object)((Component)item).transform == (Object)null)
{
continue;
}
Transform transform = ((Component)item).transform;
ulong ownerClientId = item.OwnerClientId;
Vector3 val = transform.position - localPlayer.position;
val.y = 0f;
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
continue;
}
float num = Vector3.SignedAngle(Vector3.forward, val, Vector3.up);
float num2 = Mathf.DeltaAngle(y, num);
if (Mathf.Abs(num2) <= visibleFOV / 2f)
{
float num3 = (num2 + visibleFOV / 2f) / visibleFOV;
float num4 = ((Rect)(ref compassRect)).x + num3 * ((Rect)(ref compassRect)).width;
float num5 = 20f;
((Rect)(ref val2))..ctor(num4 - num5 / 2f, ((Rect)(ref compassRect)).y + ((Rect)(ref compassRect)).height - num5 - 2f, num5, num5);
Color playerColor = GetPlayerColor(ownerClientId);
Color color = GUI.color;
GUI.color = playerColor;
if ((Object)(object)_playerIcon != (Object)null)
{
GUI.DrawTexture(val2, (Texture)(object)_playerIcon);
}
GUI.color = color;
float num6 = Vector3.Distance(localPlayer.position, transform.position);
float value = ConfigManager.PlayerNameDistance.Value;
if (value < 0f || num6 <= value)
{
string playerName = CompassNetworkManager.GetPlayerName(ownerClientId);
string text = $"{playerName}\n{num6:F1}m";
Vector2 val3 = _textStyle.CalcSize(new GUIContent(text));
((Rect)(ref val4))..ctor(num4 - val3.x / 2f, ((Rect)(ref compassRect)).y + ((Rect)(ref compassRect)).height + 5f, val3.x, val3.y);
Color textColor = _textStyle.normal.textColor;
_textStyle.normal.textColor = Color.black;
GUI.Label(new Rect(((Rect)(ref val4)).x + 1f, ((Rect)(ref val4)).y + 1f, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height), text, _textStyle);
_textStyle.normal.textColor = playerColor;
GUI.Label(val4, text, _textStyle);
_textStyle.normal.textColor = textColor;
}
}
}
}
private Color GetPlayerColor(ulong clientId)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
return Color.HSVToRGB((float)clientId * 0.618034f % 1f, 0.8f, 0.95f);
}
}
}
namespace MarketCompass.Patches
{
[HarmonyPatch(typeof(UIManager))]
public static class UIManagerPatch
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
public static void Start_Postfix(UIManager __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
CompassHUD component = ((Component)__instance).gameObject.GetComponent<CompassHUD>();
if ((Object)(object)component == (Object)null)
{
((Component)__instance).gameObject.AddComponent<CompassHUD>();
}
else if (!((Behaviour)component).enabled)
{
((Behaviour)component).enabled = true;
}
}
}
}
}
namespace MarketCompass.Network
{
public static class CompassNetworkManager
{
public const string MSG_REQ_NAME = "MarketCompass_ReqName";
public const string MSG_RES_NAME = "MarketCompass_ResName";
private static FieldInfo _clientIdNicknamesField;
private static readonly Dictionary<ulong, string> _playerNameCache = new Dictionary<ulong, string>();
private static readonly Dictionary<ulong, float> _lastRequestTime = new Dictionary<ulong, float>();
private const float REQUEST_COOLDOWN = 2f;
private static bool _isInitialized = false;
public static void Initialize()
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
if (!_isInitialized && !((Object)(object)NetworkManager.Singleton == (Object)null))
{
CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
if (customMessagingManager != null)
{
_clientIdNicknamesField = AccessTools.Field(typeof(GameManager), "clientIdNicknames");
customMessagingManager.RegisterNamedMessageHandler("MarketCompass_ReqName", new HandleNamedMessageDelegate(OnReceiveNameRequest));
customMessagingManager.RegisterNamedMessageHandler("MarketCompass_ResName", new HandleNamedMessageDelegate(OnReceiveNameResponse));
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnected;
_isInitialized = true;
}
}
}
public static void Shutdown()
{
if (!_isInitialized)
{
return;
}
if ((Object)(object)NetworkManager.Singleton != (Object)null)
{
if (NetworkManager.Singleton.CustomMessagingManager != null)
{
NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("MarketCompass_ReqName");
NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("MarketCompass_ResName");
}
NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientDisconnected;
}
_playerNameCache.Clear();
_lastRequestTime.Clear();
_isInitialized = false;
}
private static void OnClientDisconnected(ulong clientId)
{
if (_playerNameCache.ContainsKey(clientId))
{
_playerNameCache.Remove(clientId);
}
if (_lastRequestTime.ContainsKey(clientId))
{
_lastRequestTime.Remove(clientId);
}
}
public static string GetPlayerName(ulong clientId)
{
if (_playerNameCache.TryGetValue(clientId, out var value))
{
return value;
}
string text = null;
if ((Object)(object)GameManager.Instance != (Object)null && _clientIdNicknamesField != null)
{
try
{
if (_clientIdNicknamesField.GetValue(GameManager.Instance) is Dictionary<ulong, string> dictionary && dictionary.TryGetValue(clientId, out var value2) && !string.IsNullOrEmpty(value2))
{
text = value2;
}
}
catch
{
}
}
if (string.IsNullOrEmpty(text) && !_playerNameCache.ContainsKey(clientId) && (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
{
RequestNameFromServer(clientId);
}
if (!string.IsNullOrEmpty(text))
{
_playerNameCache[clientId] = text;
return text;
}
return LocalizationManager.Instance.GetLocalizedText("compass.player_default", clientId);
}
private static void RequestNameFromServer(ulong targetClientId)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsClient || (_lastRequestTime.TryGetValue(targetClientId, out var value) && Time.time - value < 2f))
{
return;
}
_lastRequestTime[targetClientId] = Time.time;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref targetClientId, default(ForPrimitives));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("MarketCompass_ReqName", 0uL, val, (NetworkDelivery)3);
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
private static void OnReceiveNameRequest(ulong senderId, FastBufferReader reader)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkManager.Singleton.IsServer)
{
return;
}
ulong key = default(ulong);
((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
string text = null;
if ((Object)(object)GameManager.Instance != (Object)null && _clientIdNicknamesField != null && _clientIdNicknamesField.GetValue(GameManager.Instance) is Dictionary<ulong, string> dictionary && dictionary.TryGetValue(key, out var value))
{
text = value;
}
if (string.IsNullOrEmpty(text))
{
return;
}
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref key, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("MarketCompass_ResName", senderId, val, (NetworkDelivery)3);
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
private static void OnReceiveNameResponse(ulong senderId, FastBufferReader reader)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
ulong key = default(ulong);
((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
string value = default(string);
((FastBufferReader)(ref reader)).ReadValueSafe(ref value, false);
if (!string.IsNullOrEmpty(value))
{
_playerNameCache[key] = value;
}
}
}
}
namespace MarketCompass.Localization
{
public static class LocalizationHelper
{
public static Dictionary<string, string> GetDefaultTranslations(string language)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
switch (language)
{
case "zh":
dictionary.Add("plugin.initializing", "开始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初始化成功!");
dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
dictionary.Add("compass.N", "北");
dictionary.Add("compass.NE", "东北");
dictionary.Add("compass.E", "东");
dictionary.Add("compass.SE", "东南");
dictionary.Add("compass.S", "南");
dictionary.Add("compass.SW", "西南");
dictionary.Add("compass.W", "西");
dictionary.Add("compass.NW", "西北");
dictionary.Add("compass.player_default", "玩家 {0}");
dictionary.Add("config.show_npcs_desc", "是否显示普通NPC");
dictionary.Add("config.show_fest_npcs_desc", "是否显示节日NPC");
dictionary.Add("config.npc_name_distance_desc", "显示NPC名字的距离(米)");
dictionary.Add("config.show_players_desc", "是否显示玩家");
dictionary.Add("config.player_name_distance_desc", "显示玩家名字的距离(米,-1为无限)");
dictionary.Add("config.enable_external_access_desc", "是否显示其他模组通过 API 添加的标记");
break;
case "zh-Hant":
dictionary.Add("plugin.initializing", "開始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初始化成功!");
dictionary.Add("plugin.patches_skipped", "補丁已應用,跳過...");
dictionary.Add("compass.N", "北");
dictionary.Add("compass.NE", "東北");
dictionary.Add("compass.E", "東");
dictionary.Add("compass.SE", "東南");
dictionary.Add("compass.S", "南");
dictionary.Add("compass.SW", "西南");
dictionary.Add("compass.W", "西");
dictionary.Add("compass.NW", "西北");
dictionary.Add("compass.player_default", "玩家 {0}");
dictionary.Add("config.show_npcs_desc", "是否顯示普通NPC");
dictionary.Add("config.show_fest_npcs_desc", "是否顯示節日NPC");
dictionary.Add("config.npc_name_distance_desc", "顯示NPC名字的距離(米)");
dictionary.Add("config.show_players_desc", "是否顯示玩家");
dictionary.Add("config.player_name_distance_desc", "顯示玩家名字的距離(米,-1為無限)");
dictionary.Add("config.enable_external_access_desc", "是否顯示其他模組透過 API 新增的標記");
break;
case "en":
dictionary.Add("plugin.initializing", "is initializing...");
dictionary.Add("plugin.author_prefix", "Author: ");
dictionary.Add("plugin.initialized", "initialized successfully!");
dictionary.Add("plugin.patches_skipped", "Patches already applied, skipping...");
dictionary.Add("compass.N", "N");
dictionary.Add("compass.NE", "NE");
dictionary.Add("compass.E", "E");
dictionary.Add("compass.SE", "SE");
dictionary.Add("compass.S", "S");
dictionary.Add("compass.SW", "SW");
dictionary.Add("compass.W", "W");
dictionary.Add("compass.NW", "NW");
dictionary.Add("compass.player_default", "Player {0}");
dictionary.Add("config.show_npcs_desc", "Whether to show regular NPCs");
dictionary.Add("config.show_fest_npcs_desc", "Whether to show festival NPCs");
dictionary.Add("config.npc_name_distance_desc", "Distance to show NPC names (meters)");
dictionary.Add("config.show_players_desc", "Whether to show players");
dictionary.Add("config.player_name_distance_desc", "Distance to show player names (meters, -1 for infinite)");
dictionary.Add("config.enable_external_access_desc", "Whether to show markers added by other mods via API");
break;
case "ja":
dictionary.Add("plugin.initializing", "初期化中...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初期化に成功しました!");
dictionary.Add("plugin.patches_skipped", "パッチは既に適用されています。スキップします...");
dictionary.Add("compass.N", "北");
dictionary.Add("compass.NE", "北東");
dictionary.Add("compass.E", "東");
dictionary.Add("compass.SE", "南東");
dictionary.Add("compass.S", "南");
dictionary.Add("compass.SW", "南西");
dictionary.Add("compass.W", "西");
dictionary.Add("compass.NW", "北西");
dictionary.Add("compass.player_default", "プレイヤー {0}");
dictionary.Add("config.show_npcs_desc", "通常のNPCを表示するかどうか");
dictionary.Add("config.show_fest_npcs_desc", "祭りのNPCを表示するかどうか");
dictionary.Add("config.npc_name_distance_desc", "NPC名を表示する距離(メートル)");
dictionary.Add("config.show_players_desc", "プレイヤーを表示するかどうか");
dictionary.Add("config.player_name_distance_desc", "プレイヤー名を表示する距離(メートル、-1は無限)");
dictionary.Add("config.enable_external_access_desc", "外部MODがAPI経由でマーカーを追加することを許可するかどうか");
break;
}
return dictionary;
}
}
public class LocalizationManager
{
private static LocalizationManager _instance;
private readonly Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();
private string _currentLocale = "zh";
public static readonly string[] SupportedLanguages = new string[12]
{
"zh", "zh-Hant", "en", "fr", "de", "ja", "ko", "pt", "ru", "es",
"tr", "uk"
};
public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager());
private LocalizationManager()
{
Initialize();
}
public void Initialize()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)LocalizationSettings.SelectedLocale != (Object)null)
{
LocaleIdentifier identifier = LocalizationSettings.SelectedLocale.Identifier;
_currentLocale = ((LocaleIdentifier)(ref identifier)).Code;
}
string[] supportedLanguages = SupportedLanguages;
foreach (string text in supportedLanguages)
{
Dictionary<string, string> defaultTranslations = LocalizationHelper.GetDefaultTranslations(text);
if (defaultTranslations != null && defaultTranslations.Count > 0)
{
_localizations[text] = defaultTranslations;
}
}
LocalizationSettings.SelectedLocaleChanged += OnGameLanguageChanged;
}
private void OnGameLanguageChanged(Locale locale)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)locale != (Object)null)
{
LocaleIdentifier identifier = locale.Identifier;
string code = ((LocaleIdentifier)(ref identifier)).Code;
if (_localizations.ContainsKey(code))
{
_currentLocale = code;
}
else
{
_currentLocale = "en";
}
}
}
public string GetLocalizedText(string key, params object[] args)
{
if (string.IsNullOrEmpty(_currentLocale) || !_localizations.ContainsKey(_currentLocale))
{
_currentLocale = "en";
}
if (_localizations.ContainsKey(_currentLocale) && _localizations[_currentLocale].TryGetValue(key, out var value))
{
if (args.Length == 0)
{
return value;
}
return string.Format(value, args);
}
if (_currentLocale != "en" && _localizations.ContainsKey("en") && _localizations["en"].TryGetValue(key, out var value2))
{
if (args.Length == 0)
{
return value2;
}
return string.Format(value2, args);
}
if (_localizations.ContainsKey("zh") && _localizations["zh"].TryGetValue(key, out var value3))
{
if (args.Length == 0)
{
return value3;
}
return string.Format(value3, args);
}
return key;
}
}
}
namespace MarketCompass.Configuration
{
public static class ConfigManager
{
public static ConfigEntry<bool> ShowNPCs { get; private set; }
public static ConfigEntry<bool> ShowFestivalNPCs { get; private set; }
public static ConfigEntry<float> NPCNameDistance { get; private set; }
public static ConfigEntry<bool> ShowPlayers { get; private set; }
public static ConfigEntry<float> PlayerNameDistance { get; private set; }
public static ConfigEntry<bool> EnableExternalAccess { get; private set; }
public static void Initialize(ConfigFile config)
{
ShowNPCs = config.Bind<bool>("NPC", "ShowNPCs", true, LocalizationManager.Instance.GetLocalizedText("config.show_npcs_desc"));
ShowFestivalNPCs = config.Bind<bool>("NPC", "ShowFestivalNPCs", true, LocalizationManager.Instance.GetLocalizedText("config.show_fest_npcs_desc"));
NPCNameDistance = config.Bind<float>("NPC", "NPCNameDistance", 20f, LocalizationManager.Instance.GetLocalizedText("config.npc_name_distance_desc"));
ShowPlayers = config.Bind<bool>("Player", "ShowPlayers", true, LocalizationManager.Instance.GetLocalizedText("config.show_players_desc"));
PlayerNameDistance = config.Bind<float>("Player", "PlayerNameDistance", -1f, LocalizationManager.Instance.GetLocalizedText("config.player_name_distance_desc"));
EnableExternalAccess = config.Bind<bool>("API", "EnableExternalAccess", true, LocalizationManager.Instance.GetLocalizedText("config.enable_external_access_desc"));
}
}
}
namespace MarketCompass.Api
{
public static class ExternalMarkerAPI
{
public struct ExternalMarker
{
public string Source;
public string Id;
public Vector3 Position;
public string Name;
}
private struct MarkerState
{
public Vector3 Position;
public string Name;
}
private static readonly Dictionary<string, Dictionary<string, MarkerState>> _markersBySource = new Dictionary<string, Dictionary<string, MarkerState>>();
private static ExternalMarker[] _cachedMarkers = Array.Empty<ExternalMarker>();
private static bool _isDirty = true;
public static void SetMarkers(string source, string[] ids, Vector3[] positions, string[] names)
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
if (!ConfigManager.EnableExternalAccess.Value || string.IsNullOrEmpty(source))
{
return;
}
if (!_markersBySource.TryGetValue(source, out var value))
{
value = new Dictionary<string, MarkerState>();
_markersBySource[source] = value;
}
else
{
value.Clear();
}
if (ids == null || positions == null)
{
_isDirty = true;
return;
}
int num = Math.Min(ids.Length, positions.Length);
for (int i = 0; i < num; i++)
{
string text = ids[i];
if (!string.IsNullOrEmpty(text))
{
value[text] = new MarkerState
{
Position = positions[i],
Name = ((names != null && i < names.Length) ? names[i] : null)
};
}
}
_isDirty = true;
}
public static void AddMarker(string source, string id, Vector3 position, string name)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
if (ConfigManager.EnableExternalAccess.Value && !string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(id))
{
if (!_markersBySource.TryGetValue(source, out var value))
{
value = new Dictionary<string, MarkerState>();
_markersBySource[source] = value;
}
value[id] = new MarkerState
{
Position = position,
Name = name
};
_isDirty = true;
}
}
public static void RemoveMarker(string source, string id)
{
if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(id) && _markersBySource.TryGetValue(source, out var value) && value.Remove(id))
{
_isDirty = true;
}
}
public static void ClearMarkers(string source)
{
if (!string.IsNullOrEmpty(source) && _markersBySource.Remove(source))
{
_isDirty = true;
}
}
public static ExternalMarker[] GetAllMarkers()
{
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
if (!_isDirty)
{
return _cachedMarkers;
}
int num = 0;
foreach (KeyValuePair<string, Dictionary<string, MarkerState>> item in _markersBySource)
{
num += item.Value.Count;
}
if (num == 0)
{
_cachedMarkers = Array.Empty<ExternalMarker>();
_isDirty = false;
return _cachedMarkers;
}
ExternalMarker[] array = new ExternalMarker[num];
int num2 = 0;
foreach (KeyValuePair<string, Dictionary<string, MarkerState>> item2 in _markersBySource)
{
foreach (KeyValuePair<string, MarkerState> item3 in item2.Value)
{
array[num2++] = new ExternalMarker
{
Source = item2.Key,
Id = item3.Key,
Position = item3.Value.Position,
Name = item3.Value.Name
};
}
}
_cachedMarkers = array;
_isDirty = false;
return _cachedMarkers;
}
}
}