ModMusic.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Runtime.CompilerServices;
  6. using System.Threading;
  7. using System.Windows.Controls;
  8. using Microsoft.VisualBasic.CompilerServices;
  9. using NAudio;
  10. using NAudio.Wave;
  11. namespace PCL
  12. {
  13. // Token: 0x020000B4 RID: 180
  14. [StandardModule]
  15. public sealed class ModMusic
  16. {
  17. // Token: 0x06000573 RID: 1395 RVA: 0x0002EDFC File Offset: 0x0002CFFC
  18. private static void MusicListInit(bool ForceReload, string PreventFirst = null)
  19. {
  20. if (ForceReload)
  21. {
  22. ModMusic.m_SpecificationField = null;
  23. }
  24. try
  25. {
  26. if (ModMusic.m_SpecificationField == null)
  27. {
  28. ModMusic.m_SpecificationField = new List<string>();
  29. Directory.CreateDirectory(ModBase.Path + "PCL\\Musics\\");
  30. try
  31. {
  32. foreach (FileInfo fileInfo in ModBase.EnumerateFiles(ModBase.Path + "PCL\\Musics\\"))
  33. {
  34. string text = fileInfo.Extension.ToLower();
  35. if (!Enumerable.Contains<string>(new string[]
  36. {
  37. ".ini",
  38. ".jpg",
  39. ".txt",
  40. ".cfg",
  41. ".lrc",
  42. ".db",
  43. ".png"
  44. }, text))
  45. {
  46. ModMusic.m_SpecificationField.Add(fileInfo.FullName);
  47. }
  48. }
  49. }
  50. finally
  51. {
  52. IEnumerator<FileInfo> enumerator;
  53. if (enumerator != null)
  54. {
  55. enumerator.Dispose();
  56. }
  57. }
  58. }
  59. ModMusic._ContextField = (List<string>)(Conversions.ToBoolean(ModBase.m_IdentifierRepository.Get("UiMusicRandom", null)) ? ModBase.Shuffle<string>(new List<string>(ModMusic.m_SpecificationField)) : new List<string>(ModMusic.m_SpecificationField));
  60. if (PreventFirst != null && Operators.CompareString(Enumerable.FirstOrDefault<string>(ModMusic._ContextField), PreventFirst, false) == 0)
  61. {
  62. ModMusic._ContextField.RemoveAt(0);
  63. ModMusic._ContextField.Add(PreventFirst);
  64. }
  65. }
  66. catch (Exception ex)
  67. {
  68. ModBase.Log(ex, "初始化音乐列表失败", ModBase.LogLevel.Feedback, "出现错误");
  69. }
  70. }
  71. // Token: 0x06000574 RID: 1396 RVA: 0x0002EF94 File Offset: 0x0002D194
  72. private static string DequeueNextMusicAddress()
  73. {
  74. if (ModMusic.m_SpecificationField == null || !Enumerable.Any<string>(ModMusic.m_SpecificationField) || !Enumerable.Any<string>(ModMusic._ContextField))
  75. {
  76. ModMusic.MusicListInit(false, null);
  77. }
  78. string text;
  79. if (Enumerable.Any<string>(ModMusic._ContextField))
  80. {
  81. text = ModMusic._ContextField[0];
  82. ModMusic._ContextField.RemoveAt(0);
  83. }
  84. else
  85. {
  86. text = null;
  87. }
  88. if (!Enumerable.Any<string>(ModMusic._ContextField))
  89. {
  90. ModMusic.MusicListInit(false, text);
  91. }
  92. return text;
  93. }
  94. // Token: 0x06000575 RID: 1397 RVA: 0x00004E9D File Offset: 0x0000309D
  95. private static void MusicRefreshUI()
  96. {
  97. ModBase.RunInUi((ModMusic._Closure$__.$I5-0 == null) ? (ModMusic._Closure$__.$I5-0 = delegate()
  98. {
  99. try
  100. {
  101. if (!Enumerable.Any<string>(ModMusic.m_SpecificationField))
  102. {
  103. ModMain._ProcessIterator.BtnExtraMusic.Show = false;
  104. }
  105. else
  106. {
  107. ModMain._ProcessIterator.BtnExtraMusic.Show = true;
  108. string text;
  109. if (ModMusic.ReflectReader() == ModMusic.MusicStates.Pause)
  110. {
  111. ModMain._ProcessIterator.BtnExtraMusic.Logo = "M803.904 463.936a55.168 55.168 0 0 1 0 96.128l-463.616 264.448C302.848 845.888 256 819.136 256 776.448V247.616c0-42.752 46.848-69.44 84.288-48.064l463.616 264.384z";
  112. ModMain._ProcessIterator.BtnExtraMusic.ManageField(0.8);
  113. text = "已暂停:" + ModBase.GetFileNameWithoutExtentionFromPath(ModMusic.m_RequestField);
  114. if (ModMusic.m_SpecificationField.Count > 1)
  115. {
  116. text += "\r\n左键恢复播放,右键播放下一曲。";
  117. }
  118. else
  119. {
  120. text += "\r\n左键恢复播放,右键重新从头播放。";
  121. }
  122. }
  123. else
  124. {
  125. ModMain._ProcessIterator.BtnExtraMusic.Logo = "M348.293565 716.53287V254.797913c0-41.672348 28.004174-78.358261 68.919652-90.37913L815.994435 40.826435c62.775652-18.610087 125.907478 26.579478 125.907478 89.933913v539.158261c8.013913 42.25113-8.94887 89.177043-47.014956 127.109565a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c21.014261 1.024 40.514783 5.164522 57.878261 12.065391V233.338435c0-12.109913-10.551652-20.034783-20.569044-20.034783a24.620522 24.620522 0 0 0-5.787826 0.934957L439.785739 338.18713a19.545043 19.545043 0 0 0-14.825739 19.144348v438.984348H423.846957c11.53113 43.987478-5.164522 94.208-45.412174 134.322087a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c20.791652 1.024 40.069565 5.075478 57.299478 11.842783z";
  126. ModMain._ProcessIterator.BtnExtraMusic.ManageField(1.0);
  127. text = "正在播放:" + ModBase.GetFileNameWithoutExtentionFromPath(ModMusic.m_RequestField);
  128. if (ModMusic.m_SpecificationField.Count > 1)
  129. {
  130. text += "\r\n左键暂停,右键播放下一曲。";
  131. }
  132. else
  133. {
  134. text += "\r\n左键暂停,右键重新从头播放。";
  135. }
  136. }
  137. ModMain._ProcessIterator.BtnExtraMusic.ToolTip = text;
  138. ToolTipService.SetVerticalOffset(ModMain._ProcessIterator.BtnExtraMusic, (double)(text.Contains("\n") ? 10 : 16));
  139. }
  140. if (ModMain.m_OrderIterator != null)
  141. {
  142. ModMain.m_OrderIterator.MusicRefreshUI();
  143. }
  144. }
  145. catch (Exception ex)
  146. {
  147. ModBase.Log(ex, "刷新背景音乐 UI 失败", ModBase.LogLevel.Feedback, "出现错误");
  148. }
  149. }) : ModMusic._Closure$__.$I5-0, false);
  150. }
  151. // Token: 0x06000576 RID: 1398 RVA: 0x0002F004 File Offset: 0x0002D204
  152. public static void MusicControlPause()
  153. {
  154. if (ModMusic.mockField == null)
  155. {
  156. ModMain.Hint("音乐播放尚未开始!", ModMain.HintType.Critical, true);
  157. return;
  158. }
  159. ModMusic.MusicStates musicStates = ModMusic.ReflectReader();
  160. if (musicStates == ModMusic.MusicStates.Play)
  161. {
  162. ModMusic.MusicPause();
  163. return;
  164. }
  165. if (musicStates == ModMusic.MusicStates.Pause)
  166. {
  167. ModMusic.MusicResume();
  168. return;
  169. }
  170. ModBase.Log("[Music] 音乐目前为停止状态,已强制尝试开始播放", ModBase.LogLevel.Debug, "出现错误");
  171. ModMusic.MusicRefreshPlay(false, false);
  172. }
  173. // Token: 0x06000577 RID: 1399 RVA: 0x0002F058 File Offset: 0x0002D258
  174. public static void MusicControlNext()
  175. {
  176. if (ModMusic.m_SpecificationField.Count == 1)
  177. {
  178. ModMusic.MusicStartPlay(ModMusic.m_RequestField, false);
  179. ModMain.Hint("重新播放:" + ModBase.GetFileNameFromPath(ModMusic.m_RequestField), ModMain.HintType.Finish, true);
  180. }
  181. else
  182. {
  183. string text = ModMusic.DequeueNextMusicAddress();
  184. if (text == null)
  185. {
  186. ModMain.Hint("没有可以播放的音乐!", ModMain.HintType.Critical, true);
  187. }
  188. else
  189. {
  190. ModMusic.MusicStartPlay(text, false);
  191. ModMain.Hint("正在播放:" + ModBase.GetFileNameFromPath(text), ModMain.HintType.Finish, true);
  192. }
  193. }
  194. ModMusic.MusicRefreshUI();
  195. }
  196. // Token: 0x06000578 RID: 1400 RVA: 0x0002F0D4 File Offset: 0x0002D2D4
  197. public static ModMusic.MusicStates ReflectReader()
  198. {
  199. ModMusic.MusicStates result;
  200. if (ModMusic.mockField == null)
  201. {
  202. result = ModMusic.MusicStates.Stop;
  203. }
  204. else
  205. {
  206. object left = NewLateBinding.LateGet(ModMusic.mockField, null, "PlaybackState", new object[0], null, null, null);
  207. if (Operators.ConditionalCompareObjectEqual(left, 0, false))
  208. {
  209. result = ModMusic.MusicStates.Stop;
  210. }
  211. else if (Operators.ConditionalCompareObjectEqual(left, 2, false))
  212. {
  213. result = ModMusic.MusicStates.Pause;
  214. }
  215. else
  216. {
  217. result = ModMusic.MusicStates.Play;
  218. }
  219. }
  220. return result;
  221. }
  222. // Token: 0x06000579 RID: 1401 RVA: 0x0002F130 File Offset: 0x0002D330
  223. public static void MusicRefreshPlay(bool ShowHint, bool IsFirstLoad = false)
  224. {
  225. try
  226. {
  227. ModMusic.MusicListInit(true, null);
  228. if (!Enumerable.Any<string>(ModMusic.m_SpecificationField))
  229. {
  230. if (ModMusic.mockField == null)
  231. {
  232. if (ShowHint)
  233. {
  234. ModMain.Hint("未检测到可用的背景音乐!", ModMain.HintType.Critical, true);
  235. }
  236. }
  237. else
  238. {
  239. ModMusic.mockField = null;
  240. if (ShowHint)
  241. {
  242. ModMain.Hint("背景音乐已清除!", ModMain.HintType.Finish, true);
  243. }
  244. }
  245. }
  246. else
  247. {
  248. string text = ModMusic.DequeueNextMusicAddress();
  249. if (text == null)
  250. {
  251. if (ShowHint)
  252. {
  253. ModMain.Hint("没有可以播放的音乐!", ModMain.HintType.Critical, true);
  254. }
  255. }
  256. else
  257. {
  258. try
  259. {
  260. ModMusic.MusicStartPlay(text, IsFirstLoad);
  261. if (ShowHint)
  262. {
  263. ModMain.Hint("背景音乐已刷新:" + ModBase.GetFileNameFromPath(text), ModMain.HintType.Finish, false);
  264. }
  265. }
  266. catch (Exception ex)
  267. {
  268. }
  269. }
  270. }
  271. ModMusic.MusicRefreshUI();
  272. }
  273. catch (Exception ex2)
  274. {
  275. ModBase.Log(ex2, "刷新背景音乐播放失败", ModBase.LogLevel.Feedback, "出现错误");
  276. }
  277. }
  278. // Token: 0x0600057A RID: 1402 RVA: 0x0002F20C File Offset: 0x0002D40C
  279. private static void MusicStartPlay(string Address, bool IsFirstLoad = false)
  280. {
  281. if (Address != null)
  282. {
  283. ModBase.Log("[Music] 播放开始:" + Address, ModBase.LogLevel.Normal, "出现错误");
  284. ModMusic.m_RequestField = Address;
  285. ModBase.RunInNewThread(delegate
  286. {
  287. ModMusic.MusicLoop(IsFirstLoad);
  288. }, "Music", ThreadPriority.BelowNormal);
  289. }
  290. }
  291. // Token: 0x0600057B RID: 1403 RVA: 0x0002F260 File Offset: 0x0002D460
  292. public static bool MusicPause()
  293. {
  294. bool result;
  295. if (ModMusic.ReflectReader() == ModMusic.MusicStates.Play)
  296. {
  297. ModBase.RunInThread((ModMusic._Closure$__.$I13-0 == null) ? (ModMusic._Closure$__.$I13-0 = delegate()
  298. {
  299. ModBase.Log("[Music] 已暂停播放", ModBase.LogLevel.Normal, "出现错误");
  300. WaveOut waveOut = ModMusic.mockField;
  301. if (waveOut != null)
  302. {
  303. NewLateBinding.LateCall(waveOut, null, "Pause", new object[0], null, null, null, true);
  304. }
  305. ModMusic.MusicRefreshUI();
  306. }) : ModMusic._Closure$__.$I13-0);
  307. result = true;
  308. }
  309. else
  310. {
  311. ModBase.Log(string.Format("[Music] 无需暂停播放,当前状态为 {0}", ModMusic.ReflectReader()), ModBase.LogLevel.Normal, "出现错误");
  312. result = false;
  313. }
  314. return result;
  315. }
  316. // Token: 0x0600057C RID: 1404 RVA: 0x0002F2C4 File Offset: 0x0002D4C4
  317. public static bool MusicResume()
  318. {
  319. bool result;
  320. if (ModMusic.ReflectReader() != ModMusic.MusicStates.Play && Enumerable.Any<string>(ModMusic.m_SpecificationField))
  321. {
  322. ModBase.RunInThread((ModMusic._Closure$__.$I14-0 == null) ? (ModMusic._Closure$__.$I14-0 = delegate()
  323. {
  324. ModBase.Log("[Music] 已恢复播放", ModBase.LogLevel.Normal, "出现错误");
  325. WaveOut waveOut = ModMusic.mockField;
  326. if (waveOut != null)
  327. {
  328. NewLateBinding.LateCall(waveOut, null, "Play", new object[0], null, null, null, true);
  329. }
  330. ModMusic.MusicRefreshUI();
  331. }) : ModMusic._Closure$__.$I14-0);
  332. result = true;
  333. }
  334. else
  335. {
  336. ModBase.Log(string.Format("[Music] 无需继续播放,当前状态为 {0}", ModMusic.ReflectReader()), ModBase.LogLevel.Normal, "出现错误");
  337. result = false;
  338. }
  339. return result;
  340. }
  341. // Token: 0x0600057D RID: 1405 RVA: 0x0002F334 File Offset: 0x0002D534
  342. private static void MusicLoop(bool IsFirstLoad = false)
  343. {
  344. WaveOut waveOut = null;
  345. WaveStream waveStream = null;
  346. try
  347. {
  348. waveOut = new WaveOut();
  349. ModMusic.mockField = waveOut;
  350. waveStream = new AudioFileReader(ModMusic.m_RequestField);
  351. waveOut.Init(waveStream);
  352. waveOut.Play();
  353. if (Conversions.ToBoolean(IsFirstLoad && Conversions.ToBoolean(Operators.NotObject(ModBase.m_IdentifierRepository.Get("UiMusicAuto", null)))))
  354. {
  355. waveOut.Pause();
  356. }
  357. ModMusic.MusicRefreshUI();
  358. int num = 0;
  359. while (waveOut.Equals(RuntimeHelpers.GetObjectValue(ModMusic.mockField)) && waveOut.PlaybackState != null)
  360. {
  361. ModMusic._Closure$__17-0 CS$<>8__locals1 = new ModMusic._Closure$__17-0(CS$<>8__locals1);
  362. if (Operators.ConditionalCompareObjectNotEqual(ModBase.m_IdentifierRepository.Get("UiMusicVolume", null), num, false))
  363. {
  364. num = Conversions.ToInteger(ModBase.m_IdentifierRepository.Get("UiMusicVolume", null));
  365. waveOut.Volume = (float)((double)num / 1000.0);
  366. }
  367. CS$<>8__locals1.$VB$Local_Percent = waveStream.CurrentTime.TotalMilliseconds / waveStream.TotalTime.TotalMilliseconds;
  368. ModBase.RunInUi(delegate()
  369. {
  370. ModMain._ProcessIterator.BtnExtraMusic.Progress = CS$<>8__locals1.$VB$Local_Percent;
  371. }, false);
  372. Thread.Sleep(100);
  373. }
  374. if (waveOut.PlaybackState == null && Enumerable.Any<string>(ModMusic.m_SpecificationField))
  375. {
  376. ModMusic.MusicStartPlay(ModMusic.DequeueNextMusicAddress(), false);
  377. }
  378. }
  379. catch (Exception ex)
  380. {
  381. ModBase.Log(ex, "播放音乐出现内部错误(" + ModMusic.m_RequestField + ")", ModBase.LogLevel.Developer, "出现错误");
  382. if (ex is MmException && (ex.Message.Contains("NoDriver") || ex.Message.Contains("BadDeviceId")))
  383. {
  384. ModMain.Hint("由于音频设备变更,音乐播放功能在重启 PCL 后才能恢复!", ModMain.HintType.Critical, true);
  385. Thread.Sleep(1000000000);
  386. }
  387. if (!ex.Message.Contains("Got a frame at sample rate") && !ex.Message.Contains("does not support changes to"))
  388. {
  389. if ((!ModMusic.m_RequestField.EndsWithF(".wav", true) && !ModMusic.m_RequestField.EndsWithF(".mp3", true) && !ModMusic.m_RequestField.EndsWithF(".flac", true)) || ex.Message.Contains("0xC00D36C4"))
  390. {
  391. ModMain.Hint("播放音乐失败(" + ModBase.GetFileNameFromPath(ModMusic.m_RequestField) + "):PCL 可能不支持此音乐格式,请将格式转换为 .wav、.mp3 或 .flac 后再试", ModMain.HintType.Critical, true);
  392. }
  393. else
  394. {
  395. ModBase.Log(ex, "播放音乐失败(" + ModBase.GetFileNameFromPath(ModMusic.m_RequestField) + ")", ModBase.LogLevel.Hint, "出现错误");
  396. }
  397. }
  398. else
  399. {
  400. ModMain.Hint("播放音乐失败(" + ModBase.GetFileNameFromPath(ModMusic.m_RequestField) + "):PCL 不支持播放音频属性在中途发生变化的音乐", ModMain.HintType.Critical, true);
  401. }
  402. ModMusic.m_SpecificationField.Remove(ModMusic.m_RequestField);
  403. ModMusic._ContextField.Remove(ModMusic.m_RequestField);
  404. ModMusic.MusicRefreshUI();
  405. Thread.Sleep(2000);
  406. if (ex is FileNotFoundException)
  407. {
  408. ModMusic.MusicRefreshPlay(true, IsFirstLoad);
  409. }
  410. else
  411. {
  412. ModMusic.MusicStartPlay(ModMusic.DequeueNextMusicAddress(), IsFirstLoad);
  413. }
  414. }
  415. finally
  416. {
  417. if (waveOut != null)
  418. {
  419. waveOut.Dispose();
  420. }
  421. if (waveStream != null)
  422. {
  423. waveStream.Dispose();
  424. }
  425. ModMusic.MusicRefreshUI();
  426. }
  427. }
  428. // Token: 0x040002FC RID: 764
  429. public static List<string> _ContextField = null;
  430. // Token: 0x040002FD RID: 765
  431. public static List<string> m_SpecificationField = null;
  432. // Token: 0x040002FE RID: 766
  433. public static WaveOut mockField = null;
  434. // Token: 0x040002FF RID: 767
  435. private static string m_RequestField = "";
  436. // Token: 0x020000B5 RID: 181
  437. public enum MusicStates
  438. {
  439. // Token: 0x04000301 RID: 769
  440. Stop,
  441. // Token: 0x04000302 RID: 770
  442. Play,
  443. // Token: 0x04000303 RID: 771
  444. Pause
  445. }
  446. }
  447. }