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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using ExpandWorldData;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ServerSync;
using Service;
using UnityEngine;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ExpandWorldMusic")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+731222ea1219a36615ddb8ae50d210f6cab01a4a")]
[assembly: AssemblyProduct("ExpandWorldMusic")]
[assembly: AssemblyTitle("ExpandWorldMusic")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 ExpandWorld.Music
{
public class Configuration
{
public static CustomSyncedValue<string> valueMusicData;
public static void Init(ConfigWrapper wrapper)
{
valueMusicData = wrapper.AddValue("music_data");
((CustomSyncedValueBase)valueMusicData).ValueChanged += delegate
{
Manager.FromSetting(valueMusicData.Value);
};
}
}
[HarmonyPatch(typeof(Terminal), "InitTerminal")]
public class SetCommands
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Func<string, string> <>9__0_1;
public static ConsoleEvent <>9__0_0;
internal void <Postfix>b__0_0(ConsoleEventArgs args)
{
ZLog.Log((object)string.Join("\n", Loader.Clips.Keys.OrderBy((string k) => k)));
}
internal string <Postfix>b__0_1(string k)
{
return k;
}
}
private static void Postfix()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
object obj = <>c.<>9__0_0;
if (obj == null)
{
ConsoleEvent val = delegate
{
ZLog.Log((object)string.Join("\n", Loader.Clips.Keys.OrderBy((string k) => k)));
};
<>c.<>9__0_0 = val;
obj = (object)val;
}
new ConsoleCommand("ew_musics", "- Prints available music clips.", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
}
}
[BepInPlugin("expand_world_music", "Expand World Music", "1.4")]
[BepInDependency("expand_world_data", "1.27")]
public class EWM : BaseUnityPlugin
{
public const string GUID = "expand_world_music";
public const string NAME = "Expand World Music";
public const string VERSION = "1.4";
public static ConfigSync ConfigSync = new ConfigSync("expand_world_music")
{
DisplayName = "Expand World Music",
CurrentVersion = "1.4",
ModRequired = true,
IsLocked = true
};
public void Awake()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
Configuration.Init(new ConfigWrapper("expand_music_config", ((BaseUnityPlugin)this).Config, ConfigSync, (Action)delegate
{
}));
new Harmony("expand_world_music").PatchAll();
try
{
if (Configuration.DataReload)
{
Manager.SetupWatcher();
}
}
catch (Exception ex)
{
Log.Error(ex.StackTrace);
}
}
}
public class Loader
{
public static Dictionary<string, AudioClip> Clips = new Dictionary<string, AudioClip>();
public static NamedMusic FromData(Data data)
{
//IL_0000: 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_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: 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)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Expected O, but got Unknown
return new NamedMusic
{
m_alwaysFadeout = data.alwaysFadeOut,
m_ambientMusic = data.ambientMusic,
m_clips = (from c in data.clips.Select(PreloadClipCoroutine)
where (Object)(object)c != (Object)null
select c).Cast<AudioClip>().ToArray(),
m_enabled = true,
m_fadeInTime = data.fadeInTime,
m_loop = data.loop,
m_name = data.name,
m_resume = data.resume,
m_volume = data.volume
};
}
public static Data ToData(NamedMusic music)
{
return new Data
{
alwaysFadeOut = music.m_alwaysFadeout,
ambientMusic = music.m_ambientMusic,
clips = (from c in music.m_clips
where ((c != null) ? ((Object)c).name : null) != null
select ((Object)c).name).ToArray(),
fadeInTime = music.m_fadeInTime,
loop = music.m_loop,
name = music.m_name,
resume = music.m_resume,
volume = music.m_volume
};
}
public static void InitializeDefaultClips()
{
Clips = (from c in MusicMan.instance.m_music.SelectMany((NamedMusic m) => m.m_clips)
where ((c != null) ? ((Object)c).name : null) != null
select c).Distinct(new Comparer()).ToDictionary((AudioClip c) => ((Object)c).name, (AudioClip c) => c);
Clips["empty"] = null;
AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
foreach (AudioClip val in array)
{
string key = ((Object)val).name;
int num = 2;
while (Clips.ContainsKey(key) && !((Object)(object)Clips[key] == (Object)(object)val))
{
key = ((Object)val).name + "_" + num++;
}
if (!Clips.ContainsKey(key))
{
Clips.Add(key, val);
}
}
}
private static AudioClip? PreloadClipCoroutine(string path)
{
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
if (Clips.ContainsKey(path))
{
return Clips[path];
}
if (!File.Exists(path))
{
path = Path.Combine(Yaml.Directory, path);
}
if (Clips.ContainsKey(path))
{
return Clips[path];
}
if (!File.Exists(path))
{
Log.Warning("Can't find audio clip at " + path);
return null;
}
string text = "file:///" + path.Replace("\\", "/");
try
{
UnityWebRequest val = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)0) ?? throw new Exception();
val.SendWebRequest();
while (!val.isDone)
{
}
AudioClip val2 = ((DownloadHandlerAudioClip)val.downloadHandler).audioClip ?? throw new Exception();
((Object)val2).name = Path.GetFileNameWithoutExtension(path);
Clips.Add(path, val2);
return val2;
}
catch
{
Log.Warning("Failed to load audio clip at " + path);
}
return null;
}
}
public class Comparer : IEqualityComparer<AudioClip>
{
public bool Equals(AudioClip x, AudioClip y)
{
return ((Object)x).name == ((Object)y).name;
}
public int GetHashCode(AudioClip obj)
{
return StringExtensionMethods.GetStableHashCode(((Object)obj).name);
}
}
public class Manager
{
public static string FileName = "expand_music.yaml";
public static string FilePath = Path.Combine(Yaml.Directory, FileName);
public static string Pattern = "expand_music*.yaml";
public static List<NamedMusic> Originals = new List<NamedMusic>();
public static bool IsServer()
{
if (Object.op_Implicit((Object)(object)ZNet.instance))
{
return ZNet.instance.IsServer();
}
return true;
}
public static void ToFile()
{
if (IsServer() && !File.Exists(FilePath))
{
string contents = Yaml.Serializer().Serialize((object)MusicMan.instance.m_music.Select(Loader.ToData).ToList());
File.WriteAllText(FilePath, contents);
}
}
public static void FromFile()
{
if (IsServer())
{
string text = DataManager.Read(Pattern);
Set(text);
Configuration.valueMusicData.Value = text;
}
}
public static void FromSetting(string yaml)
{
if (!IsServer())
{
Set(yaml);
}
}
private static void Set(string yaml)
{
if (IsServer() && Originals.Count == 0)
{
List<NamedMusic> music = MusicMan.instance.m_music;
List<NamedMusic> list = new List<NamedMusic>(music.Count);
list.AddRange(music);
Originals = list;
}
if (yaml == "")
{
return;
}
try
{
List<NamedMusic> list2 = Yaml.Deserialize<Data>(yaml, FileName).Select(Loader.FromData).ToList();
if (list2.Count == 0)
{
Log.Warning("Failed to load any music data.");
}
else if (!Configuration.DataMigration || !Helper.IsServer() || !AddMissingEntries(list2))
{
Log.Info($"Reloading music data ({list2.Count} entries).");
MusicMan.instance.m_music = list2;
UpdateHashes();
string text = MusicMan.instance.m_currentMusic?.m_name ?? "";
MusicMan.instance.Reset();
MusicMan.instance.StartMusic(text);
}
}
catch (Exception ex)
{
Log.Error(ex.Message);
Log.Error(ex.StackTrace);
}
}
private static bool AddMissingEntries(List<NamedMusic> entries)
{
HashSet<string> missingKeys = Originals.Select((NamedMusic e) => e.m_name).Distinct().ToHashSet();
foreach (NamedMusic entry in entries)
{
missingKeys.Remove(entry.m_name);
}
if (missingKeys.Count == 0)
{
return false;
}
List<NamedMusic> list = Originals.Where((NamedMusic item) => missingKeys.Contains(item.m_name)).ToList();
Log.Warning($"Adding {list.Count} missing music to the expand_music.yaml file.");
foreach (NamedMusic item in list)
{
Log.Warning(item.m_name);
}
string text = File.ReadAllText(FilePath);
string text2 = Yaml.Serializer().Serialize((object)list.Select(Loader.ToData));
text = text + "\n" + text2;
File.WriteAllText(FilePath, text);
return true;
}
private static void UpdateHashes()
{
MusicMan instance = MusicMan.instance;
instance.m_musicHashes.Clear();
foreach (NamedMusic item in instance.m_music)
{
if (item.m_enabled && item.m_clips.Length != 0 && !((Object)(object)item.m_clips[0] == (Object)null))
{
instance.m_musicHashes.Add(StringExtensionMethods.GetStableHashCode(item.m_name), item);
}
}
}
public static void SetupWatcher()
{
Yaml.SetupWatcher(Pattern, (Action)FromFile);
}
}
[HarmonyPatch(typeof(MusicMan), "Awake")]
[HarmonyPriority(0)]
public class InitializeContent
{
private static void Postfix()
{
Loader.InitializeDefaultClips();
Manager.ToFile();
Manager.FromFile();
}
}
public class Data
{
public string name = "";
public string[] clips = Array.Empty<string>();
public float volume;
public float fadeInTime;
public bool alwaysFadeOut;
public bool ambientMusic;
public bool loop;
public bool resume;
}
}