using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Mistward.common;
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("Mistward")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mistward")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace Mistward
{
internal class Config
{
public static ConfigFile cfg;
public static ConfigEntry<bool> EnableDebugMode;
public static ConfigEntry<float> MistwardRange;
public Config(ConfigFile Config)
{
cfg = Config;
cfg.SaveOnConfigSet = true;
CreateConfigValues(Config);
}
private void CreateConfigValues(ConfigFile Config)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging for Mistward.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdvanced = true
} }));
MistwardRange = BindServerConfig("Mistward", "MistwardRange", 70f, "The distance the mistward effects.", advanced: false, 10f, 200f);
}
public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, ConfigDescription configDescription)
{
return cfg.Bind<string>(catagory, key, value, configDescription);
}
public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, bool advanced = false)
{
//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)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdminOnly = true,
IsAdvanced = advanced
} }));
}
public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, bool advanced = false)
{
//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)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdminOnly = true,
IsAdvanced = advanced
} }));
}
public static ConfigEntry<short> BindServerConfig(string catagory, string key, short value, string description, bool advanced = false, short valmin = 0, short valmax = 150)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
return cfg.Bind<short>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<short>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdminOnly = true,
IsAdvanced = advanced
} }));
}
public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdminOnly = true,
IsAdvanced = advanced
} }));
}
}
[BepInPlugin("MidnightsFX.Mistward", "Mistward", "0.7.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class Mistward : BaseUnityPlugin
{
public const string PluginGUID = "MidnightsFX.Mistward";
public const string PluginName = "Mistward";
public const string PluginVersion = "0.7.1";
internal static AssetBundle EmbeddedResourceBundle;
public Config cfg;
private void Awake()
{
cfg = new Config(((BaseUnityPlugin)this).Config);
EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("Mistward.AssetsEmbedded.mistward", typeof(Mistward).Assembly);
AddLocalizations();
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("name", "Mistward");
dictionary.Add("catagory", "Misc");
dictionary.Add("prefab", "MFX_Mistward");
dictionary.Add("sprite", "mistward_icon");
dictionary.Add("requiredBench", "piece_stonecutter");
new JotunnPiece(dictionary, new Dictionary<string, bool>(), new Dictionary<string, Tuple<int, bool>>
{
{
"BlackMarble",
Tuple.Create(30, item2: true)
},
{
"Copper",
Tuple.Create(15, item2: true)
},
{
"Sap",
Tuple.Create(10, item2: true)
},
{
"BlackCore",
Tuple.Create(1, item2: true)
}
});
}
internal static string ReadEmbeddedResourceFile(string filename)
{
using Stream stream = typeof(Mistward).Assembly.GetManifestResourceStream(filename);
using StreamReader streamReader = new StreamReader(stream);
return streamReader.ReadToEnd();
}
private void AddLocalizations()
{
CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
Logger.LogDebug((object)"Loading Localizations.");
string[] manifestResourceNames = typeof(Mistward).Assembly.GetManifestResourceNames();
foreach (string text in manifestResourceNames)
{
if (text.Contains("Localizations"))
{
string input = ReadEmbeddedResourceFile(text);
string text2 = Regex.Replace(input, "\\/\\/.*", "");
string[] array = text.Split(new char[1] { '.' });
Logger.LogDebug((object)("Adding localization: " + array[2]));
localization.AddJsonFile(array[2], text2);
}
}
}
}
}
namespace Mistward.common
{
public class JotunnPiece
{
private Dictionary<string, string> PieceMetadata;
private Dictionary<string, Tuple<int, bool>> RecipeData;
private Dictionary<string, bool> PieceToggles;
private Dictionary<string, Tuple<int, bool>> UpdatedRecipeData = new Dictionary<string, Tuple<int, bool>>();
private GameObject ScenePrefab;
private GameObject PiecePrefab;
private Sprite PieceSprite;
private ConfigEntry<bool> EnabledConfig;
private ConfigEntry<string> RecipeConfig;
private ConfigEntry<string> BuiltAt;
private ConfigEntry<string> BuildCategory;
private static ParticleSystemForceField mistward_pushfield;
public JotunnPiece(Dictionary<string, string> metadata, Dictionary<string, bool> pieceToggles, Dictionary<string, Tuple<int, bool>> recipedata)
{
PieceMetadata = metadata;
PieceToggles = pieceToggles;
RecipeData = recipedata;
PieceMetadata["short_item_name"] = string.Join("", metadata["name"].Split((string[]?)null, StringSplitOptions.RemoveEmptyEntries));
if (!PieceToggles.ContainsKey("enabled"))
{
PieceToggles.Add("enabled", value: true);
}
PiecePrefab = Mistward.EmbeddedResourceBundle.LoadAsset<GameObject>("Assets/Custom/Pieces/" + PieceMetadata["catagory"] + "/" + PieceMetadata["prefab"] + ".prefab");
PieceSprite = Mistward.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/" + PieceMetadata["sprite"] + ".png");
InitItemConfigs();
InitialPieceSetup();
mistward_pushfield = ((Component)ExposedGameObjectExtension.FindDeepChild(PiecePrefab, "Particle_System_Force_Field", (IterativeSearchType)1)).GetComponent<ParticleSystemForceField>();
mistward_pushfield.endRange = Config.MistwardRange.Value;
Config.MistwardRange.SettingChanged += MistwardRangeChange;
PrefabManager.OnPrefabsRegistered += SetSceneParentPrefab;
}
private void MistwardRangeChange(object sender, EventArgs e)
{
mistward_pushfield.endRange = Config.MistwardRange.Value;
IEnumerable<GameObject> enumerable = from obj in Resources.FindObjectsOfTypeAll<GameObject>()
where ((Object)obj).name.StartsWith(PieceMetadata["prefab"])
select obj;
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)$"Found in scene objects: {enumerable.Count()}");
}
foreach (GameObject item in enumerable)
{
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)("Found " + ((Object)item).name));
}
ParticleSystemForceField val = null;
((Component)ExposedGameObjectExtension.FindDeepChild(item, "Particle_System_Force_Field", (IterativeSearchType)1)).TryGetComponent<ParticleSystemForceField>(ref val);
if ((Object)(object)val != (Object)null)
{
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)$"{((Object)item).name} updating forcefield {Config.MistwardRange.Value}");
}
val.endRange = Config.MistwardRange.Value;
}
}
}
private void InitialPieceSetup()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
//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_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Expected O, but got Unknown
//IL_00fe: 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_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: 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_0157: Expected O, but got Unknown
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Expected O, but got Unknown
CreateAndUpdateRecipe();
BuildCategory = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-category", "Misc", new ConfigDescription("Build piece Category.", (AcceptableValueBase)(object)PieceCategories.GetAcceptableValueList(), Array.Empty<object>()));
BuildCategory.SettingChanged += CraftingCategory_SettingChanged;
RequirementConfig[] array = (RequirementConfig[])(object)new RequirementConfig[UpdatedRecipeData.Count];
int num = 0;
foreach (KeyValuePair<string, Tuple<int, bool>> updatedRecipeDatum in UpdatedRecipeData)
{
array[num] = new RequirementConfig
{
Item = updatedRecipeDatum.Key,
Amount = updatedRecipeDatum.Value.Item1,
Recover = updatedRecipeDatum.Value.Item2
};
num++;
}
PieceConfig val = new PieceConfig
{
CraftingStation = (PieceMetadata["requiredBench"] ?? ""),
PieceTable = PieceTables.Hammer,
Category = BuildCategory.Value,
Icon = PieceSprite,
Requirements = array
};
PieceManager.Instance.AddPiece(new CustomPiece(PiecePrefab, true, val));
}
private void SetSceneParentPrefab()
{
IEnumerable<GameObject> source = from obj in Resources.FindObjectsOfTypeAll<GameObject>()
where ((Object)obj).name == PieceMetadata["prefab"]
select obj;
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)string.Format("Found {0} scene parent objects: {1}", PieceMetadata["prefab"], source.Count()));
}
ScenePrefab = source.First();
}
private void CreateAndUpdateRecipe()
{
string text = "";
foreach (KeyValuePair<string, Tuple<int, bool>> recipeDatum in RecipeData)
{
if (text.Length > 0)
{
text += "|";
}
text += $"{recipeDatum.Key},{recipeDatum.Value.Item1},{recipeDatum.Value.Item2}";
}
RecipeConfig = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-recipe", text, "Recipe to craft and upgrade costs. Find item ids: https://valheim.fandom.com/wiki/Item_IDs, at most 4 costs. Format: resouce_id,craft_cost,upgrade_cost eg: Wood,8,2|Iron,12,4|LeatherScraps,4,0", advanced: true);
if (!PieceRecipeConfigUpdater(RecipeConfig.Value, startup: true))
{
Logger.LogWarning((object)(PieceMetadata["name"] + " has an invalid recipe. The default will be used instead."));
PieceRecipeConfigUpdater(text, startup: true);
}
RecipeConfig.SettingChanged += BuildRecipeChanged_SettingChanged;
}
private void InitItemConfigs()
{
EnabledConfig = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-enabled", PieceToggles["enabled"], "Enable/Disable the " + PieceMetadata["name"] + ".");
PieceToggles["enabled"] = EnabledConfig.Value;
EnabledConfig.SettingChanged += BuildRecipeChanged_SettingChanged;
BuiltAt = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-requiredBench", PieceMetadata["requiredBench"], "The table required to allow building this piece, eg: 'forge', 'piece_workbench', 'blackforge', 'piece_artisanstation'.");
PieceMetadata["requiredBench"] = BuiltAt.Value;
BuiltAt.SettingChanged += RequiredBench_SettingChanged;
}
private void BuildRecipeChanged_SettingChanged(object sender, EventArgs e)
{
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Expected O, but got Unknown
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_020d: Expected O, but got Unknown
if (sender.GetType() == typeof(ConfigEntry<string>))
{
ConfigEntry<string> val = (ConfigEntry<string>)sender;
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)("Recieved new piece config " + val.Value));
}
if (!PieceRecipeConfigUpdater(val.Value))
{
return;
}
}
RequirementConfig[] array = (RequirementConfig[])(object)new RequirementConfig[UpdatedRecipeData.Count];
int num = 0;
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)"Validating and building requirementsConfig");
}
foreach (KeyValuePair<string, Tuple<int, bool>> updatedRecipeDatum in UpdatedRecipeData)
{
if ((Object)(object)PrefabManager.Instance.GetPrefab(updatedRecipeDatum.Key) == (Object)null)
{
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)(updatedRecipeDatum.Key + " is not a valid prefab, skipping recipe update."));
}
return;
}
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)$"Checking entry {updatedRecipeDatum.Key} c:{updatedRecipeDatum.Value.Item1} r:{updatedRecipeDatum.Value.Item2}");
}
array[num] = new RequirementConfig
{
Item = updatedRecipeDatum.Key,
Amount = updatedRecipeDatum.Value.Item1,
Recover = updatedRecipeDatum.Value.Item2
};
num++;
}
if (PieceToggles["enabled"])
{
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)"Updating Piece.");
}
Requirement[] array2 = (Requirement[])(object)new Requirement[UpdatedRecipeData.Count];
int num2 = 0;
RequirementConfig[] array3 = array;
foreach (RequirementConfig val2 in array3)
{
Requirement val3 = new Requirement();
GameObject prefab = PrefabManager.Instance.GetPrefab(val2.Item.Replace("JVLmock_", ""));
val3.m_resItem = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null);
val3.m_amount = val2.Amount;
val3.m_recover = val2.Recover;
array2[num2] = val3;
num2++;
}
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)$"Fixed mock requirements {array2.Length}.");
}
ScenePrefab.GetComponent<Piece>().m_resources = array2;
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)$"New requirements set {ScenePrefab.GetComponent<Piece>().m_resources}.");
}
}
else
{
ScenePrefab.GetComponent<Piece>().m_enabled = false;
}
}
private void RequiredBench_SettingChanged(object sender, EventArgs e)
{
if (BuiltAt.Value == "" || BuiltAt.Value == null || BuiltAt.Value.ToLower() == "NONE")
{
Logger.LogInfo((object)"Setting required crafting station to none.");
ScenePrefab.GetComponent<Piece>().m_craftingStation = null;
return;
}
GameObject prefab = PrefabManager.Instance.GetPrefab(BuiltAt.Value);
CraftingStation val = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
if ((Object)(object)val == (Object)null)
{
Logger.LogWarning((object)("Required crafting station does not exist or does not have a crafting station componet, check your prefab name (" + BuiltAt.Value + ")."));
return;
}
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)("Setting crafting station to " + BuiltAt.Value + "."));
}
ScenePrefab.GetComponent<Piece>().m_craftingStation = val;
}
private void CraftingCategory_SettingChanged(object sender, EventArgs e)
{
//IL_002b: 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)
ScenePrefab.GetComponent<Piece>().m_category = (PieceCategory)Enum.Parse(typeof(PieceCategory), PieceCategories.GetInternalName(BuildCategory.Value));
}
private bool PieceRecipeConfigUpdater(string rawrecipe, bool startup = false)
{
string[] array = rawrecipe.Split(new char[1] { '|' });
Dictionary<string, Tuple<int, bool>> dictionary = new Dictionary<string, Tuple<int, bool>>();
if (array.Length >= 1)
{
string[] array2 = array;
foreach (string text in array2)
{
string[] array3 = text.Split(new char[1] { ',' });
if (array3.Length != 3)
{
Logger.LogWarning((object)(text + " is invalid, it does not have enough segments. Proper format is: PREFABNAME,COST,REFUND_BOOL eg: Wood,8,false"));
return false;
}
if (Config.EnableDebugMode.Value)
{
string text2 = "";
string[] array4 = array3;
foreach (string text3 in array4)
{
text2 = text2 + " " + text3;
}
}
if (!startup && (Object)(object)PrefabManager.Instance.GetPrefab(array3[0]) == (Object)null)
{
Logger.LogWarning((object)(array3[0] + " is an invalid prefab and does not exist."));
return false;
}
if (array3[0].Length == 0 || array3[1].Length == 0 || array3[2].Length == 0)
{
Logger.LogWarning((object)(text + " is invalid, one segment does not have enough data. Proper format is: PREFABNAME,CRAFT_COST,REFUND_BOOL eg: Wood,8,false"));
return false;
}
if (!bool.TryParse(array3[2], out var result))
{
Logger.LogWarning((object)(text + " is invalid, the REFUND_BOOL could not be parsed to (true/false). Proper format is: PREFABNAME,CRAFT_COST,REFUND_BOOL eg: Wood,8,false"));
return false;
}
if (Config.EnableDebugMode.Value)
{
Logger.LogInfo((object)("prefab: " + array3[0] + " c:" + array3[1] + " u:" + array3[2]));
}
dictionary.Add(array3[0], new Tuple<int, bool>(int.Parse(array3[1]), result));
}
UpdatedRecipeData.Clear();
foreach (KeyValuePair<string, Tuple<int, bool>> item in dictionary)
{
UpdatedRecipeData.Add(item.Key, item.Value);
}
if (Config.EnableDebugMode.Value)
{
string text4 = "";
foreach (KeyValuePair<string, Tuple<int, bool>> item2 in dictionary)
{
text4 += $" {item2.Key} c:{item2.Value.Item1} r:{item2.Value.Item2}";
}
Logger.LogInfo((object)("Updated recipe:" + text4));
}
return true;
}
Logger.LogWarning((object)("Invalid recipe: " + rawrecipe + ". defaults will be used. Check your prefab names."));
UpdatedRecipeData = RecipeData;
return false;
}
}
}