using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RichDiscordPresence")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RichDiscordPresence")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1c31fc1f-1533-4b90-8a55-feeabea1cf7a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public class DiscordRpc
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ReadyCallback();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DisconnectedCallback(int errorCode, string message);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ErrorCallback(int errorCode, string message);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void JoinCallback(string secret);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SpectateCallback(string secret);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void RequestCallback(ref JoinRequest request);
public struct EventHandlers
{
public ReadyCallback readyCallback;
public DisconnectedCallback disconnectedCallback;
public ErrorCallback errorCallback;
public JoinCallback joinCallback;
public SpectateCallback spectateCallback;
public RequestCallback requestCallback;
}
[Serializable]
public struct RichPresenceStruct
{
public IntPtr state;
public IntPtr details;
public long startTimestamp;
public long endTimestamp;
public IntPtr largeImageKey;
public IntPtr largeImageText;
public IntPtr smallImageKey;
public IntPtr smallImageText;
public IntPtr partyId;
public int partySize;
public int partyMax;
public IntPtr matchSecret;
public IntPtr joinSecret;
public IntPtr spectateSecret;
public bool instance;
}
[Serializable]
public struct JoinRequest
{
public string userId;
public string username;
public string discriminator;
public string avatar;
}
public enum Reply
{
No,
Yes,
Ignore
}
public class RichPresence
{
private RichPresenceStruct _presence;
private readonly List<IntPtr> _buffers = new List<IntPtr>(10);
public string state;
public string details;
public long startTimestamp;
public long endTimestamp;
public string largeImageKey;
public string largeImageText;
public string smallImageKey;
public string smallImageText;
public string partyId;
public int partySize;
public int partyMax;
public string matchSecret;
public string joinSecret;
public string spectateSecret;
public bool instance;
internal RichPresenceStruct GetStruct()
{
if (_buffers.Count > 0)
{
FreeMem();
}
_presence.state = StrToPtr(state, 128);
_presence.details = StrToPtr(details, 128);
_presence.startTimestamp = startTimestamp;
_presence.endTimestamp = endTimestamp;
_presence.largeImageKey = StrToPtr(largeImageKey, 32);
_presence.largeImageText = StrToPtr(largeImageText, 128);
_presence.smallImageKey = StrToPtr(smallImageKey, 32);
_presence.smallImageText = StrToPtr(smallImageText, 128);
_presence.partyId = StrToPtr(partyId, 128);
_presence.partySize = partySize;
_presence.partyMax = partyMax;
_presence.matchSecret = StrToPtr(matchSecret, 128);
_presence.joinSecret = StrToPtr(joinSecret, 128);
_presence.spectateSecret = StrToPtr(spectateSecret, 128);
_presence.instance = instance;
return _presence;
}
private IntPtr StrToPtr(string input, int maxbytes)
{
if (string.IsNullOrEmpty(input))
{
return IntPtr.Zero;
}
string s = StrClampBytes(input, maxbytes);
int byteCount = Encoding.UTF8.GetByteCount(s);
IntPtr intPtr = Marshal.AllocHGlobal(byteCount);
_buffers.Add(intPtr);
Marshal.Copy(Encoding.UTF8.GetBytes(s), 0, intPtr, byteCount);
return intPtr;
}
private static string StrToUtf8NullTerm(string toconv)
{
string text = toconv.Trim();
byte[] bytes = Encoding.Default.GetBytes(text);
if (bytes.Length != 0 && bytes[^1] != 0)
{
text += "\0\0";
}
return Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(text));
}
private static string StrClampBytes(string toclamp, int maxbytes)
{
string text = StrToUtf8NullTerm(toclamp);
byte[] bytes = Encoding.UTF8.GetBytes(text);
if (bytes.Length <= maxbytes)
{
return text;
}
byte[] array = new byte[0];
Array.Copy(bytes, 0, array, 0, maxbytes - 1);
array[^1] = 0;
array[^2] = 0;
return Encoding.UTF8.GetString(array);
}
internal void FreeMem()
{
for (int num = _buffers.Count - 1; num >= 0; num--)
{
Marshal.FreeHGlobal(_buffers[num]);
_buffers.RemoveAt(num);
}
}
}
[DllImport("discord-rpc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Discord_Initialize")]
public static extern void Initialize(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId);
[DllImport("discord-rpc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Discord_Shutdown")]
public static extern void Shutdown();
[DllImport("discord-rpc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Discord_RunCallbacks")]
public static extern void RunCallbacks();
[DllImport("discord-rpc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Discord_UpdatePresence")]
private static extern void UpdatePresenceNative(ref RichPresenceStruct presence);
[DllImport("discord-rpc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Discord_ClearPresence")]
public static extern void ClearPresence();
[DllImport("discord-rpc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Discord_Respond")]
public static extern void Respond(string userId, Reply reply);
public static void UpdatePresence(RichPresence presence)
{
RichPresenceStruct presence2 = presence.GetStruct();
UpdatePresenceNative(ref presence2);
presence.FreeMem();
}
}
namespace RichDiscordPresence;
[BepInPlugin("shudnal.RichDiscordPresence", "Rich Discord Presence", "1.0.5")]
[BepInProcess("valheim.exe")]
public class RichDiscordPresence : BaseUnityPlugin
{
[HarmonyPatch(typeof(FejdStartup), "Awake")]
private class FejdStartup_Awake_MainMenu
{
private static void Postfix()
{
if (modEnabled.Value)
{
LogInfo("FejdStartup.Awake");
SetPresence(updateState: true);
}
}
}
[HarmonyPatch(typeof(FejdStartup), "OnDestroy")]
private class FejdStartup_OnDestroy_MainMenu
{
private static void Postfix()
{
if (modEnabled.Value)
{
LogInfo("FejdStartup.OnDestroy");
SetPresence(updateState: true);
}
}
}
[HarmonyPatch(typeof(ZNet), "Awake")]
private class ZNet_Awake_PlayersCount
{
private static void Postfix()
{
if (modEnabled.Value)
{
playerCount = ZNet.instance.GetNrOfPlayers();
LogInfo("ZNet.Awake");
SetPresence();
}
}
}
[HarmonyPatch(typeof(ZNet), "UpdatePlayerList")]
private class ZNet_UpdatePlayerList_PlayersCount
{
private static void Postfix()
{
if (modEnabled.Value && showServerSize.Value && ZNet.instance.GetNrOfPlayers() != playerCount)
{
playerCount = ZNet.instance.GetNrOfPlayers();
LogInfo("ZNet.UpdatePlayerList");
SetPresence();
}
}
}
[HarmonyPatch(typeof(ZNet), "RPC_PlayerList")]
private class ZNet_RPC_PlayerList_PlayersCount
{
private static void Postfix()
{
if (modEnabled.Value && showServerSize.Value && ZNet.instance.GetNrOfPlayers() != playerCount)
{
playerCount = ZNet.instance.GetNrOfPlayers();
LogInfo("ZNet.RPC_PlayerList");
SetPresence();
}
}
}
[HarmonyPatch(typeof(Player), "UpdateBiome")]
private class Player_UpdateBiome_Roaming
{
private static void Postfix(Player __instance)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
if (modEnabled.Value && !((Object)(object)Player.m_localPlayer != (Object)(object)__instance) && currentBiome != __instance.GetCurrentBiome())
{
currentBiome = __instance.GetCurrentBiome();
LogInfo("Player.UpdateBiome");
SetPresence(updateState: true);
}
}
}
[HarmonyPatch(typeof(Ship), "OnTriggerEnter")]
private class Ship_OnTriggerEnter_Sailing
{
private static void Postfix(Collider collider)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if (modEnabled.Value && !((Object)(object)((Component)collider).GetComponent<Player>() != (Object)(object)Player.m_localPlayer) && onShip != ((Object)(object)Ship.GetLocalShip() != (Object)null))
{
onShip = (Object)(object)Ship.GetLocalShip() != (Object)null;
LogInfo("Ship.OnTriggerEnter");
SetPresence(updateState: true);
}
}
}
[HarmonyPatch(typeof(Ship), "OnTriggerExit")]
private class Ship_OnTriggerExit_Sailing
{
private static void Postfix(Collider collider)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if (modEnabled.Value && !((Object)(object)((Component)collider).GetComponent<Player>() != (Object)(object)Player.m_localPlayer) && onShip != ((Object)(object)Ship.GetLocalShip() != (Object)null))
{
onShip = (Object)(object)Ship.GetLocalShip() != (Object)null;
LogInfo("Ship.OnTriggerExit");
SetPresence(updateState: true);
}
}
}
[HarmonyPatch(typeof(EnvMan), "SetForceEnvironment")]
private class EnvMan_SetForceEnvironment_SpecialEnv
{
private static void Postfix(string ___m_forceEnv)
{
if (modEnabled.Value && !(forceEnv == ___m_forceEnv))
{
forceEnv = ___m_forceEnv;
LogInfo("EnvMan.SetForceEnvironment");
SetPresence(updateState: true);
}
}
}
[HarmonyPatch(typeof(Player), "UpdateEnvStatusEffects")]
private class Player_UpdateEnvStatusEffects_Roaming
{
private static void Postfix(Player __instance)
{
if (modEnabled.Value && !((Object)(object)Player.m_localPlayer != (Object)(object)__instance))
{
bool flag = __instance.IsSafeInHome() && __instance.GetBaseValue() >= safeInHomeBaseValue.Value;
if (safeInHome != flag)
{
safeInHome = flag;
LogInfo("Player.UpdateEnvStatusEffects");
SetPresence(updateState: true);
}
}
}
}
[HarmonyPatch(typeof(Trader), "Update")]
private class Trader_Update_Trader
{
private static void Postfix(Trader __instance, float ___m_byeRange)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
if (modEnabled.Value && showTrader.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
{
float num = Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, ((Component)__instance).transform.position);
if (num > ___m_byeRange && (Object)(object)activeTrader != (Object)null)
{
activeTrader = null;
LogInfo("Trader.Update");
SetPresence(updateState: true);
}
else if (num <= ___m_byeRange && (Object)(object)activeTrader == (Object)null)
{
activeTrader = __instance;
LogInfo("Trader.Update");
SetPresence(updateState: true);
}
}
}
}
[HarmonyPatch(typeof(EnemyHud), "UpdateHuds")]
private class EnemyHud_UpdateHuds_Boss
{
private static void Postfix(EnemyHud __instance, Player player)
{
if (modEnabled.Value && !((Object)(object)Player.m_localPlayer != (Object)(object)player) && showingBossHud != __instance.ShowingBossHud())
{
showingBossHud = __instance.ShowingBossHud();
LogInfo("EnemyHud.UpdateHuds");
SetPresence(updateState: true);
}
}
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static EventHandler <>9__59_0;
public static EventHandler <>9__59_1;
public static ConsoleEvent <>9__59_2;
public static Func<Teleport, bool> <>9__75_0;
internal void <ConfigInit>b__59_0(object sender, EventArgs args)
{
UpdateImageDescription();
}
internal void <ConfigInit>b__59_1(object sender, EventArgs args)
{
UpdateImageDescription();
}
internal void <ConfigInit>b__59_2(ConsoleEventArgs args)
{
if (!modEnabled.Value)
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)"Mod disabled");
}
else
{
SetPresence(updateState: true);
}
}
internal bool <SetPresence>b__75_0(Teleport tp)
{
return !Utility.IsNullOrWhiteSpace(tp.m_enterText);
}
}
private const string pluginID = "shudnal.RichDiscordPresence";
private const string pluginName = "Rich Discord Presence";
private const string pluginVersion = "1.0.5";
private Harmony _harmony;
private static ConfigEntry<bool> modEnabled;
private static ConfigEntry<bool> loggingEnabled;
private static ConfigEntry<string> ApplicationID;
private static ConfigEntry<string> localizationLanguage;
private static ConfigEntry<string> msgMainMenu;
private static ConfigEntry<string> msgSingleplayer;
private static ConfigEntry<string> msgMultiplayer;
private static ConfigEntry<string> msgMultiplayerAlone;
private static ConfigEntry<string> msgRoaming;
private static ConfigEntry<string> msgBoss;
private static ConfigEntry<string> msgAtHome;
private static ConfigEntry<string> msgSailing;
private static ConfigEntry<string> msgInDungeon;
private static ConfigEntry<string> msgTrader;
private static ConfigEntry<string> msgBiomeMeadows;
private static ConfigEntry<string> msgBiomeSwamp;
private static ConfigEntry<string> msgBiomeMountain;
private static ConfigEntry<string> msgBiomeBlackForest;
private static ConfigEntry<string> msgBiomePlains;
private static ConfigEntry<string> msgBiomeAshLands;
private static ConfigEntry<string> msgBiomeDeepNorth;
private static ConfigEntry<string> msgBiomeOcean;
private static ConfigEntry<string> msgBiomeMistlands;
private static ConfigEntry<bool> showIngameTime;
private static ConfigEntry<bool> showServerSize;
private static ConfigEntry<bool> showServerName;
private static ConfigEntry<bool> showGameState;
private static ConfigEntry<int> serverMaxCapacity;
private static ConfigEntry<string> serverName;
private static ConfigEntry<bool> showTrader;
private static ConfigEntry<int> safeInHomeBaseValue;
private static ConfigEntry<string> liKeyDefault;
private static ConfigEntry<string> liTextDefault;
private static ConfigEntry<string> siKeyDefault;
private static ConfigEntry<string> siTextDefault;
private static ConfigEntry<string> liDescriptions;
private static ConfigEntry<string> siDescriptions;
private static readonly long started = (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
private static readonly Random random = new Random();
private static RichDiscordPresence instance;
private static DiscordRpc.EventHandlers handlers;
private static Biome currentBiome = (Biome)0;
private static string forceEnv = "";
private static bool safeInHome;
private static int playerCount = 0;
private static Trader activeTrader;
private static bool showingBossHud;
private static bool onShip;
private static readonly Dictionary<string, string> imageDescription = new Dictionary<string, string>();
private static string details = "";
private static string state = "";
private void Awake()
{
_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "shudnal.RichDiscordPresence");
instance = this;
ConfigInit();
if (Utility.IsNullOrWhiteSpace(ApplicationID.Value))
{
((BaseUnityPlugin)instance).Logger.LogWarning((object)"Application ID is not set. Set and relaunch the game to load discord.");
return;
}
DiscordRpc.Initialize(ApplicationID.Value, ref handlers, autoRegister: true, "");
Game.isModded = true;
UpdateImageDescription();
}
private void OnDestroy()
{
((BaseUnityPlugin)this).Config.Save();
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void OnDisable()
{
if (modEnabled.Value)
{
LogInfo("Shutdown");
DiscordRpc.Shutdown();
}
}
public static void LogInfo(object data)
{
if (loggingEnabled.Value)
{
((BaseUnityPlugin)instance).Logger.LogInfo(data);
}
}
private void ConfigInit()
{
//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
//IL_05ae: Expected O, but got Unknown
((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 2555, "Nexus mod ID for updates");
modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the mod.");
loggingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Logging enabled", false, "Enable logging.");
ApplicationID = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Application ID", "", "The APPLICATION ID you get from discord developer portal -> Applications -> Your app -> General Information");
localizationLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Loсalization language", "", "Specify language to make bosses, locations and biomes localized to it. If empty - current game language is used");
msgMainMenu = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "State - Main menu", "Main Menu", "Message while in menu");
msgSingleplayer = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "State - Singleplayer", "On their own", "Semicolon separated in singleplayer messages");
msgMultiplayer = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "State - Multiplayer", "In a Group", "Semicolon separated in multiplayer messages");
msgMultiplayerAlone = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "State - Alone in multiplayer", "Feeling lonely", "Semicolon separated in multiplayer but alone messages");
msgRoaming = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "Details - Roaming", "Roaming around;Taking a stroll;Moving around;Wandering around;Prowling around;Walking around;Sauntering;", "Semicolon separated Biome: messages");
msgBoss = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "Details - Fighting boss", "Fighting;Brawling;In combat;Is being fought;In a fight;Struggling against;Battling;In a battle;Hell of a fight", "Semicolon separated Boss: messages");
msgAtHome = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "Details - Safe at home", "Hanging out at home;Keeping warm safely;Working at base;Chilling at home;Warm and safe;Safe at home;Warm and cozy", "Semicolon separated while safe at home messages");
msgSailing = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "Details - Sailing", "Sailing;Seafaring;Boating;Yachting;Boat trip", "Semicolon separated sailing messages");
msgInDungeon = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "Details - Dungeon", "Conquering;Killing things;Wiping out;Tomb Raiding;Grave-robbing;Plundering;Looting;Pillaging", "Semicolon separated in dungeon messages");
msgTrader = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "Details - Trader", "Trading;Making a deal;Exchanging;Doing business;Negotiating;Bargaining;Haggling", "Semicolon separated when Trader nearby messages");
msgBiomeMeadows = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "Meadows", "", "Semicolon separated Biome: messages");
msgBiomeSwamp = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "Swamp", "", "Semicolon separated Biome: messages");
msgBiomeMountain = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "Mountain", "", "Semicolon separated Biome: messages");
msgBiomeBlackForest = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "BlackForest", "", "Semicolon separated Biome: messages");
msgBiomePlains = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "Plains", "", "Semicolon separated Biome: messages");
msgBiomeAshLands = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "AshLands", "", "Semicolon separated Biome: messages");
msgBiomeDeepNorth = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "DeepNorth", "", "Semicolon separated Biome: messages");
msgBiomeOcean = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "Ocean", "", "Semicolon separated Biome: messages");
msgBiomeMistlands = ((BaseUnityPlugin)this).Config.Bind<string>("Messages - Roaming Biome Specific", "Mistlands", "", "Semicolon separated Biome: messages");
safeInHomeBaseValue = ((BaseUnityPlugin)this).Config.Bind<int>("Misc", "Base value limit to be safe at home", 3, "How much PlayerBase objects should be near to consider player be safe at home");
showIngameTime = ((BaseUnityPlugin)this).Config.Bind<bool>("State", "Show ingame time", true, "Show time since game start");
showServerSize = ((BaseUnityPlugin)this).Config.Bind<bool>("State", "Show server size", true, "Show server size");
showServerName = ((BaseUnityPlugin)this).Config.Bind<bool>("State", "Show server name", true, "Show server name");
showGameState = ((BaseUnityPlugin)this).Config.Bind<bool>("State", "Show game state", true, "Show game state (singleplayer, multiplayer, multiplayer alone)");
serverName = ((BaseUnityPlugin)this).Config.Bind<string>("State", "Server name", "", "If left emtpy the ingame server name will be used");
serverMaxCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("State", "Server max capacity", 0, "If left empty default Valheim capacity will be used");
showTrader = ((BaseUnityPlugin)this).Config.Bind<bool>("State", "Show active Trader", true, "Show Trader name and trader message if any Trader is nearby");
liKeyDefault = ((BaseUnityPlugin)this).Config.Bind<string>("Images - Default", "Large image key", "logo", "Default Large image key");
liTextDefault = ((BaseUnityPlugin)this).Config.Bind<string>("Images - Default", "Large image text", "Valheim", "Default Large image text");
siKeyDefault = ((BaseUnityPlugin)this).Config.Bind<string>("Images - Default", "Small image key", "", "Default Small image key");
siTextDefault = ((BaseUnityPlugin)this).Config.Bind<string>("Images - Default", "Small image text", "", "Default Small image text");
liDescriptions = ((BaseUnityPlugin)this).Config.Bind<string>("Images - Descriptions", "Large images descriptions", "", "Semicolon separated list of key-text Large Image descriptions where key is what's before : in details string. More at mod's page.");
liDescriptions.SettingChanged += delegate
{
UpdateImageDescription();
};
siDescriptions = ((BaseUnityPlugin)this).Config.Bind<string>("Images - Descriptions", "Small images descriptions", "", "Semicolon separated list of key-text Small Image descriptions where key is what's after : in details string. More at mod's page.");
siDescriptions.SettingChanged += delegate
{
UpdateImageDescription();
};
object obj = <>c.<>9__59_2;
if (obj == null)
{
ConsoleEvent val = delegate
{
if (!modEnabled.Value)
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)"Mod disabled");
}
else
{
SetPresence(updateState: true);
}
};
<>c.<>9__59_2 = val;
obj = (object)val;
}
new ConsoleCommand("richdiscordpresence", "Force Rich Presence update", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
}
private static void UpdateImageDescription()
{
imageDescription.Clear();
string[] array = liDescriptions.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string text in array)
{
int num = text.IndexOf("-");
if (num != -1 && num != text.Length)
{
LogInfo("Loaded image description: " + text.Substring(0, num).Trim() + ", " + text.Substring(num + 1).Trim());
imageDescription.Add(text.Substring(0, num).Trim(), text.Substring(num + 1).Trim());
}
}
string[] array2 = siDescriptions.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string text2 in array2)
{
int num2 = text2.IndexOf("-");
if (num2 != -1 && num2 != text2.Length)
{
LogInfo("Loaded image description: " + text2.Substring(0, num2).Trim() + ", " + text2.Substring(num2 + 1).Trim());
imageDescription.Add(text2.Substring(0, num2).Trim(), text2.Substring(num2 + 1).Trim());
}
}
}
private static string GetRandomState(string state)
{
string[] array = state.Split(new char[1] { ';' }, StringSplitOptions.None);
return array[random.Next(array.Length)];
}
private static string BiomeSpecific(Biome biome)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Invalid comparison between Unknown and I4
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
//IL_000a: 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)
//IL_0022: Expected I4, but got Unknown
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Invalid comparison between Unknown and I4
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Invalid comparison between Unknown and I4
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Invalid comparison between Unknown and I4
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Invalid comparison between Unknown and I4
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Invalid comparison between Unknown and I4
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Invalid comparison between Unknown and I4
if ((int)biome <= 16)
{
switch (biome - 1)
{
default:
if ((int)biome != 8)
{
if ((int)biome != 16)
{
break;
}
return GetRandomState(msgBiomePlains.Value);
}
return GetRandomState(msgBiomeBlackForest.Value);
case 0:
return GetRandomState(msgBiomeMeadows.Value);
case 1:
return GetRandomState(msgBiomeSwamp.Value);
case 3:
return GetRandomState(msgBiomeMountain.Value);
case 2:
break;
}
}
else if ((int)biome <= 64)
{
if ((int)biome == 32)
{
return GetRandomState(msgBiomeAshLands.Value);
}
if ((int)biome == 64)
{
return GetRandomState(msgBiomeDeepNorth.Value);
}
}
else
{
if ((int)biome == 256)
{
return GetRandomState(msgBiomeOcean.Value);
}
if ((int)biome == 512)
{
return GetRandomState(msgBiomeMistlands.Value);
}
}
return "";
}
public static void SetPresence(bool updateState = false)
{
//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Invalid comparison between Unknown and I4
//IL_0233: Unknown result type (might be due to invalid IL or missing references)
//IL_0307: Unknown result type (might be due to invalid IL or missing references)
if (!modEnabled.Value)
{
return;
}
string text = "";
string text2 = "";
string text3 = "";
string text4 = "";
if (updateState)
{
if ((Object)(object)FejdStartup.instance != (Object)null)
{
details = msgMainMenu.Value;
state = "";
}
else if ((Object)(object)Player.m_localPlayer == (Object)null)
{
details = "";
state = "";
}
else
{
StringBuilder stringBuilder = new StringBuilder(256);
string text5 = GetRandomState(msgRoaming.Value);
if (showingBossHud)
{
string name = EnemyHud.instance.GetActiveBoss().m_name;
text5 = GetRandomState(msgBoss.Value);
stringBuilder.Append(Utility.IsNullOrWhiteSpace(localizationLanguage.Value) ? name : Localization.instance.TranslateSingleId(name, localizationLanguage.Value));
stringBuilder.Append(": ");
stringBuilder.Append(Utility.IsNullOrWhiteSpace(text5) ? "$menu_combat" : text5);
}
else if (showTrader.Value && (Object)(object)activeTrader != (Object)null)
{
text5 = GetRandomState(msgTrader.Value);
stringBuilder.Append(Utility.IsNullOrWhiteSpace(localizationLanguage.Value) ? activeTrader.m_name : Localization.instance.TranslateSingleId(activeTrader.m_name, localizationLanguage.Value));
stringBuilder.Append(": ");
stringBuilder.Append(Utility.IsNullOrWhiteSpace(text5) ? "$npc_haldor_random_talk2" : text5);
}
else if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).InInterior())
{
text5 = GetRandomState(msgInDungeon.Value);
string text6 = "$tutorial_hildirdungeon_label";
Location zoneLocation = Location.GetZoneLocation(((Component)Player.m_localPlayer).transform.position);
if ((Object)(object)zoneLocation != (Object)null)
{
Teleport val = ((Component)zoneLocation).GetComponentsInChildren<Teleport>().First((Teleport tp) => !Utility.IsNullOrWhiteSpace(tp.m_enterText));
if ((Object)(object)val != (Object)null)
{
text6 = val.m_enterText;
}
}
stringBuilder.Append(Utility.IsNullOrWhiteSpace(localizationLanguage.Value) ? text6 : Localization.instance.TranslateSingleId(text6, localizationLanguage.Value));
if (!Utility.IsNullOrWhiteSpace(text5))
{
stringBuilder.Append(": ");
stringBuilder.Append(text5);
}
}
else if ((int)currentBiome > 0)
{
string text7 = BiomeSpecific(currentBiome);
if (safeInHome)
{
text5 = GetRandomState(msgAtHome.Value);
}
else if (onShip)
{
text5 = GetRandomState(msgSailing.Value);
}
else if (!Utility.IsNullOrWhiteSpace(text7))
{
text5 = text7;
}
string text8 = "$biome_" + ((object)(Biome)(ref currentBiome)).ToString().ToLower();
stringBuilder.Append(Utility.IsNullOrWhiteSpace(localizationLanguage.Value) ? text8 : Localization.instance.TranslateSingleId(text8, localizationLanguage.Value));
if (!Utility.IsNullOrWhiteSpace(text5))
{
stringBuilder.Append(": ");
stringBuilder.Append(text5);
}
}
details = Localization.instance.Localize(stringBuilder.ToString());
StringBuilder stringBuilder2 = new StringBuilder(256);
if (ZNet.IsSinglePlayer)
{
if (showGameState.Value)
{
stringBuilder2.Append(GetRandomState(msgSingleplayer.Value));
}
}
else
{
if (showServerName.Value)
{
stringBuilder2.Append(Utility.IsNullOrWhiteSpace(serverName.Value) ? ZNet.m_ServerName : serverName.Value);
}
if (showServerName.Value && showGameState.Value)
{
stringBuilder2.Append(": ");
}
if (showGameState.Value)
{
if (((Object)(object)ZNet.instance == (Object)null || playerCount == 1) && !Utility.IsNullOrWhiteSpace(msgMultiplayerAlone.Value))
{
stringBuilder2.Append(GetRandomState(msgMultiplayerAlone.Value));
}
else
{
stringBuilder2.Append(GetRandomState(msgMultiplayer.Value));
}
}
}
state = Localization.instance.Localize(stringBuilder2.ToString());
}
}
if (imageDescription.Count > 0)
{
string[] array = details.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (imageDescription.ContainsKey(array[0].Trim().Replace(" ", "_").ToLower()))
{
text = array[0].Trim().Replace(" ", "_").ToLower();
text2 = imageDescription[text];
}
if (array.Length > 1 && imageDescription.ContainsKey(array[1].Trim().Replace(" ", "_").ToLower()))
{
text3 = array[1].Trim().Replace(" ", "_").ToLower();
text4 = imageDescription[text3];
}
}
LogInfo("Details: \"" + details + "\"" + ((!Utility.IsNullOrWhiteSpace(text)) ? (", Large Image: " + text) : string.Empty) + ((!Utility.IsNullOrWhiteSpace(text2)) ? (", Large Text: \"" + text2 + "\"") : string.Empty) + ((!Utility.IsNullOrWhiteSpace(text3)) ? (", Small Image: " + text3) : string.Empty) + ((!Utility.IsNullOrWhiteSpace(text4)) ? (", Small Text: \"" + text4 + "\"") : string.Empty));
try
{
if (Utility.IsNullOrWhiteSpace(state) && Utility.IsNullOrWhiteSpace(details))
{
DiscordRpc.ClearPresence();
return;
}
DiscordRpc.RichPresence presence = new DiscordRpc.RichPresence
{
details = details,
state = state,
largeImageKey = (Utility.IsNullOrWhiteSpace(text) ? liKeyDefault.Value : text),
largeImageText = (Utility.IsNullOrWhiteSpace(text2) ? liTextDefault.Value : text2),
smallImageKey = (Utility.IsNullOrWhiteSpace(text3) ? siKeyDefault.Value : text3),
smallImageText = (Utility.IsNullOrWhiteSpace(text4) ? siTextDefault.Value : text4),
startTimestamp = (showIngameTime.Value ? started : 0),
partySize = ((showServerSize.Value && !ZNet.IsSinglePlayer && (Object)(object)ZNet.instance != (Object)null) ? playerCount : 0),
partyMax = ((showServerSize.Value && !ZNet.IsSinglePlayer) ? ((serverMaxCapacity.Value == 0) ? 10 : serverMaxCapacity.Value) : 0)
};
DiscordRpc.UpdatePresence(presence);
}
catch (Exception ex)
{
((BaseUnityPlugin)instance).Logger.LogWarning((object)ex);
}
}
}