using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Kalamies")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("StrongerBeer")]
[assembly: AssemblyTitle("StrongerBeer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace StrongerBeer
{
[BepInPlugin("kalamies.StrongerBeer", "StrongerBeer", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "kalamies.StrongerBeer";
public const string Name = "StrongerBeer";
public const string Version = "0.1.0";
internal static ManualLogSource Log;
private void Awake()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
try
{
new Harmony("kalamies.StrongerBeer").PatchAll();
}
catch (Exception arg)
{
Log.LogError((object)$"Could not patch; bait models may look wrong. {arg}");
}
((MonoBehaviour)this).StartCoroutine(Run());
}
private IEnumerator Run()
{
while ((Object)(object)LocalizationSettings.SelectedLocale == (Object)null || GameInfo.AllCreatureCount == 0)
{
yield return null;
}
try
{
Text.Apply();
}
catch (Exception arg)
{
Log.LogError((object)$"Text pass failed, game untouched: {arg}");
}
try
{
Models.Apply();
}
catch (Exception arg2)
{
Log.LogError((object)$"Model pass failed, game untouched: {arg2}");
}
LocalizationSettings.SelectedLocaleChanged += delegate
{
((MonoBehaviour)this).StartCoroutine(Reapply());
};
SceneManager.sceneLoaded += delegate
{
try
{
Models.ApplyToScene();
}
catch (Exception ex)
{
Log.LogWarning((object)("Scene pass failed: " + ex.Message));
}
};
}
private IEnumerator Reapply()
{
yield return (object)new WaitForSeconds(1f);
try
{
Text.Apply();
}
catch (Exception ex)
{
Log.LogWarning((object)("Re-apply failed: " + ex.Message));
}
}
}
internal static class Text
{
private static readonly (string Pattern, string Replacement)[] Rules = new(string, string)[14]
{
("empty beer cans", "empty Koskenkorva bottles"),
("empty beer can", "empty Koskenkorva bottle"),
("Empty Beer Can", "Empty Koskenkorva Bottle"),
("beer can", "Koskenkorva bottle"),
("\\bBeer\\b", "Koskenkorva"),
("\\bbeer\\b", "Koskenkorva"),
("Leere Bierdose", "Leere Koskenkorva-Flasche"),
("leeren bierdose", "leeren Koskenkorva-Flasche"),
("\\bBierdose\\b", "Koskenkorva-Flasche"),
("\\bBier\\b", "Koskenkorva"),
("Lattina di birra vuota", "Bottiglia di Koskenkorva vuota"),
("lattina di birra", "bottiglia di Koskenkorva"),
("\\bBirra\\b", "Koskenkorva"),
("\\bbirra\\b", "Koskenkorva")
};
internal static void Apply()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
foreach (StringTable item in ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetAllTables((Locale)null).WaitForCompletion())
{
if ((Object)(object)item == (Object)null)
{
continue;
}
foreach (StringTableEntry value in ((DetailedLocalizationTable<StringTableEntry>)(object)item).Values)
{
if (value == null)
{
continue;
}
string localizedValue = ((TableEntry)value).LocalizedValue;
if (!string.IsNullOrEmpty(localizedValue))
{
string text = Rules.Aggregate(localizedValue, (string input, (string Pattern, string Replacement) rule) => Regex.Replace(input, rule.Pattern, rule.Replacement));
if (!(text == localizedValue))
{
value.Value = text;
}
}
}
}
}
}
internal static class Models
{
private const string BundleFile = "koskenkorva.bundle";
private static readonly string[] OriginalMeshes = new string[1] { "beercan" };
private static Mesh _source;
private static Material _material;
private static Mesh _bottle;
private static readonly Dictionary<MeshRenderer, Material> Borrowed = new Dictionary<MeshRenderer, Material>();
private static Item Beer
{
get
{
if (!GameInfo._nameToSpawnable.TryGetValue("beer", out var value))
{
return null;
}
return value;
}
}
internal static void Apply()
{
var (val, val2) = LoadModel();
if (!Object.op_Implicit((Object)(object)val))
{
Plugin.Log.LogWarning((object)"No bottle model available; text changed, models left alone.");
return;
}
CheckShader(val2);
_source = val;
_material = (Object.op_Implicit((Object)(object)val2) ? val2 : CloneMaterialFrom(Beer));
Item beer = Beer;
if (!Build(Reference(beer)))
{
return;
}
if (Object.op_Implicit((Object)(object)beer))
{
MeshFilter[] componentsInChildren = ((Component)beer).GetComponentsInChildren<MeshFilter>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Swap(componentsInChildren[i]);
}
if (IsOriginal(beer._mesh))
{
beer._mesh = _bottle;
}
}
else
{
Plugin.Log.LogWarning((object)"Could not find the beer item.");
}
foreach (BaitInfo allBait in GameInfo.AllBaits)
{
if (Object.op_Implicit((Object)(object)allBait) && ((Object)allBait).name.IndexOf("beercan", StringComparison.OrdinalIgnoreCase) >= 0)
{
if (IsOriginal(allBait._mesh))
{
allBait._mesh = _bottle;
}
if (IsOriginal(allBait._meshForNpc))
{
allBait._meshForNpc = _bottle;
}
}
}
ApplyToScene();
}
internal static void ApplyToScene()
{
if (!Object.op_Implicit((Object)(object)_bottle))
{
return;
}
MeshFilter[] array = Resources.FindObjectsOfTypeAll<MeshFilter>();
foreach (MeshFilter val in array)
{
if (Object.op_Implicit((Object)(object)val))
{
Swap(val);
}
}
}
internal static void Materialise(MeshFilter filter)
{
try
{
MeshRenderer val = default(MeshRenderer);
if (!Object.op_Implicit((Object)(object)filter) || !((Component)filter).TryGetComponent<MeshRenderer>(ref val))
{
return;
}
Material value;
if (Object.op_Implicit((Object)(object)_bottle) && Object.op_Implicit((Object)(object)_material) && (Object)(object)filter.sharedMesh == (Object)(object)_bottle)
{
if (!Borrowed.ContainsKey(val))
{
Borrowed[val] = ((Renderer)val).sharedMaterial;
}
((Renderer)val).sharedMaterial = _material;
}
else if (Borrowed.TryGetValue(val, out value))
{
((Renderer)val).sharedMaterial = value;
Borrowed.Remove(val);
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Could not set the bottle material: " + ex.Message));
}
}
private static void Swap(MeshFilter filter)
{
if (Object.op_Implicit((Object)(object)_bottle) && IsOriginal(filter.sharedMesh))
{
filter.sharedMesh = _bottle;
MeshRenderer val = default(MeshRenderer);
if (Object.op_Implicit((Object)(object)_material) && ((Component)filter).TryGetComponent<MeshRenderer>(ref val))
{
((Renderer)val).sharedMaterial = _material;
}
}
}
private static Mesh Reference(Item beer)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: 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)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)beer))
{
if (IsOriginal(beer._mesh))
{
return beer._mesh;
}
MeshFilter[] componentsInChildren = ((Component)beer).GetComponentsInChildren<MeshFilter>(true);
foreach (MeshFilter val in componentsInChildren)
{
if (IsOriginal(val.sharedMesh))
{
return val.sharedMesh;
}
}
}
Mesh val2 = null;
Mesh[] array = Resources.FindObjectsOfTypeAll<Mesh>();
foreach (Mesh val3 in array)
{
if (!IsOriginal(val3))
{
continue;
}
if (Object.op_Implicit((Object)(object)val2))
{
Bounds bounds = val3.bounds;
float num = Longest(((Bounds)(ref bounds)).size);
bounds = val2.bounds;
if (!(num > Longest(((Bounds)(ref bounds)).size)))
{
continue;
}
}
val2 = val3;
}
return val2;
}
private static bool Build(Mesh reference)
{
//IL_0026: 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_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: 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_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)_source) || !Object.op_Implicit((Object)(object)reference))
{
Plugin.Log.LogWarning((object)"Nothing to size the bottle against; models left alone.");
return false;
}
Bounds bounds = reference.bounds;
float num = Longest(((Bounds)(ref bounds)).size);
bounds = _source.bounds;
float num2 = Longest(((Bounds)(ref bounds)).size);
if (num <= 0f || num2 <= 0f)
{
return false;
}
float num3 = num / num2;
Mesh val = Object.Instantiate<Mesh>(_source);
((Object)val).name = "KoskenkorvaBottle";
if (!_source.isReadable)
{
Plugin.Log.LogWarning((object)("'" + ((Object)_source).name + "' is not readable, so it cannot be resized here. It is " + Size(_source) + " against the can's " + Size(reference) + " - either scale the model to match via the importer's Scale Factor, or tick Read/Write Enabled to let this resize it."));
_bottle = _source;
return true;
}
Vector3[] vertices = val.vertices;
for (int i = 0; i < vertices.Length; i++)
{
ref Vector3 reference2 = ref vertices[i];
reference2 *= num3;
}
val.vertices = vertices;
val.RecalculateBounds();
_bottle = val;
return true;
}
private static string Size(Mesh mesh)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
Bounds bounds = mesh.bounds;
Vector3 size = ((Bounds)(ref bounds)).size;
return $"{size.x:0.####} x {size.y:0.####} x {size.z:0.####} units (longest {Longest(size):0.####})";
}
private static bool IsOriginal(Mesh mesh)
{
if (Object.op_Implicit((Object)(object)mesh))
{
return OriginalMeshes.Any((string n) => ((Object)mesh).name.IndexOf(n, StringComparison.OrdinalIgnoreCase) >= 0);
}
return false;
}
private static bool Approximately(Vector3 v, Vector3 to)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (Mathf.Approximately(v.x, to.x) && Mathf.Approximately(v.y, to.y))
{
return Mathf.Approximately(v.z, to.z);
}
return false;
}
private static float Longest(Vector3 size)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//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)
return Mathf.Max(size.x, Mathf.Max(size.y, size.z));
}
private static (Mesh, Material) LoadModel()
{
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: 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)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? ".", "koskenkorva.bundle");
if (!File.Exists(text))
{
Plugin.Log.LogWarning((object)"koskenkorva.bundle is missing from the plugin folder.");
return (null, null);
}
try
{
AssetBundle val = AssetBundle.LoadFromFile(text);
if (!Object.op_Implicit((Object)(object)val))
{
Plugin.Log.LogWarning((object)"koskenkorva.bundle could not be opened.");
return (null, null);
}
GameObject[] array = val.LoadAllAssets<GameObject>();
foreach (GameObject val2 in array)
{
MeshFilter val3 = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponentInChildren<MeshFilter>(true) : null);
if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val3.sharedMesh))
{
Vector3 localScale = val2.transform.localScale;
Vector3 localScale2 = ((Component)val3).transform.localScale;
if (!Approximately(localScale, Vector3.one) || !Approximately(localScale2, Vector3.one))
{
Plugin.Log.LogWarning((object)($"The bundled prefab is scaled ({localScale.x:0.###},{localScale.y:0.###},{localScale.z:0.###}) " + $"with the mesh at ({localScale2.x:0.###},{localScale2.y:0.###},{localScale2.z:0.###}). That scale " + "is ignored - set the size on the model importer's Scale Factor instead."));
}
Renderer component = ((Component)val3).GetComponent<Renderer>();
return (val3.sharedMesh, Object.op_Implicit((Object)(object)component) ? component.sharedMaterial : null);
}
}
Mesh val4 = ((IEnumerable<Mesh>)val.LoadAllAssets<Mesh>()).FirstOrDefault((Func<Mesh, bool>)((Mesh m) => Object.op_Implicit((Object)(object)m)));
Material item = ((IEnumerable<Material>)val.LoadAllAssets<Material>()).FirstOrDefault((Func<Material, bool>)((Material m) => Object.op_Implicit((Object)(object)m)));
if (!Object.op_Implicit((Object)(object)val4))
{
Plugin.Log.LogWarning((object)"koskenkorva.bundle holds no mesh.");
}
return (val4, item);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("koskenkorva.bundle failed to load: " + ex.Message));
return (null, null);
}
}
private static void CheckShader(Material material)
{
if (Object.op_Implicit((Object)(object)material) && (!Object.op_Implicit((Object)(object)material.shader) || ((Object)material.shader).name == "Hidden/InternalErrorShader"))
{
Plugin.Log.LogError((object)"The bundle's shader did not load, so the bottle will be magenta. Usual causes: the bundle was built by an editor other than 6000.4.4f1, the shader was not a dependency of the tagged prefab, or its name collides with one already in the game.");
}
}
private static Material CloneMaterialFrom(Item item)
{
//IL_0030: 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_0041: Expected O, but got Unknown
Renderer val = (Object.op_Implicit((Object)(object)item) ? ((Component)item).GetComponentInChildren<Renderer>(true) : null);
if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.sharedMaterial))
{
return null;
}
return new Material(val.sharedMaterial)
{
name = "KoskenkorvaBottle"
};
}
}
[HarmonyPatch(typeof(Bait), "SetBaitInfo")]
internal static class SetBaitInfo_Patch
{
private static void Postfix(Bait __instance)
{
Models.Materialise(__instance._meshFilter);
}
}
[HarmonyPatch(typeof(BaitSlot), "SetBait")]
internal static class SetBait_Patch
{
private static void Postfix(BaitSlot __instance)
{
Models.Materialise(((InventorySlot)__instance)._filter);
}
}
[HarmonyPatch(typeof(QuestInteractable), "SetQuest")]
internal static class SetQuest_Patch
{
private static void Postfix(QuestInteractable __instance)
{
Models.Materialise(__instance._meshToUpdate);
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}