using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Security; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Characters; using Characters.AI; using Characters.AI.Behaviours; using Characters.AI.TwinSister; using Characters.Abilities; using Characters.Abilities.Darks; using Characters.Abilities.Debuffs; using Characters.Actions; using Characters.Gear; using Characters.Gear.Fragments; using Characters.Gear.Items; using Characters.Gear.Quintessences; using Characters.Gear.Synergy; using Characters.Gear.Synergy.Inscriptions; using Characters.Gear.Upgrades; using Characters.Gear.Weapons; using Characters.Player; using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks.CompilerServices; using Data; using GameResources; using Hardmode; using HarmonyLib; using Level; using Level.Altars; using Level.Npc.FieldNpcs; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Services; using Singletons; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; using UnityEngine.UI; using WebSocketSharp; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Plugins.Common")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [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; } } } public class BypassCertificate : CertificateHandler { public override bool ValidateCertificate(byte[] certificateData) { return true; } } public class ChzzkUnity : MonoBehaviour { private enum SslProtocolsHack { Tls = 192, Tls11 = 768, Tls12 = 3072 } [Serializable] public class LiveStatus { [Serializable] public class Content { public string liveTitle; public string status; public int concurrentUserCount; public int accumulateCount; public bool paidPromotion; public bool adult; public string chatChannelId; public string categoryType; public string liveCategory; public string liveCategoryValue; public string livePollingStatusJson; public string faultStatus; public string userAdultStatus; public bool chatActive; public string chatAvailableGroup; public string chatAvailableCondition; public int minFollowerMinute; } public int code; public string message; public Content content; } [Serializable] public class AccessTokenResult { [Serializable] public class Content { [Serializable] public class TemporaryRestrict { public bool temporaryRestrict; public int times; public int duration; public int createdTime; } public string accessToken; public bool realNameAuth; public string extraToken; } public int code; public string message; public Content content; } [Serializable] public class Profile { [Serializable] public class StreamingProperty { } public string userIdHash; public string nickname; public string profileImageUrl; public string userRoleCode; public string badge; public string title; public string verifiedMark; public List activityBadges; public StreamingProperty streamingProperty; } [Serializable] public class SubscriptionExtras { public int month; public string tierName; public string nickname; public int tierNo; } [Serializable] public class DonationExtras { [Serializable] public class WeeklyRank { public string userIdHash; public string nickName; public bool verifiedMark; public int donationAmount; public int ranking; } private object emojis; public bool isAnonymous; public string payType; public int payAmount; public string streamingChannelId; public string nickname; public string osType; public string donationType; public List weeklyRankList; public WeeklyRank donationUserWeeklyRank; } [Serializable] public class ChannelInfo { [Serializable] public class Content { public string channelId; public string channelName; public string channelImageUrl; public bool verifiedMark; public string channelType; public string channelDescription; public int followerCount; public bool openLive; } public int code; public string message; public Content content; } [CompilerGenerated] private sealed class d__31 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public ChzzkUnity <>4__this; private LiveStatus 5__1; private AccessTokenResult 5__2; private SslProtocols 5__3; private LiveStatus <>s__4; private AccessTokenResult <>s__5; private Exception 5__6; private Awaiter <>u__1; private Awaiter <>u__2; private Awaiter <>u__3; private void MoveNext() { //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_0505: 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_00e6: 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_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; try { Awaiter val3; if ((uint)num <= 1u || num != 2) { try { Awaiter val; Awaiter val2; if (num != 0) { if (num == 1) { val = <>u__2; <>u__2 = default(Awaiter); num = (<>1__state = -1); goto IL_0233; } if (<>4__this.socket != null && <>4__this.socket.IsAlive) { <>4__this.socket.Close(); <>4__this.socket = null; } Debug.Log((object)("[ChzzkUnity] Connecting to channel: " + <>4__this.channel)); val2 = <>4__this.GetLiveStatus(<>4__this.channel).GetAwaiter(); if (!val2.IsCompleted) { num = (<>1__state = 0); <>u__1 = val2; d__31 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted, d__31>(ref val2, ref d__); return; } } else { val2 = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); } <>s__4 = val2.GetResult(); 5__1 = <>s__4; <>s__4 = null; if (5__1 == null) { Debug.LogError((object)"[ChzzkUnity] 라이브 상태 데이터를 가져오지 못했습니다. 연결을 중단합니다."); } else if (5__1.content == null) { Debug.LogError((object)$"[ChzzkUnity] 라이브 상태 content가 null입니다. (코드: {5__1.code}, 메시지: {5__1.message}). 연결을 중단합니다."); } else { <>4__this.cid = 5__1.content.chatChannelId; if (!string.IsNullOrEmpty(<>4__this.cid)) { val = <>4__this.GetAccessToken(<>4__this.cid).GetAwaiter(); if (!val.IsCompleted) { num = (<>1__state = 1); <>u__2 = val; d__31 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted, d__31>(ref val, ref d__); return; } goto IL_0233; } Debug.LogError((object)"[ChzzkUnity] chatChannelId가 비어있습니다. 방송이 켜져있지 않거나 채널 ID가 틀렸습니다. 연결을 중단합니다."); } goto end_IL_0007; IL_0233: <>s__5 = val.GetResult(); 5__2 = <>s__5; <>s__5 = null; if (5__2 == null) { Debug.LogError((object)"[ChzzkUnity] 액세스 토큰 데이터를 가져오지 못했습니다. 연결을 중단합니다."); } else if (5__2.content == null) { Debug.LogError((object)$"[ChzzkUnity] 액세스 토큰 content가 null입니다. (코드: {5__2.code}, 메시지: {5__2.message}). 연결을 중단합니다."); } else { <>4__this.token = 5__2.content.accessToken; if (!string.IsNullOrEmpty(<>4__this.token)) { <>4__this.socket = new WebSocket("wss://kr-ss3.chat.naver.com/chat", Array.Empty()); if (<>4__this.socket.Log != null) { <>4__this.socket.Log.Output = delegate { }; } 5__3 = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; <>4__this.socket.SslConfiguration.EnabledSslProtocols = 5__3; <>4__this.socket.SslConfiguration.ServerCertificateValidationCallback = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true; <>4__this.socket.OnMessage += <>4__this.ParseMessage; <>4__this.socket.OnClose += <>4__this.CloseConnect; <>4__this.socket.OnOpen += <>4__this.StartChat; <>4__this.socket.OnError += delegate(object sender, ErrorEventArgs e) { Debug.LogError((object)("[ChzzkUnity] WebSocket 오류: " + e.Message)); }; <>4__this.socket.ConnectAsync(); Debug.Log((object)("[ChzzkUnity] WebSocket 연결 요청 완료 (채널 ID: " + <>4__this.cid + ")")); 5__1 = null; 5__2 = null; goto end_IL_001c; } Debug.LogError((object)"[ChzzkUnity] 액세스 토큰 값이 비어있습니다. 연결을 중단합니다."); } goto end_IL_0007; end_IL_001c:; } catch (Exception ex) { 5__6 = ex; Debug.LogError((object)$"[ChzzkUnity] Connect 중 치명적 예외 발생: {5__6}"); } val3 = ((UniTask)(ref UniTask.CompletedTask)).GetAwaiter(); if (!((Awaiter)(ref val3)).IsCompleted) { num = (<>1__state = 2); <>u__3 = val3; d__31 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompletedd__31>(ref val3, ref d__); return; } } else { val3 = <>u__3; <>u__3 = default(Awaiter); num = (<>1__state = -1); } ((Awaiter)(ref val3)).GetResult(); end_IL_0007:; } catch (Exception ex) { <>1__state = -2; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(ex); return; } <>1__state = -2; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__30 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string cid; public ChzzkUnity <>4__this; private string 5__1; private UnityWebRequest 5__2; private AccessTokenResult 5__3; private Exception 5__4; private Awaiter <>u__1; private void MoveNext() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Invalid comparison between Unknown and I4 //IL_008c: 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) int num = <>1__state; AccessTokenResult result; try { if (num != 0) { 5__1 = "https://comm-api.game.naver.com/nng_main/v1/chats/access-token?channelId=" + cid + "&chatType=STREAMING"; 5__2 = UnityWebRequest.Get(5__1); } try { if (num != 0) { 5__2.certificateHandler = (CertificateHandler)(object)new BypassCertificate(); 5__2.SendWebRequest(); 5__3 = null; goto IL_00cf; } Awaiter val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_00c6; IL_00c6: ((Awaiter)(ref val)).GetResult(); goto IL_00cf; IL_00cf: if (!5__2.isDone) { YieldAwaitable val2 = UniTask.Yield(); val = ((YieldAwaitable)(ref val2)).GetAwaiter(); if (!((Awaiter)(ref val)).IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__30 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__30>(ref val, ref d__); return; } goto IL_00c6; } if ((int)5__2.result == 1) { try { 5__3 = JsonConvert.DeserializeObject(5__2.downloadHandler.text); } catch (Exception ex) { 5__4 = ex; Debug.LogError((object)("[ChzzkUnity] GetAccessToken JSON 파싱 실패: " + 5__4.Message)); } } else { Debug.LogError((object)("[ChzzkUnity] GetAccessToken HTTP 요청 실패: " + 5__2.error + " (URL: " + 5__1 + ")")); } result = 5__3; } finally { if (num < 0 && 5__2 != null) { ((IDisposable)5__2).Dispose(); } } } catch (Exception ex) { <>1__state = -2; 5__1 = null; <>t__builder.SetException(ex); return; } <>1__state = -2; 5__1 = null; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__28 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string channelId; public ChzzkUnity <>4__this; private string 5__1; private UnityWebRequest 5__2; private ChannelInfo 5__3; private Awaiter <>u__1; private void MoveNext() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Invalid comparison between Unknown and I4 //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; ChannelInfo result; try { if (num != 0) { 5__1 = "https://api.chzzk.naver.com/service/v1/channels/" + channelId; 5__2 = UnityWebRequest.Get(5__1); } try { if (num != 0) { 5__2.certificateHandler = (CertificateHandler)(object)new BypassCertificate(); 5__2.SendWebRequest(); 5__3 = null; goto IL_00ca; } Awaiter val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_00c1; IL_00c1: ((Awaiter)(ref val)).GetResult(); goto IL_00ca; IL_00ca: if (!5__2.isDone) { YieldAwaitable val2 = UniTask.Yield(); val = ((YieldAwaitable)(ref val2)).GetAwaiter(); if (!((Awaiter)(ref val)).IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__28 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__28>(ref val, ref d__); return; } goto IL_00c1; } if ((int)5__2.result == 1) { 5__3 = JsonConvert.DeserializeObject(5__2.downloadHandler.text); } result = 5__3; } finally { if (num < 0 && 5__2 != null) { ((IDisposable)5__2).Dispose(); } } } catch (Exception exception) { <>1__state = -2; 5__1 = null; <>t__builder.SetException(exception); return; } <>1__state = -2; 5__1 = null; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__29 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string channelId; public ChzzkUnity <>4__this; private string 5__1; private UnityWebRequest 5__2; private LiveStatus 5__3; private Exception 5__4; private Awaiter <>u__1; private void MoveNext() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Invalid comparison between Unknown and I4 //IL_008c: 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) int num = <>1__state; LiveStatus result; try { if (num != 0) { 5__1 = "https://api.chzzk.naver.com/polling/v2/channels/" + channelId + "/live-status"; 5__2 = UnityWebRequest.Get(5__1); } try { if (num != 0) { 5__2.certificateHandler = (CertificateHandler)(object)new BypassCertificate(); 5__2.SendWebRequest(); 5__3 = null; goto IL_00cf; } Awaiter val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_00c6; IL_00c6: ((Awaiter)(ref val)).GetResult(); goto IL_00cf; IL_00cf: if (!5__2.isDone) { YieldAwaitable val2 = UniTask.Yield(); val = ((YieldAwaitable)(ref val2)).GetAwaiter(); if (!((Awaiter)(ref val)).IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__29 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__29>(ref val, ref d__); return; } goto IL_00c6; } if ((int)5__2.result == 1) { try { 5__3 = JsonConvert.DeserializeObject(5__2.downloadHandler.text); } catch (Exception ex) { 5__4 = ex; Debug.LogError((object)("[ChzzkUnity] GetLiveStatus JSON 파싱 실패: " + 5__4.Message)); } } else { Debug.LogError((object)("[ChzzkUnity] GetLiveStatus HTTP 요청 실패: " + 5__2.error + " (URL: " + 5__1 + ")")); } result = 5__3; } finally { if (num < 0 && 5__2 != null) { ((IDisposable)5__2).Dispose(); } } } catch (Exception ex) { <>1__state = -2; 5__1 = null; <>t__builder.SetException(ex); return; } <>1__state = -2; 5__1 = null; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } private const string WS_URL = "wss://kr-ss3.chat.naver.com/chat"; private const string HEARTBEAT_REQUEST = "{\"ver\":\"2\",\"cmd\":0}"; private const string HEARTBEAT_RESPONSE = "{\"ver\":\"2\",\"cmd\":10000}"; private string cid; private string token; public string channel; private WebSocket socket = null; private float timer = 0f; private bool running = false; public UnityEvent onMessage = new UnityEvent(); public UnityEvent onDonation = new UnityEvent(); public UnityEvent onSubscription = new UnityEvent(); public UnityEvent onClose = new UnityEvent(); public UnityEvent onOpen = new UnityEvent(); private int closedCount = 0; private bool reOpenTrying = false; private void Start() { onMessage.AddListener((UnityAction)DebugMessage); onDonation.AddListener((UnityAction)DebugDonation); onSubscription.AddListener((UnityAction)DebugSubscription); } private void Update() { if (closedCount > 0) { UnityEvent obj = onClose; if (obj != null) { obj.Invoke(); } if (!reOpenTrying) { ((MonoBehaviour)this).StartCoroutine(TryReOpen()); } closedCount--; } } public IEnumerator TryReOpen() { reOpenTrying = true; yield return (object)new WaitForSeconds(3f); UniTaskExtensions.Forget(Connect()); reOpenTrying = false; } private void FixedUpdate() { if (running) { timer += Time.unscaledDeltaTime; if (timer > 15f) { socket.Send("{\"ver\":\"2\",\"cmd\":0}"); timer = 0f; } } } private void OnDestroy() { StopListening(); } private void DebugMessage(Profile profile, string str) { } private void DebugDonation(Profile profile, string str, DonationExtras donation) { } private void DebugSubscription(Profile profile, SubscriptionExtras subscription) { } public void RemoveAllOnMessageListener() { ((UnityEventBase)onMessage).RemoveAllListeners(); } public void RemoveAllOnDonationListener() { ((UnityEventBase)onDonation).RemoveAllListeners(); } public void RemoveAllOnSubscriptionListener() { ((UnityEventBase)onSubscription).RemoveAllListeners(); } [AsyncStateMachine(typeof(d__28))] [DebuggerStepThrough] public UniTask GetChannelInfo(string channelId) { //IL_0007: 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_0039: Unknown result type (might be due to invalid IL or missing references) d__28 d__ = new d__28(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.<>4__this = this; d__.channelId = channelId; d__.<>1__state = -1; d__.<>t__builder.Start<d__28>(ref d__); return d__.<>t__builder.Task; } [AsyncStateMachine(typeof(d__29))] [DebuggerStepThrough] public UniTask GetLiveStatus(string channelId) { //IL_0007: 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_0039: Unknown result type (might be due to invalid IL or missing references) d__29 d__ = new d__29(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.<>4__this = this; d__.channelId = channelId; d__.<>1__state = -1; d__.<>t__builder.Start<d__29>(ref d__); return d__.<>t__builder.Task; } [AsyncStateMachine(typeof(d__30))] [DebuggerStepThrough] public UniTask GetAccessToken(string cid) { //IL_0007: 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_0039: Unknown result type (might be due to invalid IL or missing references) d__30 d__ = new d__30(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.<>4__this = this; d__.cid = cid; d__.<>1__state = -1; d__.<>t__builder.Start<d__30>(ref d__); return d__.<>t__builder.Task; } [AsyncStateMachine(typeof(d__31))] [DebuggerStepThrough] public UniTask Connect() { //IL_0007: 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_0032: Unknown result type (might be due to invalid IL or missing references) d__31 d__ = new d__31(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.<>4__this = this; d__.<>1__state = -1; ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Start<d__31>(ref d__); return ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Task; } public void Connect(string channelId) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) channel = channelId; UniTaskExtensions.Forget(Connect()); } public void StopListening() { if (socket != null) { socket.Close(); socket = null; } } private void ParseMessage(object sender, MessageEventArgs e) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Expected O, but got Unknown //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown try { IDictionary dictionary = JsonConvert.DeserializeObject>(e.Data); switch ((long)dictionary["cmd"]) { case 0L: socket.Send("{\"ver\":\"2\",\"cmd\":10000}"); timer = 0f; break; case 93101L: { JArray val = (JArray)dictionary["bdy"]; { foreach (JToken item in val) { try { JObject val2 = (JObject)item; string text = ((object)val2["profile"])?.ToString(); Profile profile = new Profile(); profile.nickname = "익명"; if (!string.IsNullOrEmpty(text) && text != "null") { try { JObject val6 = JObject.Parse(text); if (val6["nickname"] != null) { profile.nickname = ((object)val6["nickname"]).ToString(); } if (val6["userIdHash"] != null) { profile.userIdHash = ((object)val6["userIdHash"]).ToString(); } } catch (Exception ex5) { Debug.LogWarning((object)("[ChzzkUnity] 프로필 JObject 파싱 오류: " + ex5.Message + ". 원본: " + text)); } } string text3 = ((object)val2["msg"])?.ToString()?.Trim() ?? ""; onMessage?.Invoke(profile, text3); } catch (Exception ex6) { Debug.LogError((object)("[ChzzkUnity] 개별 채팅 메시지 처리 중 오류: " + ex6.Message)); } } break; } } case 93102L: { JArray val = (JArray)dictionary["bdy"]; { JToken val4 = default(JToken); JToken val5 = default(JToken); foreach (JToken item2 in val) { try { JObject val2 = (JObject)item2; string text = ((object)val2["profile"])?.ToString(); Profile profile = new Profile(); profile.nickname = "익명"; if (!string.IsNullOrEmpty(text) && text != "null") { try { JObject val3 = JObject.Parse(text); if (val3["nickname"] != null) { profile.nickname = ((object)val3["nickname"]).ToString(); } if (val3["userIdHash"] != null) { profile.userIdHash = ((object)val3["userIdHash"]).ToString(); } } catch (Exception ex) { Debug.LogWarning((object)("[ChzzkUnity] 후원자 프로필 JObject 파싱 오류: " + ex.Message + ". 원본: " + text)); } } int num = int.Parse(((object)val2["msgTypeCode"]).ToString()); string text2 = null; if (val2.TryGetValue("extra", ref val4)) { text2 = ((object)val4).ToString(); } else if (val2.TryGetValue("extras", ref val5)) { text2 = ((object)val5).ToString(); } switch (num) { case 10: { DonationExtras donationExtras = null; if (!string.IsNullOrEmpty(text2)) { try { donationExtras = JsonConvert.DeserializeObject(text2); } catch (Exception ex3) { Debug.LogError((object)("[ChzzkUnity] DonationExtras 파싱 오류: " + ex3.Message + ". 원본: " + text2)); } } onDonation?.Invoke(profile, ((object)val2["msg"])?.ToString() ?? "", donationExtras); break; } case 11: { SubscriptionExtras subscriptionExtras = null; if (!string.IsNullOrEmpty(text2)) { try { subscriptionExtras = JsonConvert.DeserializeObject(text2); } catch (Exception ex2) { Debug.LogError((object)("[ChzzkUnity] SubscriptionExtras 파싱 오류: " + ex2.Message + ". 원본: " + text2)); } } onSubscription?.Invoke(profile, subscriptionExtras); break; } default: Debug.LogError((object)$"MessageTypeCode-{num} is not supported"); Debug.LogError((object)((object)val2).ToString()); break; } } catch (Exception ex4) { Debug.LogError((object)("[ChzzkUnity] 후원/구독 메시지 처리 중 오류: " + ex4.Message)); } } break; } } case 10100L: { UnityEvent obj = onOpen; if (obj != null) { obj.Invoke(); } break; } } } catch (Exception ex7) { Debug.LogError((object)ex7.ToString()); } } private void CloseConnect(object sender, CloseEventArgs e) { Debug.LogError((object)"[ChzzkUnity] 치지직 채팅 서버와 연결이 해제되었습니다."); closedCount++; } private void StartChat(object sender, EventArgs e) { Debug.Log((object)"[ChzzkUnity] 치지직 채팅 서버에 성공적으로 연결되었습니다!"); string text = "{\"ver\":\"2\",\"cmd\":100,\"svcid\":\"game\",\"cid\":\"" + cid + "\",\"bdy\":{\"uid\":null,\"devType\":2001,\"accTkn\":\"" + token + "\",\"auth\":\"READ\"},\"tid\":1}"; timer = 0f; running = true; socket.Send(text); } } public class ChzzkVideoDonationUnity : MonoBehaviour { private enum SslProtocolsHack { Tls = 192, Tls11 = 768, Tls12 = 3072 } [Serializable] public class SessionUrl { [Serializable] public class Content { public string sessionUrl; } public string code; public object message; public Content content; } public class DonationControl { private int startSecond; private int endSecond; private bool stopVideo; private bool titleExpose; private string donationId; private int payAmount; private bool isAnonymous; private bool useSpeech; } [Serializable] public class VideoDonationList { public List videoDonation; } [Serializable] public class VideoDonation { public int startSecond; public int endSecond; public string videoType; public string videoId; public string playMode; public bool stopVideo; public bool titleExpose; public string donationId; public string profile; public int payAmount; public string donationText; public bool isAnonymous; public int tierNo; public bool useSpeech; public override string ToString() { return JsonConvert.SerializeObject((object)this); } } [Serializable] public class Profile { [Serializable] public class ActivityBadge { public int badgeNo; public string badgeId; public string imageUrl; public bool activated; } [Serializable] public class StreamingProperty { [Serializable] public class Subscription { public class Badge { public string imageUrl; } public int accumulativeMonth; public int tier; public Badge badge; } [Serializable] public class NicknameColor { public string colorCode; } public Subscription subscription; public NicknameColor nicknameColor; } public string userIdHash; public string nickname; public string profileImageUrl; public string userRoleCode; public string badge; public string title; public bool verifiedMark; public List activityBadges; public StreamingProperty streamingProperty; } [CompilerGenerated] private sealed class d__21 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public ChzzkVideoDonationUnity <>4__this; private SslProtocols 5__1; private Awaiter <>u__1; private void MoveNext() { //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0118: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; try { Awaiter val; if (num != 0) { if (<>4__this.socket != null && <>4__this.socket.IsAlive) { <>4__this.socket.Close(); <>4__this.socket = null; } <>4__this.socket = new WebSocket(<>4__this.wssUrl, Array.Empty()); 5__1 = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; <>4__this.socket.SslConfiguration.EnabledSslProtocols = 5__1; <>4__this.socket.OnMessage += <>4__this.ParseMessage; <>4__this.socket.OnClose += <>4__this.CloseConnect; <>4__this.socket.OnOpen += <>4__this.onSocketOpen; <>4__this.socket.Connect(); val = ((UniTask)(ref UniTask.CompletedTask)).GetAwaiter(); if (!((Awaiter)(ref val)).IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__21 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompletedd__21>(ref val, ref d__); return; } } else { val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); } ((Awaiter)(ref val)).GetResult(); } catch (Exception exception) { <>1__state = -2; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception); return; } <>1__state = -2; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__16 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string missionWSSId; public ChzzkVideoDonationUnity <>4__this; private string 5__1; private UnityWebRequest 5__2; private SessionUrl 5__3; private void MoveNext() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 int num = <>1__state; string sessionUrl; try { 5__1 = "https://api.chzzk.naver.com/manage/v1/alerts/video@" + missionWSSId + "/session-url"; 5__2 = UnityWebRequest.Get(5__1); 5__2.SendWebRequest(); 5__3 = null; if ((int)5__2.result == 1) { 5__3 = JsonUtility.FromJson(5__2.downloadHandler.text); } sessionUrl = 5__3.content.sessionUrl; } catch (Exception exception) { <>1__state = -2; 5__1 = null; 5__2 = null; 5__3 = null; <>t__builder.SetException(exception); return; } <>1__state = -2; 5__1 = null; 5__2 = null; 5__3 = null; <>t__builder.SetResult(sessionUrl); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__19 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string missionUrl; public ChzzkVideoDonationUnity <>4__this; private string 5__1; private string 5__2; private string <>s__3; private Awaiter <>u__1; private void MoveNext() { //IL_0072: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; string result; try { Awaiter val; if (num != 0) { 5__1 = <>4__this.GetMissionWSSId(missionUrl); val = <>4__this.GetSessionURL(5__1).GetAwaiter(); if (!val.IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__19 d__ = this; <>t__builder.AwaitUnsafeOnCompleted, d__19>(ref val, ref d__); return; } } else { val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); } <>s__3 = val.GetResult(); 5__2 = <>s__3; <>s__3 = null; result = <>4__this.MakeWssURL(5__2); } catch (Exception exception) { <>1__state = -2; 5__1 = null; 5__2 = null; <>t__builder.SetException(exception); return; } <>1__state = -2; 5__1 = null; 5__2 = null; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } private WebSocket socket = null; private float timer = 0f; private bool running = false; private const string HEARTBEAT_REQUEST = "2"; private const string HEARTBEAT_RESPONSE = "3"; public UnityEvent onVideoDonationArrive = new UnityEvent(); public UnityEvent onVideoDonationControl = new UnityEvent(); public UnityEvent onClose = new UnityEvent(); public UnityEvent onOpen = new UnityEvent(); private int closedCount = 0; private bool reOpenTrying = false; private string wssUrl; private Dictionary> activeVideo; private void Start() { } private void Update() { if (closedCount > 0) { UnityEvent obj = onClose; if (obj != null) { obj.Invoke(); } if (!reOpenTrying) { ((MonoBehaviour)this).StartCoroutine(TryReOpen()); } closedCount--; } if (running) { timer += Time.unscaledDeltaTime; if (timer > 15f) { socket.Send("2"); timer = 0f; } } } private void OnDestroy() { StopListening(); } public string GetMissionWSSId(string url) { return url.Split(new char[1] { '@' })[1]; } [AsyncStateMachine(typeof(d__16))] [DebuggerStepThrough] public UniTask GetSessionURL(string missionWSSId) { //IL_0007: 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_0039: Unknown result type (might be due to invalid IL or missing references) d__16 d__ = new d__16(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.<>4__this = this; d__.missionWSSId = missionWSSId; d__.<>1__state = -1; d__.<>t__builder.Start<d__16>(ref d__); return d__.<>t__builder.Task; } public string MakeWssURL(string sessionUrl) { string text = sessionUrl.Split(new string[1] { "auth=" }, StringSplitOptions.None)[1]; string text2 = sessionUrl.Split(new string[1] { ".nchat" }, StringSplitOptions.None)[0].Substring(12); return "wss://ssio" + text2 + ".nchat.naver.com/socket.io/?auth=" + text + "&EIO=3&transport=websocket"; } [AsyncStateMachine(typeof(d__19))] [DebuggerStepThrough] public UniTask GetWssUrlFromMissionUrl(string missionUrl) { //IL_0007: 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_0039: Unknown result type (might be due to invalid IL or missing references) d__19 d__ = new d__19(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.<>4__this = this; d__.missionUrl = missionUrl; d__.<>1__state = -1; d__.<>t__builder.Start<d__19>(ref d__); return d__.<>t__builder.Task; } public async void Connect(string url) { wssUrl = await GetWssUrlFromMissionUrl(url); UniTaskExtensions.Forget(Connect()); } [AsyncStateMachine(typeof(d__21))] [DebuggerStepThrough] public UniTask Connect() { //IL_0007: 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_0032: Unknown result type (might be due to invalid IL or missing references) d__21 d__ = new d__21(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.<>4__this = this; d__.<>1__state = -1; ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Start<d__21>(ref d__); return ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Task; } private void onSocketOpen(object sender, EventArgs e) { timer = 0f; running = true; socket.Send("2"); } public void StopListening() { if (socket != null) { socket.Close(); socket = null; } } private void ParseMessage(object sender, MessageEventArgs e) { Debug.Log((object)e.Data); if (e.Data == "2") { timer = 0f; socket.Send("3"); } else { if (e.Data == "3" || e.Data == "40") { return; } VideoDonationList videoDonationList = JsonUtility.FromJson(e.Data); string text = videoDonationList.videoDonation[0]; string text2 = text; if (!(text2 == "donation")) { if (text2 == "donationControl") { List list = new List(); for (int i = 1; i < videoDonationList.videoDonation.Count; i++) { DonationControl donationControl = JsonUtility.FromJson(videoDonationList.videoDonation[i]); Debug.Log((object)donationControl); list.Add(donationControl); onVideoDonationControl.Invoke(donationControl); } } } else { for (int j = 1; j < videoDonationList.videoDonation.Count; j++) { VideoDonation videoDonation = JsonUtility.FromJson(videoDonationList.videoDonation[j]); Debug.Log((object)videoDonation); Profile profile = JsonUtility.FromJson(videoDonation.profile); onVideoDonationArrive.Invoke(profile, videoDonation); } } } } private void CloseConnect(object sender, CloseEventArgs e) { Debug.LogError((object)"연결이 해제되었습니다"); Debug.Log((object)e.Reason); Debug.Log((object)e.Code); Debug.Log((object)e); closedCount++; } private IEnumerator TryReOpen() { reOpenTrying = true; yield return (object)new WaitForSeconds(1f); if (!socket.IsAlive) { socket.Connect(); } reOpenTrying = false; } } namespace ChzzkSkul { public class ChzzkGameMode : MonoBehaviour { private struct CommandInfo { public string nickname; public string command; public bool isStreamer; } private struct DonationInfo { public string nickname; public int amount; public string message; } private struct ChatMessageInfo { public string msg; public float expireTime; } public enum VoteState { Inactive, Voting, Processing } public class VoteOption { public string Title; public int Votes; public Action Action; public int Weight; } private struct DonationAction { public int cost; public Action action; } public static List EnemiesAssetKeys = new List(); public static bool EnemiesKeysCached = false; private const float BUFF_DURATION = 30f; private const float HEAL_PERCENT = 0.1f; private readonly ConcurrentQueue _commandQueue = new ConcurrentQueue(); private readonly ConcurrentQueue _donationQueue = new ConcurrentQueue(); private readonly ConcurrentQueue _pendingChats = new ConcurrentQueue(); private readonly Queue _chatMessages = new Queue(); private readonly Queue _ttsQueue = new Queue(); private AudioSource _ttsAudioSource; private object _sapiVoice = null; private Type _sapiType = null; private float _cooldownTimer = 0f; private bool _onCooldown = false; private float _lastCooldownMessageTime = 0f; private Random _random = new Random(); private bool _showItemDestroyer = false; private Vector2 _itemDestroyerScroll = Vector2.zero; public static bool _forceNextDarkEnemy = false; private HashSet _appliedDarkEnemies = new HashSet(); public static Map _darkEnemyTargetMap = null; private Map _lastMap; public static ChzzkGameMode _instance; public static HashSet CustomSuperInscriptions = new HashSet(); private Map _currentMap; private string _lastSpawnedBossMap = null; private bool _streamerUsedCommandInThisMap = false; private VoteState _voteState = VoteState.Inactive; private float _voteTimer; private float _voteAutoTimer; private float _chaosTimer; private float _bossRushEmptyStageTimer = 0f; private HashSet _votedUsers = new HashSet(); private List _currentVoteOptions = new List(); private GameObject _voteUI; private string _lastSpawnedBossRushStage = null; private Character _lastPlayerForStats; private int _lastCardSynergyStep = 0; private Values _cardSynergyStats = null; private float _cardBuffCooldown = 0f; private float _cardSynergyUpdateTimer = 0f; private bool _isApplyingCardSynergyDamage = false; private Values _cardActiveBuffStats = null; public static bool IsScreenEffectActive = false; public static int _screenEffectType = 0; public static float _screenEffectTimer = 0f; private ReverseHorizontalInput _reverseAbility = null; private Volume _screenEffectVolume = null; private GameObject _splitScreenCanvas = null; private RenderTexture _splitScreenRT = null; public static bool _isNukeActive = false; public static int _nukeScenesPassed = 0; public static float _nukeElapsed = 0f; public static float _bossRushElapsed = 0f; public static Map _irradiatedMap = null; private float _irradiatedTimer = 0f; private AudioSource _voidAudioSource = null; private bool _isVoidAudioPlaying = false; private Coroutine _voidAudioCoroutine = null; public static bool _isBossRushActive = false; private Coroutine _bossRushCoroutine = null; private AudioSource _bossRushAudioSource = null; private bool _isSpawningBossRush = false; public static bool ForceNextDarkEnemy { get { return _forceNextDarkEnemy; } set { _forceNextDarkEnemy = value; ChzzkStatManager.Save(); } } private float GLOBAL_COOLDOWN => Plugin.CommandCooldown.Value; private HashSet HealCommands => GetCommands(Plugin.CmdHealString.Value); private HashSet BuffCommands => GetCommands(Plugin.CmdBuffCurseString.Value); private HashSet ItemCommands => GetCommands(Plugin.CmdItemString.Value); private HashSet SkullCommands => GetCommands(Plugin.CmdSkullString.Value); private HashSet SynergyCommands => GetCommands(Plugin.CmdSynergyString.Value); private HashSet OmenCommands => GetCommands(Plugin.CmdOmenString.Value); private HashSet BossCommands => GetCommands(Plugin.CmdBossString.Value); private HashSet DarkEnemyCommands => GetCommands(Plugin.CmdDarkEnemyString.Value); private HashSet DarkCommands => GetCommands(Plugin.CmdDarkAbilityString.Value); private HashSet RandomCommands => GetCommands(Plugin.CmdRandomString.Value); private HashSet NpcCommands => GetCommands(Plugin.CmdNpcString.Value); private HashSet FoodCommands => GetCommands(Plugin.CmdFoodString.Value); private HashSet BoneCommands => GetCommands(Plugin.CmdBoneString.Value); private HashSet GoldCommands => GetCommands(Plugin.CmdGoldString.Value); private HashSet DarkQuartzCommands => GetCommands(Plugin.CmdDarkQuartzString.Value); private HashSet QuintessenceCommands => GetCommands(Plugin.CmdQuintessenceString.Value); private HashSet FragmentCommands => GetCommands(Plugin.CmdFragmentString.Value); private HashSet DefenseCommands => GetCommands(Plugin.CmdDefenseString.Value); private HashSet TotemCommands => GetCommands(Plugin.CmdTotemString.Value); private HashSet RandomStatCommands => GetCommands(Plugin.CmdRandomStatString.Value); private HashSet ChestCommands => GetCommands(Plugin.CmdChestString.Value); public static bool IsBossRushActive { get { return _isBossRushActive; } set { _isBossRushActive = value; ChzzkStatManager.Save(); } } private IEnumerator ProcessTTSQueue() { try { _sapiType = Type.GetTypeFromProgID("SAPI.SpVoice"); if (_sapiType != null) { _sapiVoice = Activator.CreateInstance(_sapiType); } } catch (Exception ex) { Exception e = ex; Debug.LogWarning((object)("[ChzzkGameMode] Windows TTS 초기화 실패: " + e.Message)); } while (true) { if (_ttsQueue.Count > 0 && Plugin.EnableDonationTTS.Value) { string text = _ttsQueue.Dequeue(); if (!string.IsNullOrWhiteSpace(text)) { if (Plugin.TTSProvider != null && Plugin.TTSProvider.Value == "None") { continue; } if (Plugin.TTSProvider != null && Plugin.TTSProvider.Value == "Windows" && _sapiVoice != null && _sapiType != null) { bool isSpeaking = true; ThreadPool.QueueUserWorkItem(delegate { try { _sapiType.InvokeMember("Speak", BindingFlags.InvokeMethod, null, _sapiVoice, new object[2] { text, 0 }); } catch (Exception ex2) { Debug.LogWarning((object)("[ChzzkGameMode] Windows TTS 재생 오류: " + ex2.Message)); } isSpeaking = false; }); while (isSpeaking) { yield return null; } yield return (object)new WaitForSeconds(0.5f); } else { string url = "https://translate.google.com/translate_tts?ie=UTF-8&total=1&idx=0&client=tw-ob&q=" + UnityWebRequest.EscapeURL(text) + "&tl=ko"; UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, (AudioType)13); try { yield return www.SendWebRequest(); if ((int)www.result == 1) { AudioClip clip = DownloadHandlerAudioClip.GetContent(www); _ttsAudioSource.clip = clip; _ttsAudioSource.Play(); yield return (object)new WaitForSeconds(clip.length + 0.5f); } } finally { ((IDisposable)www)?.Dispose(); } } } } yield return null; } } private string GetFirstCommand(string config, string defaultValue) { if (string.IsNullOrWhiteSpace(config)) { return defaultValue; } string[] array = config.Split(new char[1] { ',' }); if (array.Length != 0) { string text = array[0].Trim(); if (!string.IsNullOrEmpty(text)) { return text; } } return defaultValue; } private HashSet GetCommands(string config) { HashSet hashSet = new HashSet(); if (config == null) { return hashSet; } string[] array = config.Split(new char[1] { ',' }); string[] array2 = array; foreach (string text in array2) { string text2 = text.Trim().ToLower(); if (!string.IsNullOrEmpty(text2)) { hashSet.Add(text2); } } return hashSet; } private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: 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_0028: Expected O, but got Unknown //IL_0028: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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 if ((Object)_instance != (Object)null && (Object)_instance != (Object)this) { Object.Destroy((Object)((Component)this).gameObject); return; } _instance = this; Object.DontDestroyOnLoad((Object)((Component)this).gameObject); ChzzkStatManager.Load(); _ttsAudioSource = ((Component)this).gameObject.AddComponent(); _ttsAudioSource.playOnAwake = false; ((MonoBehaviour)this).StartCoroutine(ProcessTTSQueue()); ((MonoBehaviour)this).StartCoroutine(RecoverStatesAfterLoad()); ((MonoBehaviour)this).StartCoroutine(C_CacheEnemyAssetKeys()); } private IEnumerator C_CacheEnemyAssetKeys() { if (EnemiesKeysCached) { yield break; } string[] targetMobs = new string[5] { "Hound", "CarleonRecruit", "Servant", "GoldmaneRecruit", "FanaticRecruit" }; HashSet targetSet = new HashSet(targetMobs, StringComparer.OrdinalIgnoreCase); foreach (IResourceLocator locator in Addressables.ResourceLocators) { if (locator == null || locator.Keys == null) { continue; } foreach (object keyObj in locator.Keys) { if (keyObj == null) { continue; } string k = keyObj.ToString(); if (k.EndsWith(".prefab") && k.Contains("Enemies") && !k.Contains("effect") && !k.Contains("ui")) { string fileName = Path.GetFileNameWithoutExtension(k); if (targetSet.Contains(fileName) && !EnemiesAssetKeys.Contains(k)) { EnemiesAssetKeys.Add(k); } } } yield return null; } EnemiesKeysCached = true; Debug.Log((object)$"[ChzzkGameMode] Successfully cached {EnemiesAssetKeys.Count} enemy asset keys."); } private IEnumerator RecoverStatesAfterLoad() { yield return (object)new WaitForSeconds(4f); if (_isNukeActive) { DoNuke("SYSTEM", isResume: true); } if (IsBossRushActive) { DoBossRush("SYSTEM", isResume: true); } yield return C_RestoreExtraInventoryItems(); } private IEnumerator C_RestoreExtraInventoryItems() { CustomGearsPatch.ExpandInventoryIfNeeded((Item)null); Character player = GetPlayer(); if ((Object)(object)player == (Object)null || player.playerComponents == null || player.playerComponents.inventory == null) { yield break; } ItemInventory itemInventory = player.playerComponents.inventory.item; if ((Object)(object)itemInventory == (Object)null || ChzzkStatManager.SaveData.ExtraInventoryItems == null || ChzzkStatManager.SaveData.ExtraInventoryItems.Count == 0) { yield break; } Service service = GetService(); if ((Object)(object)service == (Object)null || (Object)(object)service.gearManager == (Object)null || (Object)(object)service.levelManager == (Object)null) { yield break; } for (int i = 0; i < ChzzkStatManager.SaveData.ExtraInventoryItems.Count; i++) { string itemName = ChzzkStatManager.SaveData.ExtraInventoryItems[i]; int targetSlotIndex = 9 + i; if (string.IsNullOrEmpty(itemName)) { continue; } itemName = ChzzkStatManager.GetOriginalItemName(itemName); if (targetSlotIndex < itemInventory.items.Count && (Object)(object)itemInventory.items[targetSlotIndex] != (Object)null) { continue; } ItemReference itemRef = null; if (!GearResource.instance.TryGetItemReferenceByName(itemName, ref itemRef)) { continue; } ItemRequest req = itemRef.LoadAsync(); while (!((Request)(object)req).isDone) { yield return null; } if (!((Object)(object)((Request)(object)req).asset != (Object)null)) { continue; } Item drop = service.levelManager.DropItem(req, ((Component)player).transform.position); if (!((Object)(object)drop != (Object)null)) { continue; } try { MethodInfo equipAtMethod = typeof(ItemInventory).GetMethod("EquipAt", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(ItemInventory).GetMethod("EquipAt"); if (equipAtMethod != null) { equipAtMethod.Invoke(itemInventory, new object[2] { drop, targetSlotIndex }); } else if (targetSlotIndex < itemInventory.items.Count) { itemInventory.items[targetSlotIndex] = drop; ((Gear)drop).state = (State)1; ((Gear)drop).OnEquipped(); } } catch (Exception ex) { Debug.LogError((object)("[RestoreExtraInventoryItems] Failed to equip: " + ex)); } } } private void LateUpdate() { //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Expected O, but got Unknown //IL_0559: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Expected O, but got Unknown //IL_0231: 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_0111: Expected O, but got Unknown //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Invalid comparison between Unknown and I4 //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Invalid comparison between Unknown and I4 //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Invalid comparison between Unknown and I4 //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Invalid comparison between Unknown and I4 //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Invalid comparison between Unknown and I4 //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Invalid comparison between Unknown and I4 //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Invalid comparison between Unknown and I4 //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Invalid comparison between Unknown and I4 //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Invalid comparison between Unknown and I4 //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Invalid comparison between Unknown and I4 //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Invalid comparison between Unknown and I4 if (IsScreenEffectActive) { _screenEffectTimer -= Time.unscaledDeltaTime; if (_screenEffectTimer <= 0f) { IsScreenEffectActive = false; if ((Object)Camera.main != (Object)null) { ((Component)Camera.main).transform.localEulerAngles = Vector3.zero; } if (_reverseAbility != null) { Character player = GetPlayer(); if ((Object)player != (Object)null) { player.ability.Remove((IAbility)(object)_reverseAbility); } _reverseAbility = null; } if ((Object)_screenEffectVolume != (Object)null) { ((Component)_screenEffectVolume).gameObject.SetActive(false); } if ((Object)_splitScreenCanvas != (Object)null) { Object.Destroy((Object)(object)_splitScreenCanvas); _splitScreenCanvas = null; } if ((Object)_splitScreenRT != (Object)null) { if ((Object)Camera.main != (Object)null && (Object)(object)Camera.main.targetTexture == (Object)(object)_splitScreenRT) { Camera.main.targetTexture = null; } _splitScreenRT.Release(); Object.Destroy((Object)(object)_splitScreenRT); _splitScreenRT = null; } ChzzkStatManager.Save(); } else { if ((Object)Camera.main != (Object)null) { if (_screenEffectType == 0) { ((Component)Camera.main).transform.localEulerAngles = new Vector3(0f, 0f, 180f); } else if (_screenEffectType == 1) { ((Component)Camera.main).transform.localEulerAngles = new Vector3(0f, 0f, 15f); } else if (_screenEffectType == 2) { ((Component)Camera.main).transform.localEulerAngles = new Vector3(0f, 0f, -15f); } } if (_screenEffectType == 3 && _reverseAbility == null) { Character player2 = GetPlayer(); if ((Object)player2 != (Object)null) { _reverseAbility = new ReverseHorizontalInput(); player2.ability.Add((IAbility)(object)_reverseAbility); } } } } if (ForceNextDarkEnemy && (Object)(object)_darkEnemyTargetMap == (Object)(object)Map.Instance && (Object)Map.Instance != (Object)null) { if (!((Object)(object)Map.Instance.waveContainer != (Object)null)) { return; } { foreach (Character allSpawnedEnemy in Map.Instance.waveContainer.GetAllSpawnedEnemies()) { if (!((Object)(object)allSpawnedEnemy != (Object)null) || (int)allSpawnedEnemy.type != 0 || ((Health)allSpawnedEnemy.health).dead || !((Component)allSpawnedEnemy).gameObject.activeInHierarchy || _appliedDarkEnemies.Contains(allSpawnedEnemy) || (int)allSpawnedEnemy.key == 15005 || (int)allSpawnedEnemy.key == 30302 || (int)allSpawnedEnemy.key == 30303 || (int)allSpawnedEnemy.key == 30301 || (int)allSpawnedEnemy.key == 30304 || (int)allSpawnedEnemy.key == 10101 || (int)allSpawnedEnemy.key == 15002 || (int)allSpawnedEnemy.key == 15001 || (int)allSpawnedEnemy.key == 15010 || (int)allSpawnedEnemy.key == 10001 || (int)allSpawnedEnemy.key <= 0) { continue; } _appliedDarkEnemies.Add(allSpawnedEnemy); try { object obj = null; PropertyInfo property = typeof(DarkEnemySelector).GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (property != null) { obj = property.GetValue(null, null); } if (obj == null) { FieldInfo field = typeof(DarkEnemySelector).GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (field != null) { obj = field.GetValue(null); } } if (obj == null) { obj = Object.FindObjectOfType(); } if (obj == null) { continue; } FieldInfo field2 = typeof(DarkEnemySelector).GetField("_constructors", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 != null && field2.GetValue(obj) is DarkAbilityConstructor[] array) { int currentLevel = Singleton.Instance.currentLevel; if (currentLevel >= 0 && currentLevel < array.Length) { array[currentLevel].Provide(allSpawnedEnemy); } } } catch { } } return; } } if ((Object)_darkEnemyTargetMap != (Object)Map.Instance) { _appliedDarkEnemies.Clear(); } } private void Update() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_004a: Expected O, but got Unknown //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Expected O, but got Unknown //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_117f: Unknown result type (might be due to invalid IL or missing references) //IL_118a: Expected O, but got Unknown //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Expected O, but got Unknown //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Expected O, but got Unknown //IL_0380: Expected O, but got Unknown //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Expected O, but got Unknown //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Expected O, but got Unknown //IL_064e: Unknown result type (might be due to invalid IL or missing references) //IL_0659: Expected O, but got Unknown //IL_0661: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) //IL_0675: Expected O, but got Unknown //IL_0675: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_0773: Unknown result type (might be due to invalid IL or missing references) //IL_077d: Unknown result type (might be due to invalid IL or missing references) //IL_0787: Expected O, but got Unknown //IL_0787: Expected O, but got Unknown //IL_0736: Unknown result type (might be due to invalid IL or missing references) //IL_0740: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Expected O, but got Unknown //IL_074a: Expected O, but got Unknown //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown //IL_0851: Unknown result type (might be due to invalid IL or missing references) //IL_085c: Expected O, but got Unknown //IL_0879: Unknown result type (might be due to invalid IL or missing references) //IL_087f: Invalid comparison between Unknown and I4 //IL_0883: Unknown result type (might be due to invalid IL or missing references) //IL_0889: Invalid comparison between Unknown and I4 //IL_088d: Unknown result type (might be due to invalid IL or missing references) //IL_0893: Invalid comparison between Unknown and I4 CheckMoonSunFusion(); if (Input.GetKeyDown((KeyCode)290)) { AssetDumper.DumpAllAssets(); } Map instance = Map.Instance; if ((Object)instance != (Object)null && (Object)instance != (Object)_currentMap) { bool flag = (Object)(object)_currentMap != (Object)null; string text = (((Object)(object)_currentMap != (Object)null) ? ((Object)_currentMap).name : null); _currentMap = instance; _streamerUsedCommandInThisMap = false; string name = ((Object)instance).name; if (flag && !string.IsNullOrEmpty(text) && _lastSpawnedBossMap == text) { if (ChzzkStatManager.SaveData.SpawnedBossCount > 0) { ChzzkStatManager.SaveData.SpawnedBossCount = 0; ChzzkStatManager.Save(); } _lastSpawnedBossMap = null; } if (name != ChzzkStatManager.SaveData.StageName) { ChzzkStatManager.SaveData.StageName = name; ChzzkStatManager.SaveData.IsVoteCompletedInThisStage = false; ChzzkStatManager.SaveData.VotedResultTitle = null; ChzzkStatManager.Save(); } if (ChzzkStatManager.SaveData.SpawnedBossCount > 0 && _lastSpawnedBossMap != name) { Debug.Log((object)$"[ChzzkGameMode] Map 변경 감지 및 보스 복구 트리거: stageName={name}, SpawnedBossCount={ChzzkStatManager.SaveData.SpawnedBossCount}"); _lastSpawnedBossMap = name; ((MonoBehaviour)this).StartCoroutine(C_RecoverBossesForMap(name)); } if (IsBossRushActive) { Debug.Log((object)("[ChzzkGameMode] Map 변경 감지 및 보스 러쉬 복구 트리거: stageName=" + name)); ((MonoBehaviour)this).StartCoroutine(SpawnBossRushBosses()); } if ((Object)(object)_irradiatedMap != (Object)null && (Object)_irradiatedMap != (Object)(object)instance) { _irradiatedMap = null; } if ((Object)(object)_irradiatedMap == (Object)null && _isVoidAudioPlaying) { _isVoidAudioPlaying = false; if (_voidAudioCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_voidAudioCoroutine); _voidAudioCoroutine = null; } if ((Object)(object)_voidAudioSource != (Object)null) { _voidAudioSource.Stop(); } FieldInfo field = typeof(SoundManager).GetField("_backgroundMusic", BindingFlags.Instance | BindingFlags.NonPublic); if ((Object)Singleton.Instance != (Object)null && field != null) { AudioSource val = (AudioSource)field.GetValue(Singleton.Instance); if ((Object)(object)val != (Object)null && !_isNukeActive && !IsBossRushActive) { val.mute = false; } } } if (_voteState == VoteState.Voting) { EndVote(); StartVote(); } } string result; while (_pendingChats.TryDequeue(out result)) { _chatMessages.Enqueue(new ChatMessageInfo { msg = result, expireTime = Time.unscaledTime + 5f }); if (_chatMessages.Count > 6) { _chatMessages.Dequeue(); } } Character player = GetPlayer(); if ((Object)player != (Object)null && (Object)player != (Object)_lastPlayerForStats) { if ((Object)_lastPlayerForStats != (Object)null) { try { ((PriorityList)(object)_lastPlayerForStats.onGiveDamage).Remove(new GiveDamageDelegate(OnGiveDamageForCardSynergy)); if (_cardSynergyStats != null) { _lastPlayerForStats.stat.DetachValues(_cardSynergyStats); } if (_cardActiveBuffStats != null) { _lastPlayerForStats.stat.DetachValues(_cardActiveBuffStats); } _lastPlayerForStats.stat.SetNeedUpdate(); } catch { } } _cardSynergyStats = null; _cardActiveBuffStats = null; _lastCardSynergyStep = 0; _lastPlayerForStats = player; try { ((PriorityList)(object)player.onGiveDamage).Add(100, new GiveDamageDelegate(OnGiveDamageForCardSynergy)); } catch { } if ((Object)Map.Instance != (Object)null && (((Object)Map.Instance).name.Contains("Castle") || ((Object)Map.Instance).name.Contains("Tutorial") || ((Object)Map.Instance).name.Contains("Test"))) { Scene activeScene = SceneManager.GetActiveScene(); string name2 = ((Scene)(ref activeScene)).name; Debug.Log((object)("[ChzzkGameMode] Castle/Tutorial/Test 감지됨. Scene: " + name2 + ", Map: " + ((Object)Map.Instance).name)); if (name2.IndexOf("Title", StringComparison.OrdinalIgnoreCase) >= 0 || name2.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) >= 0) { Debug.Log((object)("[ChzzkGameMode] 타이틀/메뉴 화면 감지 (" + name2 + "). 초기화를 건너뜁니다.")); } else { ChzzkStatManager.Clear(); ChzzkStatManager.SaveData.SpawnedBossCount = 0; ChzzkStatManager.SaveData.IsVoteCompletedInThisStage = false; ChzzkStatManager.SaveData.VotedResultTitle = null; ChzzkStatManager.SaveData.StageName = null; ChzzkStatManager.Save(); _lastSpawnedBossMap = null; } } else { ChzzkStatManager.ApplyToPlayer(player); if (ChzzkStatManager.SaveData.IsVoteCompletedInThisStage && !string.IsNullOrEmpty(ChzzkStatManager.SaveData.VotedResultTitle)) { string votedResultTitle = ChzzkStatManager.SaveData.VotedResultTitle; if (votedResultTitle != "보스 소환" && votedResultTitle != "핵폭발 발동" && !votedResultTitle.EndsWith(" 모드")) { ApplyVotedAction(votedResultTitle); } } } } while (_chatMessages.Count > 0 && Time.unscaledTime > _chatMessages.Peek().expireTime) { _chatMessages.Dequeue(); } if ((Object)Map.Instance != (Object)null && (Object)_lastMap != (Object)Map.Instance) { _lastMap = Map.Instance; if (Plugin.EnableVote.Value && Plugin.VoteTriggerMode.Value.IndexOf("Scene", StringComparison.OrdinalIgnoreCase) >= 0 && _voteState == VoteState.Inactive && !_isNukeActive && !IsBossRushActive && !ChzzkStatManager.SaveData.IsVoteCompletedInThisStage) { StartVote(); } if (ForceNextDarkEnemy) { if ((Object)(object)_darkEnemyTargetMap == (Object)null) { _darkEnemyTargetMap = Map.Instance; Debug.Log((object)"[ChzzkGameMode] 다음 맵 커스텀 몬스터 강화 적용 완료 (타겟 맵 지정)"); ShowFloatingText("어둠의 기운이 다음 맵을 뒤덮습니다... (검은 적 등장!)"); } else if ((Object)_darkEnemyTargetMap != (Object)Map.Instance) { ForceNextDarkEnemy = false; _darkEnemyTargetMap = null; } } } if ((Object)(object)_irradiatedMap != (Object)null && (Object)Map.Instance == (Object)_irradiatedMap) { if (!_isVoidAudioPlaying && !_isNukeActive) { _isVoidAudioPlaying = true; _voidAudioCoroutine = ((MonoBehaviour)this).StartCoroutine(PlayVoidBgmRoutine()); } _irradiatedTimer += Time.unscaledDeltaTime; if (_irradiatedTimer >= 0.2f) { _irradiatedTimer = 0f; if ((Object)(object)Map.Instance.waveContainer != (Object)null) { List allSpawnedEnemies = Map.Instance.waveContainer.GetAllSpawnedEnemies(); if (allSpawnedEnemies != null) { foreach (Character item in allSpawnedEnemies) { if ((Object)item != (Object)null && !((Health)item.health).dead && (int)item.type != 3 && (int)item.type != 2 && (int)item.type != 1) { ApplyNukeDamage(item, isBoss: false); } } } } } } if ((Object)(object)_voidAudioSource != (Object)null) { _voidAudioSource.mute = IsBossRushActive || _isNukeActive; } if (Plugin.EnableVote.Value && !_isNukeActive && !IsBossRushActive) { if (_voteState == VoteState.Inactive && Plugin.VoteTriggerMode.Value.IndexOf("Timer", StringComparison.OrdinalIgnoreCase) >= 0) { _voteAutoTimer += Time.unscaledDeltaTime; if (_voteAutoTimer >= Plugin.VoteIntervalSeconds.Value) { StartVote(); _voteAutoTimer = 0f; } } else if (_voteState == VoteState.Voting) { _voteTimer -= Time.unscaledDeltaTime; if (_voteTimer <= 0f) { EndVote(); } } } if (Plugin.EnableChaosMode != null && Plugin.EnableChaosMode.Value && !_isNukeActive && !IsBossRushActive && Plugin.ChaosIntervalSeconds != null) { _chaosTimer += Time.unscaledDeltaTime; if (_chaosTimer >= Plugin.ChaosIntervalSeconds.Value) { _chaosTimer = 0f; try { TriggerRandomChaosCommand(); } catch (Exception arg) { Debug.LogError((object)$"[ChaosMode] 오류: {arg}"); } } } if (_onCooldown) { _cooldownTimer -= Time.unscaledDeltaTime; if (_cooldownTimer <= 0f) { _onCooldown = false; _cooldownTimer = 0f; } } DonationInfo result2; while (_donationQueue.TryDequeue(out result2)) { try { if (Plugin.EnableDonationTTS.Value && !string.IsNullOrWhiteSpace(result2.message)) { _ttsQueue.Enqueue(result2.message); } HandleDonation(result2.nickname, result2.amount); } catch (Exception arg2) { Debug.LogError((object)$"[ChzzkGameMode] 후원 실행 오류: {arg2}"); } } CommandInfo result3; while (_commandQueue.TryDequeue(out result3)) { string nickname = result3.nickname; string command = result3.command; if (!result3.isStreamer && _onCooldown) { if (Time.unscaledTime - _lastCooldownMessageTime > 1f) { _lastCooldownMessageTime = Time.unscaledTime; ShowFloatingText($"명령어 쿨타임.. ({_cooldownTimer:F1}초 남음)"); } continue; } if (!result3.isStreamer) { _onCooldown = true; _cooldownTimer = GLOBAL_COOLDOWN; } try { string text2 = command; string arg3 = ""; int num = command.IndexOf(' '); if (num != -1) { text2 = command.Substring(0, num).Trim(); arg3 = command.Substring(num + 1).Trim(); } text2 = text2.ToLower(); if (RandomCommands.Contains(text2)) { DoRandom(nickname); } else if (HealCommands.Contains(text2) && Plugin.AllowHeal.Value) { DoHeal(nickname); } else if (NpcCommands.Contains(text2) && Plugin.AllowNpc.Value) { DoNPC(nickname); } else if (FoodCommands.Contains(text2) && Plugin.AllowFood.Value) { DoFood(nickname); } else if (BoneCommands.Contains(text2) && Plugin.AllowBone.Value) { DoBone(nickname); } else if (GoldCommands.Contains(text2) && Plugin.AllowGold.Value) { DoGold(nickname); } else if (DarkQuartzCommands.Contains(text2) && Plugin.AllowDarkQuartz.Value) { DoDarkQuartz(nickname); } else if (QuintessenceCommands.Contains(text2) && Plugin.AllowQuintessence.Value) { ((MonoBehaviour)this).StartCoroutine(DoQuintessenceCoroutine(nickname)); } else if (FragmentCommands.Contains(text2) && Plugin.AllowFragment.Value) { ((MonoBehaviour)this).StartCoroutine(DoFragmentCoroutine(nickname)); } else if (DefenseCommands.Contains(text2) && Plugin.AllowDefense.Value) { DoDefense(nickname); } else if (TotemCommands.Contains(text2) && Plugin.AllowTotem.Value) { DoTotemBuff(nickname); } else if (ChestCommands.Contains(text2) && Plugin.AllowChest.Value) { DoChestSpawn(nickname); } else if (BuffCommands.Contains(text2) && Plugin.AllowBuffCurse.Value) { DoBuffOrCurse(nickname); } else if (ItemCommands.Contains(text2) && Plugin.AllowItem.Value) { ((MonoBehaviour)this).StartCoroutine(DoItemCoroutine(nickname, arg3)); } else if (SkullCommands.Contains(text2) && Plugin.AllowSkull.Value) { ((MonoBehaviour)this).StartCoroutine(DoSkullCoroutine(nickname, arg3)); } else if (SynergyCommands.Contains(text2) && Plugin.AllowSynergy.Value) { DoSynergy(nickname); } else if (OmenCommands.Contains(text2) && Plugin.AllowOmen.Value) { DoOmen(nickname); } else if ((BossCommands.Contains(text2) || text2 == "!보스소환") && Plugin.AllowBoss.Value) { if (text2 == "!보스소환") { if (result3.isStreamer) { DoBoss(nickname); } else { ShowFloatingText("보스소환 명령어는 스트리머 전용입니다."); } } else { DoBoss(nickname); } } else if (DarkEnemyCommands.Contains(text2)) { if (result3.isStreamer) { DoDarkEnemyForce(nickname); } else { ShowFloatingText("해당 명령어는 스트리머 전용입니다."); } } else if (DarkCommands.Contains(text2) && Plugin.AllowDarkAbility.Value) { DoDarkAbility(nickname); } else if (RandomStatCommands.Contains(text2) && Plugin.AllowRandomStat.Value) { DoRandomStat(nickname); } else if (text2 == "!핵" || text2 == "!nuke") { if (result3.isStreamer) { DoNuke(nickname); } } else if (text2 == "!entity" || text2 == "!엔티티") { if (result3.isStreamer) { DoPrintEntities(nickname); } else { ShowFloatingText("엔티티 명령어는 스트리머 전용입니다."); } } } catch (Exception arg4) { Debug.LogError((object)$"[Command Queue] Error processing {command}: {arg4}"); } } if (IsBossRushActive) { string text3 = (((Object)Map.Instance != (Object)null) ? ((Object)Map.Instance).name : null); if (text3 != null && !text3.Contains("Castle") && !text3.Contains("Tutorial") && !text3.Contains("Test")) { if (GetAliveEnemyCount() == 0) { _bossRushEmptyStageTimer += Time.unscaledDeltaTime; if (_bossRushEmptyStageTimer >= 30f) { _bossRushEmptyStageTimer = 0f; _lastSpawnedBossRushStage = null; ShowFloatingText("30초 동안 생존한 적이 없어 보스들이 재소환됩니다!"); ((MonoBehaviour)this).StartCoroutine(SpawnBossRushBosses()); } } else { _bossRushEmptyStageTimer = 0f; } } else { _bossRushEmptyStageTimer = 0f; } } else { _bossRushEmptyStageTimer = 0f; } if (_cardBuffCooldown > 0f) { _cardBuffCooldown -= Time.deltaTime; } if ((Object)(object)player != (Object)null) { _cardSynergyUpdateTimer -= Time.deltaTime; if (_cardSynergyUpdateTimer <= 0f) { _cardSynergyUpdateTimer = 0.5f; UpdateCardSynergy(player); } } if (Input.GetKeyDown((KeyCode)111) || Input.GetKeyDown((KeyCode)105)) { _showItemDestroyer = !_showItemDestroyer; } } private void TriggerRandomChaosCommand() { List> list = new List> { delegate(string n) { DoHeal(n); }, delegate(string n) { DoBuffOrCurse(n); }, delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoItemCoroutine(n)); }, delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoSkullCoroutine(n)); }, delegate(string n) { DoSynergy(n); }, delegate(string n) { DoOmen(n); }, delegate(string n) { DoBoss(n); }, delegate(string n) { DoDarkAbility(n); }, delegate(string n) { DoRandomStat(n); } }; list.Add(delegate(string n) { DoDropOmen(n); }); list.Add(delegate(string n) { DoBossRush(n); }); list.Add(delegate(string n) { DoRandomScreenEffect(n); }); if (Plugin.AllowNuke != null && Plugin.AllowNuke.Value) { list.Add(delegate(string n) { DoNuke(n); }); } list[_random.Next(list.Count)]("$CHAOS$"); } private void DrawItemDestroyerWindow(int windowId) { //IL_00a4: 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_00b3: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("파괴할 아이템을 선택하세요. 파괴된 아이템은 즉시 인벤토리에서 삭제됩니다.", Array.Empty()); Character player = GetPlayer(); if ((Object)(object)player == (Object)null || player.playerComponents == null || player.playerComponents.inventory == null || (Object)(object)player.playerComponents.inventory.item == (Object)null) { GUILayout.Label("플레이어 인벤토리를 찾을 수 없습니다.", Array.Empty()); if (GUILayout.Button("닫기", Array.Empty())) { _showItemDestroyer = false; } GUI.DragWindow(); return; } List items = player.playerComponents.inventory.item.items; _itemDestroyerScroll = GUILayout.BeginScrollView(_itemDestroyerScroll, Array.Empty()); int num = 0; for (int i = 0; i < items.Count; i++) { Item val = items[i]; if ((Object)(object)val == (Object)null) { continue; } num++; GUILayout.BeginHorizontal(Array.Empty()); string text = ((Object)val).name; try { string localizedString = Localization.GetLocalizedString(((Gear)val).displayNameKey); if (!string.IsNullOrEmpty(localizedString)) { text = localizedString; } } catch { } GUILayout.Label($"[{i + 1}] {text}", Array.Empty()); if (GUILayout.Button("파괴 (Destroy)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { try { player.playerComponents.inventory.item.Drop(i); Object.Destroy((Object)(object)((Component)val).gameObject); ChzzkStatManager.Save(); ShowFloatingText("[" + text + "] 아이템을 파괴했습니다!"); } catch (Exception ex) { Debug.LogError((object)("[ItemDestroyer] Failed to destroy item: " + ex)); } } GUILayout.EndHorizontal(); } if (num == 0) { GUILayout.Label("인벤토리에 보유 중인 아이템이 없습니다.", Array.Empty()); } GUILayout.EndScrollView(); if (GUILayout.Button("닫기", Array.Empty())) { _showItemDestroyer = false; } GUI.DragWindow(); } private void OnGUI() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Expected O, but got Unknown //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Expected O, but got Unknown //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) if (_showItemDestroyer) { Rect val = default(Rect); ((Rect)(ref val))..ctor((float)Screen.width / 2f - 250f, (float)Screen.height / 2f - 300f, 500f, 600f); GUI.Window(9999, val, new WindowFunction(DrawItemDestroyerWindow), "아이템 파괴기 (Item Destroyer)"); } GUIStyle val2 = new GUIStyle(); if ((Object)GUI.skin != (Object)null && GUI.skin.label != null) { val2 = new GUIStyle(GUI.skin.label); } val2.fontSize = 24; val2.wordWrap = true; val2.richText = true; val2.normal.textColor = Color.white; GUIStyle val3 = new GUIStyle(val2); val3.normal.textColor = Color.black; DrawTip(val2, val3); if (_chatMessages.Count == 0 && (!_onCooldown || !(_cooldownTimer > 0f)) && _voteState != VoteState.Voting) { return; } float num = (float)Screen.height - 350f; Rect val4 = default(Rect); Rect val5 = default(Rect); foreach (ChatMessageInfo chatMessage in _chatMessages) { val4 = new Rect(20f, num, 800f, 50f); ((Rect)(ref val5))..ctor(((Rect)(ref val4)).x + 1f, ((Rect)(ref val4)).y + 1f, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height); GUI.Label(val5, chatMessage.msg, val3); ((Rect)(ref val5))..ctor(((Rect)(ref val4)).x - 1f, ((Rect)(ref val4)).y - 1f, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height); GUI.Label(val5, chatMessage.msg, val3); GUI.Label(val4, chatMessage.msg, val2); num += 40f; } if (Plugin.EnableChatCommands != null && Plugin.EnableChatCommands.Value) { GUIStyle val6 = new GUIStyle(val2); val6.alignment = (TextAnchor)2; Rect val7 = default(Rect); ((Rect)(ref val7))..ctor((float)(Screen.width - 320), 20f, 300f, 50f); string text = ((_onCooldown && _cooldownTimer > 0f) ? $"커맨드 쿨타임: {_cooldownTimer:F1}초" : "커맨드 사용 가능 \ud83d\udfe2"); GUI.Label(val7, text, val6); } if (_voteState == VoteState.Voting) { GUIStyle val8 = new GUIStyle(val2); val8.fontSize = 28; val8.alignment = (TextAnchor)0; float num2 = 50f; float num3 = 100f; float num4 = 78f + (float)_currentVoteOptions.Count * 40f + 10f; GUI.Box(new Rect(30f, 90f, 640f, num4), ""); string text2 = $"[시청자 투표 진행중!] 남은 시간: {_voteTimer:F1}초\n채팅창에 번호(1, 2, 3)를 입력해 투표하세요!"; GUI.Label(new Rect(num2, num3, 600f, 70f), text2, val8); num3 += 78f; val8.fontSize = 24; for (int i = 0; i < _currentVoteOptions.Count; i++) { string text3 = $"{i + 1}. {_currentVoteOptions[i].Title} [{_currentVoteOptions[i].Votes}표]"; GUI.Label(new Rect(num2, num3, 600f, 35f), text3, val8); num3 += 40f; } } } private void DrawTip(GUIStyle baseStyle, GUIStyle baseOutlineStyle) { //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Expected O, but got Unknown //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Expected O, but got Unknown //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06aa: Unknown result type (might be due to invalid IL or missing references) List list = new List(); list.Add("[TIP] 키보드 K 키를 눌러 모드 설정창을 열고 닫을 수 있습니다."); list.Add("[TIP] 시청자 투표가 시작되면 채팅창에 번호(1, 2, 3)를 입력해 참여하세요."); list.Add("[TIP] 보스러쉬 모드가 활성화되면 보스들을 연달아 처치하며 기록에 도전하게 됩니다."); bool flag = Plugin.EnableChatCommands != null && Plugin.EnableChatCommands.Value; if (flag) { if (Plugin.AllowBoss != null && Plugin.AllowBoss.Value) { list.Add("[TIP] 채팅창에 " + GetFirstCommand(Plugin.CmdBossString.Value, "!보스") + " 명령어로 무작위 보스(체력/데미지 약화)를 소환하여 대결할 수 있습니다."); } if (Plugin.AllowOmen != null && Plugin.AllowOmen.Value) { list.Add("[TIP] 채팅창에 " + GetFirstCommand(Plugin.CmdOmenString.Value, "!오멘") + " 명령어로 강력한 오멘 아이템 상자를 필드에 소환합니다."); } if (Plugin.AllowSkull != null && Plugin.AllowSkull.Value && Plugin.AllowItem != null && Plugin.AllowItem.Value) { list.Add("[TIP] 채팅창에 " + GetFirstCommand(Plugin.CmdSkullString.Value, "!해골") + " 명령어로 새로운 스컬을, " + GetFirstCommand(Plugin.CmdItemString.Value, "!아이템") + " 명령어로 무작위 장비를 소환합니다."); } if (Plugin.AllowQuintessence != null && Plugin.AllowQuintessence.Value && Plugin.AllowTotem != null && Plugin.AllowTotem.Value) { list.Add("[TIP] 채팅창에 " + GetFirstCommand(Plugin.CmdQuintessenceString.Value, "!정수") + " 명령어로 정수를 소환하고, " + GetFirstCommand(Plugin.CmdTotemString.Value, "!토템") + " 명령어로 버프 토템을 소환합니다."); } if (Plugin.AllowDefense != null && Plugin.AllowDefense.Value) { list.Add("[TIP] 채팅창에 " + GetFirstCommand(Plugin.CmdDefenseString.Value, "!방어") + " 등의 방어 명령어로 스트리머를 일시 보호할 수 있습니다."); } if (Plugin.AllowFood != null && Plugin.AllowFood.Value) { list.Add("[TIP] 채팅창에 " + GetFirstCommand(Plugin.CmdFoodString.Value, "!음식") + " 등으로 음식을 소환하여 스트리머를 치유합니다."); } } else { list.Add("[TIP] [해골 소환] 후원은 스트리머에게 새로운 무작위 스컬(해골)을 즉시 선물합니다."); list.Add("[TIP] [아이템 소환] 후원은 스트리머의 필드에 무작위 아이템을 소환하여 지원합니다."); list.Add("[TIP] [흉조 상자 소환] 후원은 강력하고 위험한 오멘(흉조) 장비 상자를 소환합니다."); list.Add("[TIP] [보스 소환] 후원은 스트리머의 방에 약화된 무작위 보스를 소환하여 스릴을 줍니다."); list.Add("[TIP] [핵폭발 발동] 후원은 맵 전체에 강력한 핵 공격을 가해 일반 몹들을 소멸시킵니다."); list.Add("[TIP] [보스러쉬 활성화] 후원은 현재 스테이지의 난이도를 높이고 30초 대기 시 보스들을 자동 재소환합니다."); list.Add("[TIP] [아이템/검은능력/스컬 삭제] 후원은 장착 장비나 능력, 보조 스컬을 제거하여 챌린지를 방해합니다."); list.Add("[TIP] [마석/뼈/골드 선물] 후원은 유용한 성장에 필요한 기초 자원을 스트리머에게 드랍합니다."); } if (Plugin.DonAmtRandomStat != null) { list.Add($"[TIP] 소액 후원({Plugin.DonAmtRandomStat.Value:N0}원 이상): 골드/마석/뼈 소환, 랜덤 스탯 부여, 10% 힐/버프/저주 등이 무작위 발동!"); } if (Plugin.DonAmtSkull != null) { string arg = (flag ? ("무작위 해골(" + GetFirstCommand(Plugin.CmdSkullString.Value, "!해골") + ")") : "무작위 해골 소환"); string arg2 = (flag ? ("아이템(" + GetFirstCommand(Plugin.CmdItemString.Value, "!아이템") + ")") : "아이템 소환"); list.Add($"[TIP] 후원금 {Plugin.DonAmtSkull.Value:N0}원 이상: {arg}, {arg2}, 정수, NPC 소환 또는 힐/방어 부여!"); } if (Plugin.DonAmtChest != null) { string arg3 = (flag ? ("오멘 상자(" + GetFirstCommand(Plugin.CmdOmenString.Value, "!오멘") + ")") : "오멘 상자 소환"); list.Add($"[TIP] 후원금 {Plugin.DonAmtChest.Value:N0}원 이상: {arg3}, 파편 지급 또는 마석/본 등을 대량 선물!"); } if (Plugin.DonAmtBoss != null) { string arg4 = (flag ? ("보스(" + GetFirstCommand(Plugin.CmdBossString.Value, "!보스") + ")") : "보스 소환"); list.Add($"[TIP] 후원금 {Plugin.DonAmtBoss.Value:N0}원 이상: {arg4}을 소환하거나 화면 왜곡/블러 등 무작위 화면 효과 발동!"); } if (Plugin.DonAmtBossRush != null) { string arg5 = (flag ? " 또는 맵 전체 핵 공격(!핵) 발동!" : " 또는 맵 전체 핵 공격 발동!"); list.Add($"[TIP] 후원금 {Plugin.DonAmtBossRush.Value:N0}원 이상: 보스러쉬 활성화{arg5}"); } if (Plugin.DonAmtItemDelete != null) { list.Add($"[TIP] 후원금 {Plugin.DonAmtItemDelete.Value:N0}원 이상: 장착 중인 아이템 중 1개를 무작위 파괴(삭제)합니다!"); } if (Plugin.DonAmtDarkAbilityDelete != null) { list.Add($"[TIP] 후원금 {Plugin.DonAmtDarkAbilityDelete.Value:N0}원 이상: 소중한 검은 능력 중 1개를 무작위 삭제합니다!"); } if (Plugin.DonAmtSubSkullDelete != null) { list.Add($"[TIP] 후원금 {Plugin.DonAmtSubSkullDelete.Value:N0}원 이상: 장착 중인 서브 스컬(보조 해골)을 강제 삭제합니다!"); } if (Plugin.DonAmtNukeItems != null) { list.Add($"[TIP] 후원금 {Plugin.DonAmtNukeItems.Value:N0}원 이상: 인벤토리의 모든 아이템을 소멸시키고 뼈 파편으로 환원시킵니다!"); } if (Plugin.DonAmtNukeAll != null) { list.Add($"[TIP] 후원금 {Plugin.DonAmtNukeAll.Value:N0}원 이상: 장착 스컬 및 모든 아이템을 파괴하는 대재앙을 일으킵니다!"); } if (list.Count != 0) { int seed = (int)(Time.time / 8f); Random random = new Random(seed); int index = random.Next(list.Count); string text = list[index]; GUIStyle val = new GUIStyle(baseStyle); val.fontSize = 16; val.alignment = (TextAnchor)4; GUIStyle val2 = new GUIStyle(baseOutlineStyle); val2.fontSize = 16; val2.alignment = (TextAnchor)4; float num = Screen.width; float num2 = 30f; float num3 = (float)Screen.height - 40f; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, num3, num, num2); string text2 = Regex.Replace(text, "<[^>]*>", ""); GUI.Label(new Rect(((Rect)(ref val3)).x + 1f, ((Rect)(ref val3)).y + 1f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), text2, val2); GUI.Label(new Rect(((Rect)(ref val3)).x - 1f, ((Rect)(ref val3)).y - 1f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), text2, val2); GUI.Label(val3, text, val); } } private int GetAliveEnemyCount() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown if ((Object)Map.Instance == (Object)null || (Object)Map.Instance.waveContainer == (Object)null) { return 0; } List allSpawnedEnemies = Map.Instance.waveContainer.GetAllSpawnedEnemies(); if (allSpawnedEnemies == null) { return 0; } int num = 0; foreach (Character item in allSpawnedEnemies) { if ((Object)item != (Object)null && !((Health)item.health).dead) { num++; } } return num; } private void DrawOutlineText(Rect rect, string text, GUIStyle style, GUIStyle outlineStyle) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) string text2 = text.Replace("", "").Replace("", "").Replace("", "") .Replace("", "") .Replace("", "") .Replace("", "") .Replace("", ""); Rect val = rect; GUI.Label(new Rect(((Rect)(ref val)).x + 1f, ((Rect)(ref val)).y + 1f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text2, outlineStyle); GUI.Label(new Rect(((Rect)(ref val)).x - 1f, ((Rect)(ref val)).y - 1f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text2, outlineStyle); GUI.Label(rect, text, style); } private bool IsValidCommand(string text) { string text2 = text; int num = text.IndexOf(' '); if (num != -1) { text2 = text.Substring(0, num); } return HealCommands.Contains(text2) || BuffCommands.Contains(text2) || ItemCommands.Contains(text2) || SkullCommands.Contains(text2) || SynergyCommands.Contains(text2) || OmenCommands.Contains(text2) || BossCommands.Contains(text2) || text2 == "!보스소환" || DarkCommands.Contains(text2) || DarkEnemyCommands.Contains(text2) || RandomCommands.Contains(text2) || RandomStatCommands.Contains(text2) || NpcCommands.Contains(text2) || FoodCommands.Contains(text2) || BoneCommands.Contains(text2) || GoldCommands.Contains(text2) || DarkQuartzCommands.Contains(text2) || QuintessenceCommands.Contains(text2) || FragmentCommands.Contains(text2) || DefenseCommands.Contains(text2) || TotemCommands.Contains(text2) || ChestCommands.Contains(text2); } public void OnChatMessage(string nickname, string message) { if (_isNukeActive || string.IsNullOrWhiteSpace(message)) { return; } string text = message.Trim().ToLower(); nickname = (string.IsNullOrEmpty(nickname) ? "익명" : nickname); if (text.StartsWith("!후원테스트")) { if (nickname == Plugin.StreamerNickname.Value) { string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int amount = 1000; if (array.Length > 1 && int.TryParse(array[1], out var result)) { amount = result; } OnDonation(nickname, amount); } else { ShowFloatingText("후원테스트 명령어는 스트리머 전용입니다."); } return; } switch (text) { default: if (!(text == "!엔티티")) { bool flag = Plugin.EnableChatCommands != null && Plugin.EnableChatCommands.Value && IsValidCommand(text) && !IsBossRushActive; if (_voteState == VoteState.Voting && int.TryParse(text.Replace("!", ""), out var result2) && result2 >= 1 && result2 <= _currentVoteOptions.Count && !_votedUsers.Contains(nickname)) { _votedUsers.Add(nickname); _currentVoteOptions[result2 - 1].Votes++; } else if (flag) { if (nickname == Plugin.StreamerNickname.Value) { if (Plugin.AllowStreamerCommand.Value) { if (_streamerUsedCommandInThisMap) { ShowFloatingText("스트리머는 이번 맵에서 이미 명령어를 사용했습니다!"); break; } _streamerUsedCommandInThisMap = true; _commandQueue.Enqueue(new CommandInfo { nickname = nickname, command = text, isStreamer = true }); } } else { _commandQueue.Enqueue(new CommandInfo { nickname = nickname, command = text, isStreamer = false }); } } else { string text2 = nickname.Replace("<", "").Replace(">", ""); _pendingChats.Enqueue("[" + text2 + "] " + message); if (Plugin.EnableChatTTS != null && Plugin.EnableChatTTS.Value && !string.IsNullOrWhiteSpace(message)) { _ttsQueue.Enqueue(message); } } break; } goto case "!핵"; case "!핵": case "!nuke": case "!entity": _commandQueue.Enqueue(new CommandInfo { nickname = nickname, command = text, isStreamer = (nickname == Plugin.StreamerNickname.Value) }); break; } } public void OnDonation(string nickname, int amount, string message = "") { if (!_isNukeActive) { nickname = (string.IsNullOrEmpty(nickname) ? "익명" : nickname); _donationQueue.Enqueue(new DonationInfo { nickname = nickname, amount = amount, message = message }); } } private void HandleDonation(string nickname, int amount) { List list = new List(); list.Add(new DonationAction { cost = Plugin.DonAmtNukeAll.Value, action = delegate { DoDonationNukeAll(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtNukeItems.Value, action = delegate { DoDonationNukeItems(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtSubSkullDelete.Value, action = delegate { DoDonationSubSkullDelete(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtDarkAbilityDelete.Value, action = delegate { DoDonationDarkAbilityDelete(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtItemDelete.Value, action = delegate { DoDonationItemDelete(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtBossRush.Value, action = delegate { DoBossRush(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtBoss.Value, action = delegate { DoBoss(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtScreenEffect.Value, action = delegate { DoRandomScreenEffect(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtSynergy.Value, action = delegate { DoDonationSynergy(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtDarkAbility.Value, action = delegate { DoDonationDarkAbility(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtFragment.Value, action = delegate { ((MonoBehaviour)this).StartCoroutine(DoFragmentCoroutine(nickname)); } }); list.Add(new DonationAction { cost = Plugin.DonAmtOmen.Value, action = delegate { DoOmen(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtItem.Value, action = delegate { ((MonoBehaviour)this).StartCoroutine(DoDonationItemCoroutine(nickname)); } }); list.Add(new DonationAction { cost = Plugin.DonAmtSkull.Value, action = delegate { ((MonoBehaviour)this).StartCoroutine(DoSkullCoroutine(nickname)); } }); list.Add(new DonationAction { cost = Plugin.DonAmtQuintessence.Value, action = delegate { ((MonoBehaviour)this).StartCoroutine(DoQuintessenceCoroutine(nickname)); } }); list.Add(new DonationAction { cost = Plugin.DonAmtNPC.Value, action = delegate { DoNPC(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtStat.Value, action = delegate { DoDonationStat(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtRandomStat.Value, action = delegate { DoRandomStat(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtBuffCurse.Value, action = delegate { DoBuffOrCurse(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtHeal.Value, action = delegate { DoHeal(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtDefense.Value, action = delegate { DoDefense(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtTotem.Value, action = delegate { DoTotemBuff(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtNuke.Value, action = delegate { DoNuke(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtFood.Value, action = delegate { DoFood(nickname); } }); list.Add(new DonationAction { cost = Plugin.DonAmtChest.Value, action = delegate { DoChestSpawn(nickname); } }); int num = -1; foreach (DonationAction item in list) { if (item.cost <= amount && item.cost > num) { num = item.cost; } } if (num <= 0) { return; } List list2 = new List(); foreach (DonationAction item2 in list) { if (item2.cost == num) { list2.Add(item2.action); } } if (list2.Count > 0) { list2[_random.Next(list2.Count)](); } } private void DoDonationStat(string nickname) { DoGold(nickname); DoDarkQuartz(nickname); DoBone(nickname); } private void DoBone(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } int num = _random.Next(5, 15); Service service = GetService(); if ((Object)(object)service != (Object)null) { LevelManager levelManager = service.levelManager; if ((Object)(object)levelManager != (Object)null) { levelManager.DropCurrency((Type)2, num, num, ((Component)player).transform.position + Vector3.up * 1.5f); } } ShowFloatingText($"{nickname}님이 뼈 파편 {num}개를 떨어뜨렸습니다!"); } private void DoGold(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } int num = _random.Next(300, 1000); Service service = GetService(); if ((Object)(object)service != (Object)null) { LevelManager levelManager = service.levelManager; if ((Object)(object)levelManager != (Object)null) { levelManager.DropCurrency((Type)0, num, 10, ((Component)player).transform.position + Vector3.up * 1.5f); } } ShowFloatingText($"{nickname}님이 골드 {num}G를 떨어뜨렸습니다!"); } private void DoDarkQuartz(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } Service service = GetService(); if ((Object)(object)service != (Object)null) { LevelManager levelManager = service.levelManager; if ((Object)(object)levelManager != (Object)null) { levelManager.DropCurrency((Type)1, 1, 1, ((Component)player).transform.position + Vector3.up * 1.5f); } } ShowFloatingText(nickname + "님이 검은마석 1개를 떨어뜨렸습니다!"); } private void DoFood(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } AbilityBuff[] array = Resources.FindObjectsOfTypeAll(); if (array != null && array.Length != 0) { AbilityBuff val = array[_random.Next(array.Length)]; if (_random.Next(100) < 9) { AbilityBuff[] array2 = array; foreach (AbilityBuff val2 in array2) { if (((Object)val2).name.IndexOf("WitchFruit", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val2).name.IndexOf("Apple", StringComparison.OrdinalIgnoreCase) >= 0 || (((Object)val2).name.IndexOf("Witch", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)val2).name.IndexOf("Apple", StringComparison.OrdinalIgnoreCase) >= 0) || (val2.displayName != null && val2.displayName.Contains("마녀의 사과"))) { val = val2; break; } } } GameObject gameObject = ((Component)((Component)val).transform.root).gameObject; GameObject val3 = Object.Instantiate(gameObject, ((Component)player).transform.position, Quaternion.identity); ((Object)val3).name = ((Object)gameObject).name.Replace("(Clone)", ""); AbilityBuff componentInChildren = val3.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { ((Object)((Component)componentInChildren).gameObject).name = ((Object)((Component)val).gameObject).name.Replace("(Clone)", ""); componentInChildren.price = 0; componentInChildren.Initialize(); } val3.SetActive(true); string text = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.displayName : "음식"); ShowFloatingText(nickname + "님이 상점 음식(" + text + ")을 소환했어요!"); } else { double num = ((Health)player.health).PercentHeal(0.2f); ShowFloatingText(nickname + "님이 음식을 선물했어요! (체력 회복)"); } } private void DoNPC(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } try { FieldNpc[] array = Resources.FindObjectsOfTypeAll(); if (array != null && array.Length != 0) { FieldNpc val = array[_random.Next(array.Length)]; Vector3 val2 = ((Component)player).transform.position + Vector3.right * 2f; FieldNpc val3 = Object.Instantiate(val, val2, Quaternion.identity); if ((Object)Map.Instance != (Object)null) { ((Component)val3).transform.SetParent(((Component)Map.Instance).transform, true); } ((Component)val3).gameObject.SetActive(true); try { MethodInfo method = typeof(FieldNpc).GetMethod("OnCageDestroyed", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { method.Invoke(val3, null); } } catch { } ShowFloatingText(nickname + "님이 [" + ((object)val).GetType().Name + "] NPC를 소환했습니다!"); } else { ShowFloatingText(nickname + "님이 부른 NPC가 오지 못해서 대신 버프를 남겼습니다!"); DoBuffOrCurse("유령 NPC"); } } catch (Exception ex) { Debug.LogError((object)("[ChzzkGameMode] DoNPC 오류: " + ex)); ShowFloatingText(nickname + "님이 부른 NPC가 오지 못해서 대신 버프를 남겼습니다!"); DoBuffOrCurse("유령 NPC"); } } private IEnumerator DoDonationItemCoroutine(string nickname) { Character player = GetPlayer(); if ((Object)player == (Object)null) { yield break; } int roll = _random.Next(1, 101); if (roll <= 50) { Inventory inventory = player.playerComponents.inventory; if (inventory != null) { List nonGlitchedItems = inventory.item.items.Where((Item i) => (Object)(object)i != (Object)null && (Object)(object)((Component)i).GetComponent() == (Object)null).ToList(); if (nonGlitchedItems.Count > 0) { int randomIndex = _random.Next(nonGlitchedItems.Count); Item itemToRemove = nonGlitchedItems[randomIndex]; inventory.item.Remove(itemToRemove); ShowFloatingText(nickname + "님이 아이템을 삭제했습니다! (후원)"); } else { ShowFloatingText(nickname + "님의 아이템 삭제 시도! 삭제할 수 있는 일반 아이템이 없습니다. (후원)"); } } yield break; } Service service = GetService(); if ((Object)service == (Object)null) { yield break; } Rarity rarity = PickWeightedRarity(); ItemReference itemRef = service.gearManager.GetItemToTake(rarity); if (itemRef == null) { itemRef = service.gearManager.GetItemToTake((Rarity)0); } if (itemRef != null) { ItemRequest request = itemRef.LoadAsync(); while (!((Request)(object)request).isDone) { yield return null; } Item drop = service.levelManager.DropItem(request, ((Component)player).transform.position); if (player.playerComponents.inventory.item.items.Count((Item i) => (Object)i != (Object)null) < (CustomGearsPatch.HasErrorCreator() ? 50 : 9)) { player.playerComponents.inventory.item.TryEquip(drop); ShowFloatingText(nickname + "님이 아이템을 추가했습니다! (후원)"); } else { ShowFloatingText(nickname + "님이 아이템을 바닥에 떨궜습니다! (후원)"); } } } private void DoDonationDarkAbility(string nickname) { DoDarkAbility(nickname); } private void DoDonationSynergy(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Invalid comparison between Unknown and I4 //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Invalid comparison between Unknown and I4 //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } Inventory inventory = player.playerComponents.inventory; if (inventory == null || (Object)inventory.synergy == (Object)null || inventory.synergy.inscriptions == null) { return; } Synergy synergy = inventory.synergy; List list = new List(); List list2 = new List(); if (Inscription.keys != null) { foreach (Key key in Inscription.keys) { if ((int)key != 0 && (int)key != 35 && (PluginItems.IsModActive || (int)key != 37)) { if (synergy.inscriptions[key].count > 0) { list.Add(key); } else { list2.Add(key); } } } } int num = _random.Next(1, 101); if (num <= 50) { if (list.Count > 0) { Key val = list[_random.Next(list.Count)]; if (synergy.inscriptions[val].bonusCount > 0) { Inscription val2 = synergy.inscriptions[val]; val2.bonusCount--; inventory.UpdateSynergy(); ShowFloatingText($"{nickname}님이 [{val}] 각인을 1 삭제했습니다! (후원)"); } else { ShowFloatingText(nickname + "님이 각인 삭제를 시도했으나 보너스가 없습니다! (후원)"); } } else { ShowFloatingText(nickname + "님의 각인 삭제가 불발되었습니다! (후원)"); } return; } Key val3; if (list.Count > 0 && _random.Next(1, 101) <= 50) { val3 = list[_random.Next(list.Count)]; } else { if (list2.Count <= 0) { return; } val3 = list2[_random.Next(list2.Count)]; } Inscription val4 = synergy.inscriptions[val3]; val4.bonusCount++; CustomSuperInscriptions.Add(val3); ChzzkStatManager.Save(); inventory.UpdateSynergy(); ShowFloatingText($"{nickname}님이 [{val3}] 각인을 1 추가했습니다! (후원)"); } private void DoDonationItemDelete(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } Inventory inventory = player.playerComponents.inventory; if (inventory != null) { List list = inventory.item.items.Where((Item i) => (Object)(object)i != (Object)null && (Object)(object)((Component)i).GetComponent() == (Object)null).ToList(); if (list.Count > 0) { int index = _random.Next(list.Count); Item val = list[index]; inventory.item.Remove(val); ShowFloatingText(nickname + "님이 아이템 1개를 확정 삭제했습니다! (후원)"); } else { ShowFloatingText(nickname + "님의 아이템 확정 삭제 시도! 삭제할 수 있는 일반 아이템이 없습니다. (후원)"); } } } private void DoDonationDarkAbilityDelete(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } UpgradeInventory upgrade = player.playerComponents.inventory.upgrade; if ((Object)upgrade == (Object)null) { return; } List upgrades = upgrade.upgrades; List list = new List(); for (int i = 0; i < upgrades.Count; i++) { if ((Object)upgrades[i] != (Object)null) { list.Add(i); } } if (list.Count > 0) { int num = list[_random.Next(list.Count)]; upgrade.Remove(num); upgrade.Trim(); ShowFloatingText(nickname + "님이 검은 능력을 확정 삭제했습니다! (후원)"); } } private bool TryDeleteSubSkull() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00d8: 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_00e9: Expected O, but got Unknown //IL_00e9: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return false; } WeaponInventory weapon = player.playerComponents.inventory.weapon; if ((Object)weapon == (Object)null) { return false; } try { Type type = ((object)weapon).GetType(); FieldInfo fieldInfo = type.GetField("weapons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("_weapons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (fieldInfo != null && fieldInfo.GetValue(weapon) is Array array) { Weapon polymorphOrCurrent = weapon.polymorphOrCurrent; Weapon val = null; for (int i = 0; i < array.Length; i++) { Weapon val2 = (Weapon)array.GetValue(i); if ((Object)val2 != (Object)null && (Object)val2 != (Object)polymorphOrCurrent) { val = val2; break; } } if ((Object)(object)val != (Object)null) { if ((Object)(object)player.animationController != (Object)null) { FieldInfo field = ((object)player.animationController).GetType().GetField("animations", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.GetValue(player.animationController) is IList list) { CharacterAnimation[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); CharacterAnimation[] array2 = componentsInChildren; foreach (CharacterAnimation value in array2) { list.Remove(value); } for (int num = list.Count - 1; num >= 0; num--) { object obj = list[num]; if (obj == null || obj.Equals(null)) { list.RemoveAt(num); } } } } array.SetValue(polymorphOrCurrent, 0); for (int k = 1; k < array.Length; k++) { array.SetValue(null, k); } ((Component)val).transform.SetParent((Transform)null); MethodInfo method = type.GetMethod("ForceEquip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(weapon, new object[1] { polymorphOrCurrent }); } ((Component)val).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)val).gameObject); return true; } } } catch (Exception ex) { Debug.LogWarning((object)("[ChzzkGameMode] 보조 머리 삭제 실패: " + ex)); } return false; } private void DoDonationSubSkullDelete(string nickname) { if (TryDeleteSubSkull()) { ShowFloatingText(nickname + "님이 보조 머리를 확정 삭제했습니다! (후원)"); } else { ShowFloatingText(nickname + "님의 보조 머리 삭제가 불발되었습니다."); } } private void DoDonationNukeItems(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } Inventory inventory = player.playerComponents.inventory; if (inventory == null) { return; } int num = 0; for (int num2 = inventory.item.items.Count - 1; num2 >= 0; num2--) { Item val = inventory.item.items[num2]; if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent() == (Object)null) { inventory.item.Remove(val); num++; } } if (num > 0) { ShowFloatingText(nickname + "님이 모든 일반 아이템을 파괴했습니다! (후원)"); } else { ShowFloatingText(nickname + "님이 아이템 파괴를 시도했으나 파괴할 일반 아이템이 없네요!"); } } private void DoDonationNukeAll(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } bool flag = false; Inventory inventory = player.playerComponents.inventory; if (inventory != null && inventory.item.items.Count > 0) { for (int num = inventory.item.items.Count - 1; num >= 0; num--) { Item val = inventory.item.items[num]; if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent() == (Object)null) { inventory.item.Remove(val); flag = true; } } } UpgradeInventory upgrade = player.playerComponents.inventory.upgrade; if ((Object)upgrade != (Object)null) { List upgrades = upgrade.upgrades; for (int num2 = upgrades.Count - 1; num2 >= 0; num2--) { if ((Object)upgrades[num2] != (Object)null) { upgrade.Remove(num2); flag = true; } } upgrade.Trim(); } if (flag) { ShowFloatingText(nickname + "님이 모든 아이템과 검은 능력을 증발시켰습니다!! (후원)"); } else { ShowFloatingText(nickname + "님이 파괴를 시도했으나 이미 아무것도 없네요!"); } } private void DoRandom(string nickname) { int num = _random.Next(1, 4); ShowFloatingText($"{nickname}이(가) 랜덤 효과 {num}개를 발동시켰어요!"); Action[] source = new Action[10] { delegate(string n) { DoHeal(n); }, delegate(string n) { DoBuffOrCurse(n); }, delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoItemCoroutine(n)); }, delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoSkullCoroutine(n)); }, delegate(string n) { DoSynergy(n); }, delegate(string n) { DoOmen(n); }, delegate(string n) { DoBoss(n); }, delegate(string n) { DoDarkAbility(n); }, delegate(string n) { DoRandomStat(n); }, delegate(string n) { DoRandomScreenEffect(n); } }; List> list = source.OrderBy((Action x) => _random.Next()).Take(num).ToList(); foreach (Action item in list) { item(nickname); } } private void DoDefense(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } try { if (_random.Next(2) == 0) { ChzzkStatManager.AddStat(player, Category.Percent, Kind.TakingDamage, -0.1); ShowFloatingText(nickname + "이(가) 방어력(받는 피해 10% 감소) 축복을 내렸어요!"); } else { ChzzkStatManager.AddStat(player, Category.Percent, Kind.TakingDamage, 0.1); ShowFloatingText(nickname + "이(가) 방어력(받는 피해 10% 증가) 저주를 내렸어요!"); } } catch { } } private void DoTotemBuff(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } SavableAbilityManager component = ((Component)player).GetComponent(); if ((Object)component == (Object)null) { ShowFloatingText(nickname + " 버프 토템 발동 실패 (AbilityManager 없음)"); return; } string text; switch (_random.Next(4)) { case 0: component.Apply((Name)8, 1f, 90f); text = "잔혹함 토템 (공격력↑) 90초"; break; case 1: component.Apply((Name)9, 1f, 90f); text = "분노 토템 (공격속도↑) 90초"; break; case 2: component.Apply((Name)6, 20f, 90f); text = "강철 토템 (방어막 획득) 90초"; break; default: { double num = ((Health)player.health).PercentHeal(0.2f); text = $"에너지 토템 (체력 +{num:F0} 회복)"; break; } } ShowFloatingText(nickname + "이(가) " + text + " 축복을 내렸어요!"); } private void DoChestSpawn(string nickname, bool isOmen = false) { DoChestSpawn(nickname, null, isOmen); } private void DoChestSpawn(string nickname, Rarity? customRarity, bool isOmen = false) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Expected O, but got Unknown //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } try { HardmodeChest val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)delegate(HardmodeChest c) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) int result; if ((Object)(object)c != (Object)null) { Scene scene = ((Component)c).gameObject.scene; result = ((!((Scene)(ref scene)).IsValid()) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }); if ((Object)(object)val == (Object)null) { val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((HardmodeChest c) => (Object)(object)c != (Object)null)); } Vector3 val2 = ((Component)player).transform.position + Vector3.right * 2f; if ((Object)(object)val != (Object)null) { if (isOmen) { OmenChestPath.ForceNextOmen = true; } HardmodeChest val3 = Object.Instantiate(val, val2, Quaternion.identity); if ((Object)Map.Instance != (Object)null) { ((Component)val3).transform.SetParent(((Component)Map.Instance).transform, true); } Rarity rarity = (Rarity)0; try { FieldInfo field = typeof(HardmodeChest).GetField("_rarity", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { if (customRarity.HasValue) { field.SetValue(val3, customRarity.Value); } rarity = (Rarity)field.GetValue(val3); } } catch { } ((Component)val3).gameObject.SetActive(true); if (isOmen) { val3.TryToChangeOmenChest(); } if (isOmen) { ShowFloatingText(nickname + "님이 흉조 상자를 소환했습니다!"); return; } string rarityKorean = GetRarityKorean(rarity); ShowFloatingText(nickname + "님이 [" + rarityKorean + "] 등급의 상자(하드모드)를 소환했습니다!"); return; } Chest val4 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)delegate(Chest c) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) int result; if ((Object)(object)c != (Object)null) { Scene scene = ((Component)c).gameObject.scene; result = ((!((Scene)(ref scene)).IsValid()) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }); if ((Object)(object)val4 == (Object)null) { val4 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Chest c) => (Object)(object)c != (Object)null)); } if ((Object)(object)val4 != (Object)null) { Chest val5 = Object.Instantiate(val4, val2, Quaternion.identity); if ((Object)Map.Instance != (Object)null) { ((Component)val5).transform.SetParent(((Component)Map.Instance).transform, true); } Rarity rarity2 = (Rarity)0; try { FieldInfo field2 = typeof(Chest).GetField("_rarity", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 != null) { if (customRarity.HasValue) { field2.SetValue(val5, customRarity.Value); } rarity2 = (Rarity)field2.GetValue(val5); } } catch { } ((Component)val5).gameObject.SetActive(true); string rarityKorean2 = GetRarityKorean(rarity2); ShowFloatingText(nickname + "님이 [" + rarityKorean2 + "] 등급의 상자를 소환했습니다!"); } else { ShowFloatingText("소환 가능한 상자 프리팹을 찾지 못했습니다!"); } } catch (Exception ex) { Debug.LogError((object)("[ChzzkGameMode] DoChestSpawn 오류: " + ex)); ShowFloatingText("상자 소환에 실패했습니다!"); } } private string GetRarityKorean(Rarity rarity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0028: 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_0041: Expected I4, but got Unknown switch ((int)rarity) { case 4: return "신화"; case -1: return "무가치"; default: return (int)rarity switch { 0 => "일반", 1 => "희귀", 2 => "유니크", 3 => "레전더리", _ => "일반", }; } } private void DoPrintEntities(string nickname) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) if ((Object)Map.Instance == (Object)null) { return; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; List allSpawnedEnemies = Map.Instance.waveContainer.GetAllSpawnedEnemies(); foreach (Character item in allSpawnedEnemies) { if ((Object)item != (Object)null && ((Component)item).gameObject.activeInHierarchy && !((Health)item.health).dead) { if ((int)item.type == 3) { num2++; } else { num++; } Plugin.Log.LogInfo((object)("[ChzzkGameMode] Entity (Character): " + ((Object)item).name + " (Type: " + ((object)item.type/*cast due to .constrained prefix*/).ToString() + ")")); } } FieldNpc[] array = Object.FindObjectsOfType(); FieldNpc[] array2 = array; foreach (FieldNpc val in array2) { if (((Component)val).gameObject.activeInHierarchy) { num3++; Plugin.Log.LogInfo((object)("[ChzzkGameMode] Entity (NPC): " + ((Object)val).name)); } } Altar[] array3 = Object.FindObjectsOfType(); Altar[] array4 = array3; foreach (Altar val2 in array4) { Scene scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).name != null && ((Component)val2).gameObject.activeInHierarchy) { num4++; Plugin.Log.LogInfo((object)("[ChzzkGameMode] Entity (Totem): " + ((Object)((Component)val2).transform.root).name)); } } string text = $"로드된 엔티티: 일반적 {num}명, 보스 {num2}명, NPC {num3}명, 토템 {num4}개 (콘솔 로그 확인)"; ShowFloatingText(text); Plugin.Log.LogInfo((object)("[ChzzkGameMode] " + text)); } private IEnumerator PlayVoidBgmRoutine() { string pluginPath = Path.Combine(Paths.PluginPath, "ChzzkSkul"); if (!Directory.Exists(pluginPath)) { yield break; } string[] files = Directory.GetFiles(pluginPath, "*void*.*"); List validFiles = new List(); string[] array = files; foreach (string f in array) { string ext = Path.GetExtension(f).ToLower(); if (ext == ".mp3" || ext == ".wav" || ext == ".ogg") { validFiles.Add(f); } } if (validFiles.Count == 0) { FieldInfo bgmField = typeof(SoundManager).GetField("_backgroundMusic", BindingFlags.Instance | BindingFlags.NonPublic); if ((Object)Singleton.Instance != (Object)null && bgmField != null) { AudioSource gameBgm = (AudioSource)bgmField.GetValue(Singleton.Instance); if ((Object)(object)gameBgm != (Object)null && !IsBossRushActive && !_isNukeActive) { gameBgm.mute = false; } } yield break; } string bgmPath = validFiles[Random.Range(0, validFiles.Count)]; AudioClip clip = null; UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file://" + bgmPath, (AudioType)0); try { yield return www.SendWebRequest(); if ((int)www.result == 1) { clip = DownloadHandlerAudioClip.GetContent(www); } } finally { ((IDisposable)www)?.Dispose(); } if (!((Object)(object)clip != (Object)null)) { yield break; } if ((Object)(object)_voidAudioSource == (Object)null) { _voidAudioSource = ((Component)this).gameObject.AddComponent(); } _voidAudioSource.clip = clip; _voidAudioSource.loop = true; _voidAudioSource.Play(); FieldInfo bgmField2 = typeof(SoundManager).GetField("_backgroundMusic", BindingFlags.Instance | BindingFlags.NonPublic); if ((Object)Singleton.Instance != (Object)null && bgmField2 != null) { AudioSource gameBgm2 = (AudioSource)bgmField2.GetValue(Singleton.Instance); if ((Object)(object)gameBgm2 != (Object)null) { gameBgm2.mute = true; } } } private void DoNuke(string nickname, bool isResume = false) { if (!_isNukeActive || isResume) { _isNukeActive = true; ChzzkStatManager.Save(); if (_voteState == VoteState.Voting) { EndVote(); } ((MonoBehaviour)this).StartCoroutine(NukeCountdown(nickname, isResume)); } } private void ApplyNukeDamage(Character e, bool isBoss) { string text = (isBoss ? Plugin.NukeBossDamageType.Value : Plugin.NukeNormalEnemyDamageType.Value).ToLower().Trim(); float num = (isBoss ? Plugin.NukeBossDamageValue.Value : Plugin.NukeNormalEnemyDamageValue.Value); switch (text) { case "instantkill": ((Health)e.health).TryKill(); break; case "fixed": { double num3 = ((Health)e.health).currentHealth - (double)num; if (num3 <= 0.0) { ((Health)e.health).TryKill(); } else { ((Health)e.health).SetCurrentHealth(num3); } break; } case "percent": { double num2 = ((Health)e.health).currentHealth - ((Health)e.health).maximumHealth * (double)num / 100.0; if (num2 <= 0.0) { ((Health)e.health).TryKill(); } else { ((Health)e.health).SetCurrentHealth(num2); } break; } } } private IEnumerator NukeCountdown(string nickname, bool isResume = false) { float duration = Plugin.NukeCountdownTime.Value; float elapsed = (isResume ? _nukeElapsed : 0f); Map startMap = Map.Instance; Map currentMap = startMap; int scenesPassed = (isResume ? _nukeScenesPassed : 0); if (isResume) { int rem = Mathf.Max(0, Mathf.CeilToInt(duration - elapsed)); ShowFloatingText($"핵 카운트다운 복구됨! ({rem}초 남음)"); Plugin.Log.LogInfo((object)$"[Nuke] Nuke resumed from previous state ({rem}s left)."); } else { ShowFloatingText($"{nickname}이 핵을 발사했습니다! {duration}초 안에 3맵 이상을 클리어하세요!"); Plugin.Log.LogInfo((object)("[Nuke] Nuke triggered by " + nickname)); } string bgmPathMp3 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "nuke_bgm.mp3"); string bgmPathWav = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "nuke_bgm.wav"); string bgmPathOgg = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "nuke_bgm.ogg"); string expPathMp3 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "explosive_bgm.mp3"); string expPathWav = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "explosive_bgm.wav"); string expPathOgg = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "explosive_bgm.ogg"); string finalPath = null; AudioType audioType = (AudioType)13; if (File.Exists(bgmPathMp3)) { finalPath = bgmPathMp3; audioType = (AudioType)13; } else if (File.Exists(bgmPathOgg)) { finalPath = bgmPathOgg; audioType = (AudioType)14; } else if (File.Exists(bgmPathWav)) { finalPath = bgmPathWav; audioType = (AudioType)20; } AudioClip nukeClip = null; if (finalPath != null) { UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file:///" + finalPath.Replace("\\", "/"), audioType); try { yield return www.SendWebRequest(); if (!www.isNetworkError && !www.isHttpError) { nukeClip = DownloadHandlerAudioClip.GetContent(www); } } finally { ((IDisposable)www)?.Dispose(); } } string expFinalPath = null; AudioType expAudioType = (AudioType)13; if (File.Exists(expPathMp3)) { expFinalPath = expPathMp3; expAudioType = (AudioType)13; } else if (File.Exists(expPathOgg)) { expFinalPath = expPathOgg; expAudioType = (AudioType)14; } else if (File.Exists(expPathWav)) { expFinalPath = expPathWav; expAudioType = (AudioType)20; } AudioClip expClip = null; if (expFinalPath != null) { UnityWebRequest www2 = UnityWebRequestMultimedia.GetAudioClip("file:///" + expFinalPath.Replace("\\", "/"), expAudioType); try { yield return www2.SendWebRequest(); if (!www2.isNetworkError && !www2.isHttpError) { expClip = DownloadHandlerAudioClip.GetContent(www2); } } finally { ((IDisposable)www2)?.Dispose(); } } GameObject bgmObj = null; AudioSource audioSource = null; if ((Object)(object)nukeClip != (Object)null) { bgmObj = new GameObject("NukeBGM"); Object.DontDestroyOnLoad((Object)(object)bgmObj); audioSource = bgmObj.AddComponent(); audioSource.clip = nukeClip; audioSource.loop = true; audioSource.ignoreListenerVolume = true; audioSource.volume = 1f; if (isResume) { audioSource.time = elapsed; } audioSource.Play(); } GameObject canvasObj = null; Image[] borders = null; if (Plugin.EnableNukeWarningUI.Value) { canvasObj = new GameObject("NukeCanvas"); Object.DontDestroyOnLoad((Object)(object)canvasObj); Canvas canvas = canvasObj.AddComponent(); canvas.renderMode = (RenderMode)0; canvas.sortingOrder = 9999; float borderThickness = 30f; GameObject topObj = new GameObject("TopBorder"); topObj.transform.SetParent(canvasObj.transform, false); Image topImg = topObj.AddComponent(); ((Graphic)topImg).rectTransform.anchorMin = new Vector2(0f, 1f); ((Graphic)topImg).rectTransform.anchorMax = new Vector2(1f, 1f); ((Graphic)topImg).rectTransform.pivot = new Vector2(0.5f, 1f); ((Graphic)topImg).rectTransform.offsetMin = new Vector2(0f, 0f - borderThickness); ((Graphic)topImg).rectTransform.offsetMax = new Vector2(0f, 0f); GameObject bottomObj = new GameObject("BottomBorder"); bottomObj.transform.SetParent(canvasObj.transform, false); Image bottomImg = bottomObj.AddComponent(); ((Graphic)bottomImg).rectTransform.anchorMin = new Vector2(0f, 0f); ((Graphic)bottomImg).rectTransform.anchorMax = new Vector2(1f, 0f); ((Graphic)bottomImg).rectTransform.pivot = new Vector2(0.5f, 0f); ((Graphic)bottomImg).rectTransform.offsetMin = new Vector2(0f, 0f); ((Graphic)bottomImg).rectTransform.offsetMax = new Vector2(0f, borderThickness); GameObject leftObj = new GameObject("LeftBorder"); leftObj.transform.SetParent(canvasObj.transform, false); Image leftImg = leftObj.AddComponent(); ((Graphic)leftImg).rectTransform.anchorMin = new Vector2(0f, 0f); ((Graphic)leftImg).rectTransform.anchorMax = new Vector2(0f, 1f); ((Graphic)leftImg).rectTransform.pivot = new Vector2(0f, 0.5f); ((Graphic)leftImg).rectTransform.offsetMin = new Vector2(0f, 0f); ((Graphic)leftImg).rectTransform.offsetMax = new Vector2(borderThickness, 0f); GameObject rightObj = new GameObject("RightBorder"); rightObj.transform.SetParent(canvasObj.transform, false); Image rightImg = rightObj.AddComponent(); ((Graphic)rightImg).rectTransform.anchorMin = new Vector2(1f, 0f); ((Graphic)rightImg).rectTransform.anchorMax = new Vector2(1f, 1f); ((Graphic)rightImg).rectTransform.pivot = new Vector2(1f, 0.5f); ((Graphic)rightImg).rectTransform.offsetMin = new Vector2(0f - borderThickness, 0f); ((Graphic)rightImg).rectTransform.offsetMax = new Vector2(0f, 0f); borders = (Image[])(object)new Image[4] { topImg, bottomImg, leftImg, rightImg }; } FieldInfo bgmField = typeof(SoundManager).GetField("_backgroundMusic", BindingFlags.Instance | BindingFlags.NonPublic); AudioSource gameBgm = null; bool wasMuted = false; if (bgmField != null && (Object)Singleton.Instance != (Object)null) { gameBgm = (AudioSource)bgmField.GetValue(Singleton.Instance); if ((Object)(object)gameBgm != (Object)null) { wasMuted = gameBgm.mute; gameBgm.mute = true; } } bool wasBossRushMuted = false; if ((Object)(object)_bossRushAudioSource != (Object)null) { wasBossRushMuted = _bossRushAudioSource.mute; _bossRushAudioSource.mute = true; } int lastAlert = 90; while (elapsed < duration && _isNukeActive) { elapsed = (_nukeElapsed = elapsed + Time.unscaledDeltaTime); if (Time.frameCount % 60 == 0) { ChzzkStatManager.Save(); } if ((Object)Map.Instance != (Object)null && (Object)Map.Instance != (Object)currentMap) { scenesPassed = (_nukeScenesPassed = scenesPassed + 1); ChzzkStatManager.Save(); currentMap = Map.Instance; } int remaining = Mathf.CeilToInt(duration - elapsed); Color borderColor = ((scenesPassed >= 3) ? new Color(1f, 0.3f, 0.3f, 0.4f) : ((remaining > 20) ? new Color(1f, 0f, 0f, 0.6f) : new Color(0f, 0f, 0f, 0.8f))); if (borders != null) { borderColor.a += 0.15f * Mathf.Sin(elapsed * 8f); Image[] array = borders; foreach (Image img in array) { ((Graphic)img).color = borderColor; } } if (remaining % 10 == 0 && remaining != lastAlert && remaining <= 30 && remaining > 5) { lastAlert = remaining; if (Plugin.EnableNukeWarningText.Value) { ShowFloatingText($"핵폭발 1차 경고: {remaining}초 전!"); } } else if (remaining <= 5 && remaining > 0 && remaining != lastAlert) { lastAlert = remaining; if (Plugin.EnableNukeWarningText.Value) { ShowFloatingText($"핵폭발 카운트다운: {remaining}"); } } yield return null; } bool escaped = scenesPassed >= 3; _irradiatedMap = Map.Instance; if (IsBossRushActive) { if (_bossRushCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_bossRushCoroutine); _bossRushCoroutine = null; } if ((Object)(object)_bossRushAudioSource != (Object)null) { _bossRushAudioSource.Stop(); } IsBossRushActive = false; Plugin.Log.LogInfo((object)"[Nuke] Boss Rush terminated by Nuke Explosion."); } if (escaped) { Plugin.Log.LogInfo((object)"[Nuke] Detonated! Player escaped, only enemies take damage."); ShowFloatingText("핵폭발! 탈출에 성공하여 여파로 몬스터들이 타격을 입습니다."); } else { Plugin.Log.LogInfo((object)"[Nuke] Detonated! Player failed to escape."); ShowFloatingText($"시간 초과! (통과한 맵: {scenesPassed}/3) 핵폭발에 휘말립니다."); Character player = GetPlayer(); if ((Object)player != (Object)null) { ((Health)player.health).TryKill(); } } if ((Object)Map.Instance != (Object)null) { List enemies = Map.Instance.waveContainer.GetAllSpawnedEnemies(); foreach (Character e in enemies) { if ((Object)e != (Object)null && !((Health)e.health).dead) { bool isBoss = (int)e.type == 3 || (int)e.type == 2 || (int)e.type == 1; ApplyNukeDamage(e, isBoss); } } } if ((Object)(object)expClip != (Object)null) { if ((Object)(object)audioSource != (Object)null) { audioSource.Stop(); } if ((Object)(object)audioSource == (Object)null) { bgmObj = new GameObject("NukeBGM"); Object.DontDestroyOnLoad((Object)(object)bgmObj); audioSource = bgmObj.AddComponent(); audioSource.ignoreListenerVolume = true; } audioSource.clip = expClip; audioSource.loop = false; audioSource.volume = 1f; audioSource.pitch = 0.5f; audioSource.Play(); yield return (object)new WaitForSeconds(expClip.length / 0.5f); } else if ((Object)(object)audioSource != (Object)null) { audioSource.loop = false; while (audioSource.isPlaying) { yield return null; } } if ((Object)(object)bgmObj != (Object)null) { Object.Destroy((Object)(object)bgmObj, 5f); } if ((Object)(object)canvasObj != (Object)null) { Object.Destroy((Object)(object)canvasObj); } float restoreTimer2 = 0f; while (restoreTimer2 < 2f) { restoreTimer2 += Time.unscaledDeltaTime; yield return null; } if ((Object)gameBgm != (Object)null && (Object)(object)_irradiatedMap == (Object)null) { gameBgm.mute = wasMuted; } if ((Object)(object)_bossRushAudioSource != (Object)null) { _bossRushAudioSource.mute = wasBossRushMuted; } if ((Object)(object)nukeClip != (Object)null) { Object.Destroy((Object)(object)nukeClip); } if ((Object)(object)expClip != (Object)null) { Object.Destroy((Object)(object)expClip); } _isNukeActive = false; _nukeScenesPassed = 0; ChzzkStatManager.Save(); } private void DoRandomStat(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } Kind[] array = (Kind[])(object)new Kind[8] { Kind.AttackDamage, Kind.PhysicalAttackDamage, Kind.MagicAttackDamage, Kind.AttackSpeed, Kind.MovementSpeed, Kind.CriticalChance, Kind.CriticalDamage, Kind.Health }; string[] array2 = new string[8] { "모든 공격력", "물리 공격력", "마법 공격력", "공격 속도", "이동 속도", "치명타 확률", "치명타 데미지", "최대 체력" }; int num = _random.Next(array.Length); Kind val = array[num]; string text = array2[num]; bool flag = _random.Next(2) == 0; float num2 = (flag ? 0.1f : (-0.1f)); string text2 = (flag ? "증가" : "감소"); string text3 = (flag ? "축복" : "저주"); try { if (val == Kind.Health) { double num3 = (flag ? 30.0 : (-30.0)); if (!flag && ((Health)player.health).maximumHealth + num3 <= 0.0) { num3 = 0.0 - (((Health)player.health).maximumHealth - 1.0); } ChzzkStatManager.AddStat(player, Category.Constant, val, num3); ShowFloatingText($"{nickname}이(가) {text3}을 내렸어요! {text} {Math.Abs(num3)} {text2}!"); } else { ChzzkStatManager.AddStat(player, Category.PercentPoint, val, (double)num2); ShowFloatingText(nickname + "이(가) " + text3 + "을 내렸어요! " + text + " 10% " + text2 + "!"); } } catch { ShowFloatingText(nickname + "의 스탯 조작이 빗나갔어요!"); } } private void DoHeal(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } int num = _random.Next(1, 101); if (num <= 30) { double currentHealth = ((Health)player.health).currentHealth; double maximumHealth = ((Health)player.health).maximumHealth; double num2 = maximumHealth * 0.10000000149011612; if (currentHealth - num2 < 1.0) { num2 = currentHealth - 1.0; } if (num2 > 0.0) { Type type = ((object)player.health).GetType(); FieldInfo fieldInfo = type.GetField("_currentHealth", BindingFlags.Instance | BindingFlags.NonPublic) ?? type.GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo != null) { fieldInfo.SetValue(player.health, currentHealth - num2); ShowFloatingText($"{nickname}이(가) 독약을 선물했어요! -{num2:F0}"); } else { ShowFloatingText(nickname + "이(가) 독약을 선물했지만 간신히 버텼어요!"); } } else { ShowFloatingText(nickname + "이(가) 독약을 선물했지만 간신히 버텼어요!"); } } else { double num3 = ((Health)player.health).PercentHeal(0.1f); ShowFloatingText($"{nickname}이(가) 힐을 선물했어요! +{num3:F0}"); } DoBuffOrCurse(nickname); } private IEnumerator DoQuintessenceCoroutine(string nickname) { Character player = GetPlayer(); if ((Object)player == (Object)null) { yield break; } Rarity rarity = (Rarity)0; Service service = GetService(); object obj; if ((Object)(object)service == (Object)null) { obj = null; } else { GearManager gearManager = service.gearManager; obj = (((Object)(object)gearManager != (Object)null) ? gearManager.GetQuintessenceToTake(rarity) : null); } EssenceReference quintessenceRef = (EssenceReference)obj; if (quintessenceRef == null) { yield break; } EssenceRequest request = quintessenceRef.LoadAsync(); while (!((Request)(object)request).isDone) { yield return null; } Service service2 = GetService(); if ((Object)(object)service2 != (Object)null) { LevelManager levelManager = service2.levelManager; if ((Object)(object)levelManager != (Object)null) { levelManager.DropQuintessence(request, ((Component)player).transform.position + Vector3.up * 1f); } } ShowFloatingText(nickname + "님이 정수를 소환했습니다!"); } private void DoBuffOrCurse(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } SavableAbilityManager component = ((Component)player).GetComponent(); if ((Object)component == (Object)null) { return; } int num = _random.Next(1, 101); if (num <= 70) { string text; switch (_random.Next(13)) { case 0: component.Apply((Name)1, 1f); text = "안개늑대(FogWolf) 버프"; break; case 1: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.MovementSpeed, 0.2); text = "자상(프라이드): 이동속도 +20%"; break; case 2: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.AttackDamage, 0.15); text = "시기(에비): 공격력 +15%"; break; case 3: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.AttackSpeed, 0.15); text = "분노(래스): 공격속도 +15%"; break; case 4: { double num2 = ((Health)player.health).PercentHeal(0.15f); text = $"탐식(글러토니): 체력 +{num2:F0} 회복"; break; } case 5: component.Apply((Name)6, 20f); text = "게으름(슬로스): 방어막 획득"; break; case 6: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.CriticalChance, 0.1); text = "색욕(러스트): 치명타 +10%"; break; case 7: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.PhysicalAttackDamage, 0.15); text = "탐욕(그리드): 물리공격력 +15%"; break; case 8: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.CriticalChance, 0.1); text = "FogWolf: 치명타 확률 +10%"; break; case 9: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.Health, 0.1); text = "FogWolf: 최대체력 +10%"; break; case 10: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.PhysicalAttackDamage, 0.15); text = "FogWolf: 물리공격력 +15%"; break; case 11: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.MagicAttackDamage, 0.15); text = "FogWolf: 마법공격력 +15%"; break; default: ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.PhysicalAttackDamage, 1.0); ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.MagicAttackDamage, 1.0); ChzzkStatManager.AddStat(player, Category.Percent, Kind.TakingDamage, 0.5); text = "저주의 상자: 공격력+100%, 받는피해+50%"; break; } ShowFloatingText(nickname + "이(가) " + text + " 버프를 선물했어요!"); } else { component.Apply((Name)0, 1f); ShowFloatingText(nickname + "이(가) 신의 은총을 선물해주셨습니다!"); } } private void DoCursedChestBuff(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Character player = GetPlayer(); if (!((Object)player == (Object)null)) { ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.PhysicalAttackDamage, 1.0); ChzzkStatManager.AddStat(player, Category.PercentPoint, Kind.MagicAttackDamage, 1.0); ChzzkStatManager.AddStat(player, Category.Percent, Kind.TakingDamage, 0.5); ShowFloatingText(nickname + "이(가) 저주의 상자를 열었어요! [공격력+100%, 받는피해+50%]"); } } private IEnumerator DoItemCoroutine(string nickname, string arg = "") { Character player = GetPlayer(); if ((Object)player == (Object)null) { yield break; } ItemReference itemRef = null; if (!string.IsNullOrEmpty(arg)) { List allVanillaItems = new List(); if (GearResource.instance._items != null) { allVanillaItems.AddRange(GearResource.instance._items); } try { FieldInfo dlcItemsField = AccessTools.Field(typeof(GearResource), "_dlcItems"); if (dlcItemsField != null && dlcItemsField.GetValue(GearResource.instance) is List dlcList) { allVanillaItems.AddRange(dlcList); } } catch { } foreach (ItemReference item in allVanillaItems) { CustomItemReference ci = (CustomItemReference)(object)((item is CustomItemReference) ? item : null); if (ci != null) { if (ci.itemName_KR.Equals(arg, StringComparison.OrdinalIgnoreCase) || ci.itemName_EN.Equals(arg, StringComparison.OrdinalIgnoreCase) || ci.name.Equals(arg, StringComparison.OrdinalIgnoreCase) || ci.name.Equals("Custom-" + arg, StringComparison.OrdinalIgnoreCase)) { itemRef = (ItemReference)(object)ci; break; } continue; } string localizedName = Localization.GetLocalizedString(((GearReference)item).displayNameKey); if (!localizedName.Equals(arg, StringComparison.OrdinalIgnoreCase) && !((GearReference)item).name.Equals(arg, StringComparison.OrdinalIgnoreCase)) { continue; } itemRef = item; break; } if (itemRef != null) { Service service2 = GetService(); if ((Object)(object)service2 != (Object)null) { ItemRequest request2 = itemRef.LoadAsync(); while (!((Request)(object)request2).isDone) { yield return null; } int randDrop2 = _random.Next(1, 101); Item drop2 = Singleton.Instance.levelManager.DropItem(request2, ((Component)player).transform.position); CustomItemReference customItem = (CustomItemReference)(object)((itemRef is CustomItemReference) ? itemRef : null); string displayName2 = ((customItem != null) ? customItem.itemName : Localization.GetLocalizedString(((GearReference)itemRef).displayNameKey)); if (randDrop2 <= (int)Plugin.ItemAutoEquipChance.Value && player.playerComponents.inventory.item.items.Count((Item val) => (Object)val != (Object)null) < (CustomGearsPatch.HasErrorCreator() ? 50 : 9)) { player.playerComponents.inventory.item.TryEquip(drop2); ShowFloatingText(nickname + "이(가) 인벤토리에 [" + displayName2 + "] 아이템을 꽂아줬어요!"); } else if (randDrop2 <= (int)Plugin.ItemAutoEquipChance.Value) { ShowFloatingText(nickname + "이(가) 인벤토리가 꽉차서 [" + displayName2 + "] 아이템을 바닥에 떨궜어요!"); } else { ShowFloatingText(nickname + "이(가) [" + displayName2 + "] 아이템을 선물했어요!"); } yield break; } } else { ShowFloatingText("[" + arg + "] 아이템을 찾을 수 없어 무작위 아이템을 지급합니다."); } } int roll10000 = _random.Next(1, 10001); if (roll10000 <= (int)(Plugin.ItemEmptyChance.Value * 100f)) { Inventory inventory = player.playerComponents.inventory; if (inventory == null || inventory.item.items.Count <= 0) { yield break; } int count = 0; for (int i = inventory.item.items.Count - 1; i >= 0; i--) { Item item2 = inventory.item.items[i]; if ((Object)(object)item2 != (Object)null && (Object)(object)((Component)item2).GetComponent() == (Object)null) { inventory.item.Remove(item2); count++; } } if (count > 0) { ShowFloatingText(nickname + "이(가) 인벤토리의 모든 일반 아이템을 비웠어요! (0.01% 기적)"); } else { ShowFloatingText(nickname + "이(가) 인벤토리를 비우려 했으나 비울 수 있는 일반 아이템이 없네요!"); } yield break; } int roll10001 = _random.Next(1, 101); if (roll10001 <= (int)Plugin.ItemDeleteChance.Value) { Inventory inventory2 = player.playerComponents.inventory; if (inventory2 != null) { List nonGlitchedItems = inventory2.item.items.Where((Item val) => (Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent() == (Object)null).ToList(); if (nonGlitchedItems.Count > 0) { int randomIndex = _random.Next(nonGlitchedItems.Count); Item itemToRemove = nonGlitchedItems[randomIndex]; inventory2.item.Remove(itemToRemove); ShowFloatingText(nickname + "이(가) 인벤토리에서 아이템을 파괴했어요!"); } else { ShowFloatingText(nickname + "이(가) 아이템 파괴를 시도했으나 파괴할 수 있는 일반 아이템이 없네요!"); } } yield break; } Service service3 = GetService(); if ((Object)service3 == (Object)null) { yield break; } Rarity rarity = PickWeightedRarity(); int omenRoll = _random.Next(1, 101); if (omenRoll <= (int)Plugin.ItemOmenChance.Value) { FieldInfo itemsField = ((object)service3.gearManager).GetType().GetField("_items", BindingFlags.Instance | BindingFlags.NonPublic) ?? ((object)service3.gearManager).GetType().GetField("items", BindingFlags.Instance | BindingFlags.Public); IEnumerable allItems = default(IEnumerable); int num; if (itemsField != null) { object value = itemsField.GetValue(service3.gearManager); allItems = value as IEnumerable; num = ((allItems != null) ? 1 : 0); } else { num = 0; } if (num != 0) { List omenItems = allItems.Where((ItemReference val) => (int)val.prefabKeyword1 == 34 || (int)val.prefabKeyword2 == 34).ToList(); if (omenItems.Count > 0) { itemRef = omenItems[_random.Next(omenItems.Count)]; } } } if (itemRef == null) { itemRef = service3.gearManager.GetItemToTake(rarity); } if (itemRef == null) { itemRef = service3.gearManager.GetItemToTake((Rarity)0); } if (itemRef != null) { ItemRequest request3 = itemRef.LoadAsync(); while (!((Request)(object)request3).isDone) { yield return null; } int randDrop3 = _random.Next(1, 101); Item drop3 = Singleton.Instance.levelManager.DropItem(request3, ((Component)player).transform.position); CustomItemReference customItem2 = (CustomItemReference)(object)((itemRef is CustomItemReference) ? itemRef : null); string displayName3 = ((customItem2 != null) ? customItem2.itemName : Localization.GetLocalizedString(((GearReference)itemRef).displayNameKey)); if (randDrop3 <= (int)Plugin.ItemAutoEquipChance.Value && player.playerComponents.inventory.item.items.Count((Item val) => (Object)val != (Object)null) < (CustomGearsPatch.HasErrorCreator() ? 50 : 9)) { player.playerComponents.inventory.item.TryEquip(drop3); ShowFloatingText(nickname + "이(가) 인벤토리에 [" + displayName3 + "] 아이템을 꽂아줬어요!"); } else if (randDrop3 <= (int)Plugin.ItemAutoEquipChance.Value) { ShowFloatingText(nickname + "이(가) 인벤토리가 꽉차서 [" + displayName3 + "] 아이템을 바닥에 떨궜어요!"); } else { ShowFloatingText(nickname + "이(가) [" + displayName3 + "] 아이템을 선물했어요!"); } } } private IEnumerator DoFragmentCoroutine(string nickname) { Service service = GetService(); if ((Object)service == (Object)null) { yield break; } Character player = GetPlayer(); if ((Object)player == (Object)null) { yield break; } if (Random.value < 0.5f) { DoFragmentDelete(nickname); yield break; } string[] fragments = new string[9] { "VertebraOfDisbelief", "SolitarySternum", "RibsOfTerror", "TerriblePelvis", "FemurOfDespair", "JealousTibia", "ScapularsOfHatred", "HumerusOfFury", "ResentfulCollarbone" }; string chosen = fragments[Random.Range(0, fragments.Length)]; string targetKey = null; foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object keyObj in locator.Keys) { string k = keyObj.ToString(); if (k.IndexOf(chosen, StringComparison.OrdinalIgnoreCase) >= 0 && k.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase) && (targetKey == null || k.Contains("Gear/"))) { targetKey = k; } } } if (targetKey != null) { AsyncOperationHandle op = Addressables.LoadAssetAsync((object)targetKey); yield return op; if ((int)op.Status == 1) { GameObject prefab = op.Result; if ((Object)prefab != (Object)null) { Item itemComponent = prefab.GetComponent(); if ((Object)itemComponent != (Object)null) { service.levelManager.DropItem(itemComponent, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "님이 파편을 소환했습니다!"); yield break; } Weapon weapon = prefab.GetComponent(); if ((Object)weapon != (Object)null) { service.levelManager.DropWeapon(weapon, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "님이 파편 장비를 소환했습니다!"); yield break; } Quintessence quint = prefab.GetComponent(); if ((Object)quint != (Object)null) { service.levelManager.DropQuintessence(quint, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "님이 파편 정수를 소환했습니다!"); yield break; } Fragment fragment = prefab.GetComponent(); if ((Object)fragment != (Object)null) { service.levelManager.DropFragment(fragment, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "님이 파편을 소환했습니다!"); } else { ShowFloatingText("파편 소환 실패: 아이템/장비/정수/파편 아님! " + targetKey); } } else { ShowFloatingText("파편 소환 실패: 프리팹 Null! " + targetKey); } } else { ShowFloatingText("파편 소환 실패: 에셋 로드 실패! " + targetKey); } } else { ShowFloatingText("파편 소환 실패!"); } } private void DoFragmentDelete(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Character player = GetPlayer(); if (!((Object)player == (Object)null)) { Inventory inventory = player.playerComponents.inventory; if (inventory != null && (Object)(object)inventory.fragment != (Object)null && inventory.fragment.fragments.Count > 0) { int num = _random.Next(inventory.fragment.fragments.Count); inventory.fragment.Remove(num); ShowFloatingText(nickname + "님이 파편을 삭제했습니다!"); } else { ShowFloatingText(nickname + "님의 파편 삭제 시도! (파편이 없네요)"); } } } private IEnumerator DoSkullCoroutine(string nickname, string arg = "") { Service service = GetService(); if ((Object)service == (Object)null) { yield break; } Character player = GetPlayer(); if ((Object)player == (Object)null) { yield break; } WeaponReference weaponRef = null; if (!string.IsNullOrEmpty(arg)) { WeaponReference[] weapons = GearResource.instance._weapons; foreach (WeaponReference weapon in weapons) { CustomWeaponReference cw = (CustomWeaponReference)(object)((weapon is CustomWeaponReference) ? weapon : null); if (cw != null) { if (cw.weaponName_KR.Equals(arg, StringComparison.OrdinalIgnoreCase) || cw.weaponName_EN.Equals(arg, StringComparison.OrdinalIgnoreCase) || cw.name.Equals(arg, StringComparison.OrdinalIgnoreCase) || cw.name.Equals("Custom-" + arg, StringComparison.OrdinalIgnoreCase)) { weaponRef = (WeaponReference)(object)cw; break; } continue; } string localizedName = Localization.GetLocalizedString(((GearReference)weapon).displayNameKey); if (localizedName.Equals(arg, StringComparison.OrdinalIgnoreCase) || ((GearReference)weapon).name.Equals(arg, StringComparison.OrdinalIgnoreCase)) { weaponRef = weapon; break; } } if (weaponRef != null) { WeaponRequest request2 = weaponRef.LoadAsync(); while (!((Request)(object)request2).isDone) { yield return null; } int actionRoll2 = _random.Next(1, 101); CustomWeaponReference customSkull = (CustomWeaponReference)(object)((weaponRef is CustomWeaponReference) ? weaponRef : null); string displayName = ((customSkull != null) ? customSkull.weaponName_KR : Localization.GetLocalizedString(((GearReference)weaponRef).displayNameKey)); int replaceChance2 = (int)Plugin.SkullReplaceChance.Value; int deleteChance2 = (int)Plugin.SkullDeleteChance.Value; if (actionRoll2 <= replaceChance2) { TryDeleteSubSkull(); service.levelManager.DropWeapon(request2, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "이(가) 보조 스컬을 [" + displayName + "] 스컬로 강제 교체했어요!"); } else if (actionRoll2 <= replaceChance2 + deleteChance2) { if (TryDeleteSubSkull()) { ShowFloatingText(nickname + "이(가) 보조 스컬을 빼앗아갔어요!"); } else { ShowFloatingText(nickname + "이(가) 보조 스컬을 뺏으려다 불발됐어요!"); } } else { service.levelManager.DropWeapon(request2, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "이(가) [" + displayName + "] 스컬을 선물했어요!"); } yield break; } ShowFloatingText("[" + arg + "] 스컬을 찾을 수 없어 무작위 스컬을 지급합니다."); } int roll = _random.Next(1, 1001); if (roll <= (int)(Plugin.SkullSuperChance.Value * 10f)) { AsyncOperationHandle op = Addressables.LoadAssetAsync((object)"Assets/Gear/Weapons/Skul_Super/Skul_Super.prefab"); while (!op.IsDone) { yield return null; } if ((int)op.Status == 1) { GameObject prefab = op.Result; if ((Object)prefab != (Object)null) { Weapon superSkulPrefab = prefab.GetComponent(); if ((Object)superSkulPrefab != (Object)null) { service.levelManager.DropWeapon(superSkulPrefab, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "님이 강화된 스컬을 소환했습니다!!"); yield break; } } } } if (roll <= (int)(Plugin.SkullSuperChance.Value * 10f) + (int)(Plugin.SkullEvolveChance.Value * 10f)) { Weapon currentWeapon = player.playerComponents.inventory.weapon.polymorphOrCurrent; if ((Object)currentWeapon != (Object)null && (int)((Gear)currentWeapon).rarity != 3 && currentWeapon.nextLevelReference != null && !string.IsNullOrEmpty(((GearReference)currentWeapon.nextLevelReference).name)) { weaponRef = currentWeapon.nextLevelReference; } } if (weaponRef == null) { Rarity rarity = PickWeightedRarity(); weaponRef = service.gearManager.GetWeaponToTake(rarity); if (weaponRef == null) { weaponRef = service.gearManager.GetWeaponToTake((Rarity)0); } } if (weaponRef == null) { yield break; } WeaponRequest request3 = weaponRef.LoadAsync(); while (!((Request)(object)request3).isDone) { yield return null; } int actionRoll3 = _random.Next(1, 101); int replaceChance3 = (int)Plugin.SkullReplaceChance.Value; int deleteChance3 = (int)Plugin.SkullDeleteChance.Value; CustomWeaponReference customSkullMain = (CustomWeaponReference)(object)((weaponRef is CustomWeaponReference) ? weaponRef : null); string displayNameMain = ((customSkullMain != null) ? customSkullMain.weaponName_KR : Localization.GetLocalizedString(((GearReference)weaponRef).displayNameKey)); if (actionRoll3 <= replaceChance3) { TryDeleteSubSkull(); service.levelManager.DropWeapon(request3, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "이(가) 보조 스컬을 [" + displayNameMain + "] 스컬로 강제 교체했어요!"); } else if (actionRoll3 <= replaceChance3 + deleteChance3) { if (TryDeleteSubSkull()) { ShowFloatingText(nickname + "이(가) 보조 스컬을 빼앗아갔어요!"); } else { ShowFloatingText(nickname + "이(가) 보조 스컬을 뺏으려다 불발됐어요!"); } } else { service.levelManager.DropWeapon(request3, ((Component)player).transform.position + Vector3.up); ShowFloatingText(nickname + "이(가) [" + displayNameMain + "] 스컬을 선물했어요!"); } } private void DoSynergy(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Invalid comparison between Unknown and I4 //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Invalid comparison between Unknown and I4 //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } Inventory inventory = player.playerComponents.inventory; if (inventory == null || (Object)inventory.synergy == (Object)null || inventory.synergy.inscriptions == null) { return; } Synergy synergy = inventory.synergy; List list = new List(); List list2 = new List(); if (Inscription.keys != null) { foreach (Key key in Inscription.keys) { if ((int)key != 0 && (int)key != 35 && (PluginItems.IsModActive || (int)key != 37)) { if (synergy.inscriptions[key].count > 0) { list.Add(key); } else { list2.Add(key); } } } } int num = _random.Next(1, 101); string text = ""; Key val; if (num <= 50 && list.Count > 0) { val = list[_random.Next(list.Count)]; text = "강화"; } else { if (list2.Count <= 0) { ShowFloatingText(nickname + "의 각인 조작 시도! 하지만 실패했어요."); return; } val = list2[_random.Next(list2.Count)]; text = "추가"; } Inscription val2 = synergy.inscriptions[val]; val2.bonusCount++; if (text == "강화") { CustomSuperInscriptions.Add(val); ChzzkStatManager.Save(); } inventory.UpdateSynergy(); ShowFloatingText($"{nickname}이(가) [{val}] 각인을 {text}했어요!"); } private void DoOmen(string nickname) { DoChestSpawn(nickname, isOmen: true); } private void DoDropOmen(string nickname) { DoChestSpawn(nickname, isOmen: true); } private void DoBossRush(string nickname, bool isResume = false) { if (_bossRushCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_bossRushCoroutine); } _bossRushCoroutine = ((MonoBehaviour)this).StartCoroutine(BossRushRoutine(nickname, isResume)); } private string GetBossRushModeName() { string path = Path.Combine(Paths.PluginPath, "ChzzkSkul", "bossrush_bgm.mp3"); string path2 = Path.Combine(Paths.PluginPath, "ChzzkSkul", "godrush_bgm.mp3"); if (!File.Exists(path) && File.Exists(path2)) { return "신의 심판"; } return "보스 러쉬"; } private IEnumerator BossRushRoutine(string nickname, bool isResume = false) { IsBossRushActive = true; string modeName = GetBossRushModeName(); if (isResume) { ShowFloatingText(modeName + " 복구됨!"); } else { ShowFloatingText(nickname + "이(가) " + modeName + " 모드를 발동했어요!"); } ((MonoBehaviour)this).StartCoroutine(SpawnBossRushBosses()); string bgmPath = Path.Combine(Paths.PluginPath, "ChzzkSkul", "bossrush_bgm.mp3"); if (!File.Exists(bgmPath)) { string godRushPath = Path.Combine(Paths.PluginPath, "ChzzkSkul", "godrush_bgm.mp3"); bgmPath = ((!File.Exists(godRushPath)) ? Path.Combine(Paths.PluginPath, "ChzzkSkul", "bossrush_bgm.wav") : godRushPath); } AudioClip clip = null; if (File.Exists(bgmPath)) { string uri = "file:///" + bgmPath.Replace("\\", "/"); UnityWebRequest uwr = UnityWebRequestMultimedia.GetAudioClip(uri, (AudioType)0); try { UnityWebRequestAsyncOperation handle = uwr.SendWebRequest(); while (!((AsyncOperation)handle).isDone) { yield return null; } if ((int)uwr.result == 1) { clip = DownloadHandlerAudioClip.GetContent(uwr); } else { Debug.LogError((object)("[ChzzkGameMode] Failed to load BGM: " + uwr.error)); } } finally { ((IDisposable)uwr)?.Dispose(); } } if ((Object)(object)clip != (Object)null) { if ((Object)(object)_bossRushAudioSource == (Object)null) { _bossRushAudioSource = ((Component)this).gameObject.AddComponent(); } _bossRushAudioSource.clip = clip; _bossRushAudioSource.loop = false; float elapsed = (isResume ? _bossRushElapsed : 0f); if (isResume && elapsed < clip.length) { _bossRushAudioSource.time = elapsed; } _bossRushAudioSource.Play(); FieldInfo bgmField = typeof(SoundManager).GetField("_backgroundMusic", BindingFlags.Instance | BindingFlags.NonPublic); AudioSource gameBgm = null; bool wasMuted = false; if ((Object)Singleton.Instance != (Object)null && bgmField != null) { gameBgm = (AudioSource)bgmField.GetValue(Singleton.Instance); if ((Object)(object)gameBgm != (Object)null) { wasMuted = gameBgm.mute; gameBgm.mute = true; } } float duration = clip.length; while (elapsed < duration && IsBossRushActive) { elapsed = (_bossRushElapsed = elapsed + Time.unscaledDeltaTime); if (Time.frameCount % 60 == 0) { ChzzkStatManager.Save(); } yield return null; } if ((Object)(object)gameBgm != (Object)null) { gameBgm.mute = wasMuted; } } else { Debug.LogWarning((object)"[ChzzkGameMode] bossrush_bgm.wav or .mp3 not found. Defaulting to 180s."); float elapsed2 = (isResume ? _bossRushElapsed : 0f); float duration2 = 180f; while (elapsed2 < duration2 && IsBossRushActive) { elapsed2 = (_bossRushElapsed = elapsed2 + Time.unscaledDeltaTime); if (Time.frameCount % 60 == 0) { ChzzkStatManager.Save(); } yield return null; } } if (IsBossRushActive) { IsBossRushActive = false; ShowFloatingText(modeName + " 모드가 종료되었습니다."); _bossRushElapsed = 0f; ChzzkStatManager.Save(); } if ((Object)(object)_bossRushAudioSource != (Object)null) { _bossRushAudioSource.Stop(); } _lastSpawnedBossRushStage = null; _bossRushCoroutine = null; } private void DoRandomScreenEffect(string nickname) { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_0779: Unknown result type (might be due to invalid IL or missing references) //IL_0784: Expected O, but got Unknown //IL_060d: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Expected O, but got Unknown //IL_062e: Unknown result type (might be due to invalid IL or missing references) //IL_0638: Expected O, but got Unknown //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Expected O, but got Unknown //IL_078c: Unknown result type (might be due to invalid IL or missing references) //IL_0796: Expected O, but got Unknown //IL_068d: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Expected O, but got Unknown //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_0722: Unknown result type (might be due to invalid IL or missing references) //IL_072f: Unknown result type (might be due to invalid IL or missing references) //IL_073c: Unknown result type (might be due to invalid IL or missing references) _screenEffectType = _random.Next(13); _screenEffectTimer = 20f; IsScreenEffectActive = true; string text = ""; if (_screenEffectType == 0) { text = "화면 뒤집기"; } else if (_screenEffectType == 1) { text = "화면 우측 기울이기"; } else if (_screenEffectType == 2) { text = "화면 좌측 기울이기"; } else if (_screenEffectType == 3) { text = "색조 반전"; } else if (_screenEffectType == 4) { text = "흑백 화면"; } else if (_screenEffectType == 5) { text = "낡은 화면"; } else if (_screenEffectType == 6) { text = "CCTV 화면"; } else if (_screenEffectType == 7) { text = "심한 왜곡"; } else if (_screenEffectType == 8) { text = "피의 화면"; } else if (_screenEffectType == 9) { text = "화면 4분할"; } else if (_screenEffectType == 10) { text = "키 반전"; } else if (_screenEffectType == 11) { text = "스킬 1 봉인"; } else if (_screenEffectType == 12) { text = "정수 봉인"; } if (_screenEffectType >= 3 && _screenEffectType <= 8) { if ((Object)_screenEffectVolume == (Object)null) { GameObject val = new GameObject("ChzzkScreenEffectVolume"); val.layer = LayerMask.NameToLayer("PostProcessing"); Object.DontDestroyOnLoad((Object)(object)val); _screenEffectVolume = val.AddComponent(); _screenEffectVolume.isGlobal = true; _screenEffectVolume.priority = 9999f; _screenEffectVolume.profile = ScriptableObject.CreateInstance(); } VolumeProfile profile = _screenEffectVolume.profile; profile.components.Clear(); ((Component)_screenEffectVolume).gameObject.SetActive(true); if (_screenEffectType == 3) { ColorAdjustments val2 = profile.Add(false); ((VolumeParameter)(object)val2.hueShift).Override(180f); ((VolumeParameter)(object)val2.contrast).Override(100f); ColorCurves val3 = profile.Add(false); TextureCurveParameter master = val3.master; Keyframe[] obj = new Keyframe[2] { new Keyframe(0f, 1f), new Keyframe(1f, 0f) }; Vector2 val4 = new Vector2(0f, 1f); ((VolumeParameter)(object)master).Override(new TextureCurve((Keyframe[])(object)obj, 0f, true, ref val4)); } else if (_screenEffectType == 4) { ColorAdjustments val5 = profile.Add(false); ((VolumeParameter)(object)val5.saturation).Override(-100f); } else if (_screenEffectType == 5) { ColorAdjustments val6 = profile.Add(false); ((VolumeParameter)(object)val6.colorFilter).Override(new Color(0.8f, 0.6f, 0.4f, 1f)); ((VolumeParameter)(object)val6.saturation).Override(-40f); FilmGrain val7 = profile.Add(false); ((VolumeParameter)(object)val7.intensity).Override(0.8f); ((VolumeParameter)(object)val7.type).Override((FilmGrainLookup)2); Vignette val8 = profile.Add(false); ((VolumeParameter)(object)val8.intensity).Override(0.45f); ((VolumeParameter)(object)val8.smoothness).Override(0.3f); } else if (_screenEffectType == 6) { ColorAdjustments val9 = profile.Add(false); ((VolumeParameter)(object)val9.colorFilter).Override(new Color(0.4f, 0.6f, 1f, 1f)); ((VolumeParameter)(object)val9.saturation).Override(-30f); FilmGrain val10 = profile.Add(false); ((VolumeParameter)(object)val10.intensity).Override(1f); ((VolumeParameter)(object)val10.type).Override((FilmGrainLookup)8); LensDistortion val11 = profile.Add(false); ((VolumeParameter)(object)val11.intensity).Override(0.5f); ((VolumeParameter)(object)val11.scale).Override(1.1f); ChromaticAberration val12 = profile.Add(false); ((VolumeParameter)(object)val12.intensity).Override(1f); } else if (_screenEffectType == 7) { LensDistortion val13 = profile.Add(false); ((VolumeParameter)(object)val13.intensity).Override(-1f); ((VolumeParameter)(object)val13.scale).Override(0.5f); ChromaticAberration val14 = profile.Add(false); ((VolumeParameter)(object)val14.intensity).Override(1f); PaniniProjection val15 = profile.Add(false); ((VolumeParameter)(object)val15.distance).Override(1f); ((VolumeParameter)(object)val15.cropToFit).Override(1f); } else if (_screenEffectType == 8) { ColorAdjustments val16 = profile.Add(false); ((VolumeParameter)(object)val16.colorFilter).Override(new Color(1f, 0.2f, 0.2f, 1f)); ((VolumeParameter)(object)val16.contrast).Override(30f); Vignette val17 = profile.Add(false); ((VolumeParameter)(object)val17.color).Override(new Color(0.8f, 0f, 0f, 1f)); ((VolumeParameter)(object)val17.intensity).Override(0.6f); ((VolumeParameter)(object)val17.smoothness).Override(0.4f); FilmGrain val18 = profile.Add(false); ((VolumeParameter)(object)val18.intensity).Override(0.5f); } } else if (_screenEffectType == 9) { if ((Object)Camera.main != (Object)null) { _splitScreenRT = new RenderTexture(Screen.width, Screen.height, 24); Camera.main.targetTexture = _splitScreenRT; _splitScreenCanvas = new GameObject("ChzzkSplitScreenCanvas"); Object.DontDestroyOnLoad((Object)(object)_splitScreenCanvas); Canvas val19 = _splitScreenCanvas.AddComponent(); val19.renderMode = (RenderMode)0; val19.sortingOrder = 32767; _splitScreenCanvas.AddComponent(); for (int i = 0; i < 4; i++) { GameObject val20 = new GameObject("SplitImage" + i); val20.transform.SetParent(_splitScreenCanvas.transform, false); RawImage val21 = val20.AddComponent(); val21.texture = (Texture)(object)_splitScreenRT; RectTransform component = val20.GetComponent(); component.anchorMin = new Vector2((i % 2 == 0) ? 0f : 0.5f, (i < 2) ? 0.5f : 0f); component.anchorMax = new Vector2((i % 2 == 0) ? 0.5f : 1f, (i < 2) ? 1f : 0.5f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; } } } else if (_screenEffectType == 10) { Character player = GetPlayer(); if ((Object)player != (Object)null) { _reverseAbility = new ReverseHorizontalInput(); ((Ability)_reverseAbility).duration = 20f; ((Ability)_reverseAbility).Initialize(); player.ability.Add((IAbility)(object)_reverseAbility); } } ShowFloatingText(nickname + "이(가) 랜덤 화면 효과(" + text + ")를 발동했어요! (20초)"); ChzzkStatManager.Save(); } private IEnumerator SpawnBossRushBosses() { if (_isSpawningBossRush) { yield break; } _isSpawningBossRush = true; try { Character player = null; for (int i = 0; i < 40; i++) { player = GetPlayer(); if ((Object)player != (Object)null && (Object)Map.Instance != (Object)null && (Object)Map.Instance.waveContainer != (Object)null) { break; } yield return (object)new WaitForSeconds(0.5f); } if ((Object)player == (Object)null || (Object)Map.Instance == (Object)null || (Object)Map.Instance.waveContainer == (Object)null) { yield break; } string curStage = ((Object)Map.Instance).name; if (curStage.Contains("Castle") || curStage.Contains("Tutorial") || curStage.Contains("Test") || curStage == _lastSpawnedBossRushStage) { yield break; } _lastSpawnedBossRushStage = curStage; Debug.Log((object)("[ChzzkGameMode] Spawning Boss Rush bosses for stage: " + curStage)); List> spawnList = new List>(); string[] main3 = new string[3] { "DarkSkeleton_Phase2", "DarkSkeleton_Phase1", "Emperor4" }; string selectedMain = main3[_random.Next(main3.Length)]; spawnList.Add(new KeyValuePair(selectedMain, value: false)); List otherPool = new List { "ElderEnt(Hardmode)", "Dark", "Emperor_Phase1", "Pope", "Chimera", "First Hero Phase Dark", "LongHair", "ShortHair" }; string selectedOther = otherPool[_random.Next(otherPool.Count)]; spawnList.Add(new KeyValuePair(selectedOther, value: false)); string[] allowedMobs = new string[81] { "CarleonRecruitInCannon", "Hound", "LandWizard", "OldTreeEnt", "AssassinMercenary", "ForestRootKeeper", "CarleonRecruit", "CannonSpecialist", "EntApocalypse", "BD_Chaser", "ThunderCaller", "CarleonManAtArms", "BlossomEnt", "Cannoneer", "Occulist", "Ent", "CarleonAssassin", "GiganticEnt", "GiantMushroomEnt", "Dimensionalist (C1)", "Dimensionalist (C4)", "Butler", "GoldmaneSpearMan", "CarleonGoldRecruit", "WindBand", "GoldManeArcher", "GoldManeGuard", "Maid01", "ChiefMaid", "LordChamberlain", "GoldmaneLowClassWizard", "FireCaerleonLowClassWizard", "Servant", "GoldmaneRecruit", "GoldManeCavalry", "Silentist", "WindBandLeader", "StickySubject_S", "StickySubject_M_0", "StickySubject_M_1", "StickySubject_L", "StickySubject_S_0", "StickySubject_S_1", "Alchemist", "Heart", "Ultimate", "Transcendent", "ToxicAlchemist", "StrangeSubject", "LooseSubject", "PerfectSubject", "BD_HighAlchemist(Summoner)_1", "BD_HighAlchemist(Summoner)_2", "ArmoredGolem", "FanaticRecruit", "Bombardier", "HolyKnightsArcher", "LeoniaOfProtection", "Executioner", "DemonHunter", "Fanatic", "MartyrFanatic", "Moderator", "Awakened", "HolyKnightsMagician", "Wisdom", "Brave", "HereticInquisitor", "HolyKnightsPriest", "HolyKnightsRecruit", "Aged Fanatic", "HighFanatic", "Arbiter", "HolyKnightsManAtArms", "HolyKnightsSpearMan", "Fire", "Escort Orb", "Cross", "Cross (1)", "Cross (2)", "Sentinel" }; for (int j = 0; j < 3; j++) { string randomMob = allowedMobs[_random.Next(allowedMobs.Length)]; spawnList.Add(new KeyValuePair(randomMob, value: true)); } float spawnOffset = -6f; foreach (KeyValuePair spawnTarget in spawnList) { string bossName = spawnTarget.Key; bool isDark = spawnTarget.Value; string foundKey = null; foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object keyObj in locator.Keys) { string k = keyObj.ToString(); if (k.EndsWith(".prefab") && k.Contains("Enemies") && !k.Contains("effect") && !k.Contains("ui")) { string fileName = Path.GetFileNameWithoutExtension(k); if (fileName == bossName) { foundKey = k; break; } } } if (foundKey != null) { break; } } if (foundKey == null) { continue; } AsyncOperationHandle handle = Addressables.InstantiateAsync((object)foundKey, (Transform)null, false, true); yield return handle; if ((int)handle.Status != 1) { continue; } GameObject loadedObj = handle.Result; if (!((Object)(object)loadedObj != (Object)null)) { continue; } Character bossChar = loadedObj.GetComponent(); if (!((Object)bossChar != (Object)null)) { continue; } Vector3 spawnPos = ((Component)player).transform.position + Vector3.right * spawnOffset; if ((Object)Map.Instance != (Object)null) { Bounds bounds = Map.Instance.bounds; float minX = ((Bounds)(ref bounds)).min.x + 2f; bounds = Map.Instance.bounds; float maxX = ((Bounds)(ref bounds)).max.x - 2f; if (minX < maxX) { spawnPos.x = Mathf.Clamp(spawnPos.x, minX, maxX); } } try { float startY = ((Component)player).transform.position.y + 3f; RaycastHit2D[] hits = Physics2D.RaycastAll(new Vector2(spawnPos.x, startY), Vector2.down, 25f); bool foundGround = false; RaycastHit2D[] array = hits; for (int l = 0; l < array.Length; l++) { RaycastHit2D hit = array[l]; if ((Object)(object)((RaycastHit2D)(ref hit)).collider != (Object)null && !((RaycastHit2D)(ref hit)).collider.isTrigger) { spawnPos.y = ((RaycastHit2D)(ref hit)).point.y + 0.1f; foundGround = true; break; } } if (!foundGround) { spawnPos.y = ((Component)player).transform.position.y; } } catch { spawnPos.y = ((Component)player).transform.position.y; } loadedObj.transform.position = spawnPos; spawnOffset += 3f; ((Component)bossChar).gameObject.SetActive(true); if ((Object)(object)bossChar.attach != (Object)null) { bossChar.attach.SetActive(true); } yield return null; if ((Object)bossChar == (Object)null || (Object)player == (Object)null) { continue; } try { FieldInfo listField = typeof(TrueOnlyLogicalSumList).GetField("_list", BindingFlags.Instance | BindingFlags.NonPublic); if (listField != null) { if (bossChar.cinematic != null && listField.GetValue(bossChar.cinematic) is IList list) { list.Clear(); } if (bossChar.invulnerable != null && listField.GetValue(bossChar.invulnerable) is IList list2) { list2.Clear(); } } } catch (Exception ex) { Debug.LogError((object)("[ChzzkGameMode] Error clearing cinematic/invulnerable: " + ex)); } if (isDark) { try { bossChar.stat.AttachValues(new Values((Value[])(object)new Value[3] { new Value(Category.PercentPoint, Kind.PhysicalAttackDamage, -0.9), new Value(Category.PercentPoint, Kind.MagicAttackDamage, -0.9), new Value(Category.PercentPoint, Kind.AttackDamage, -0.9) })); } catch { } if ((Object)(object)bossChar.health != (Object)null) { try { ((Health)bossChar.health).SetCurrentHealth(((Health)bossChar.health).maximumHealth); ((Health)bossChar.health).Heal(999999.0, true); } catch { } } } else { double healthMultiplier = 0.05; try { Service service = Singleton.Instance; if ((Object)(object)service != (Object)null && (Object)(object)service.levelManager != (Object)null && (Object)(object)service.levelManager.currentChapter != (Object)null) { int chapterTypeVal = (int)service.levelManager.currentChapter.type; if (chapterTypeVal == 0) { healthMultiplier = 1.0; } else { double factor = 1.0 + 0.5 * (double)(chapterTypeVal - 1); healthMultiplier = 0.05 * factor; } } } catch { } if (healthMultiplier < 0.0005) { healthMultiplier = 0.0005; } if (healthMultiplier > 2.0) { healthMultiplier = 2.0; } try { bossChar.stat.AttachValues(new Values((Value[])(object)new Value[4] { new Value(Category.PercentPoint, Kind.Health, healthMultiplier - 1.0), new Value(Category.PercentPoint, Kind.PhysicalAttackDamage, -0.9), new Value(Category.PercentPoint, Kind.MagicAttackDamage, -0.9), new Value(Category.PercentPoint, Kind.AttackDamage, -0.9) })); } catch { } if ((Object)(object)bossChar.health != (Object)null) { try { ((Health)bossChar.health).SetCurrentHealth(((Health)bossChar.health).maximumHealth); ((Health)bossChar.health).Heal(999999.0, true); } catch { } } } try { InitializeSpawnedBossAI(bossChar, player); } catch (Exception ex2) { Debug.LogError((object)("[ChzzkGameMode] SpawnBossRushBosses AI 활성화 오류: " + ex2)); } if (!((Object)Map.Instance != (Object)null) || !((Object)Map.Instance.waveContainer != (Object)null)) { continue; } try { Map.Instance.waveContainer.AttachToSummonEnemyWave(bossChar); typeof(EnemyWaveContainer).GetMethod("CheckWaveState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(Map.Instance.waveContainer, null); } catch (Exception ex3) { Exception ex4 = ex3; Debug.LogWarning((object)("[ChzzkGameMode] SpawnBossRushBosses: waveContainer.AttachToSummonEnemyWave 실패: " + ex4.Message)); try { Map.Instance.waveContainer.Attach(bossChar); typeof(EnemyWaveContainer).GetMethod("CheckWaveState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(Map.Instance.waveContainer, null); } catch { } } } } finally { _isSpawningBossRush = false; } } private void DoDarkEnemyForce(string nickname) { ForceNextDarkEnemy = true; _darkEnemyTargetMap = Map.Instance; Debug.Log((object)"[ChzzkGameMode] 스트리머가 검은적 강제 변환 명령어를 사용했습니다."); ShowFloatingText(nickname + " 님의 명령으로 어둠의 기운이 뒤덮습니다... (검은 적 등장!)"); ChzzkStatManager.Save(); } private void MakeDarkEnemy(Character c) { if ((Object)(object)c == (Object)null) { return; } try { object obj = null; PropertyInfo property = typeof(DarkEnemySelector).GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (property != null) { obj = property.GetValue(null, null); } if (obj == null) { FieldInfo field = typeof(DarkEnemySelector).GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (field != null) { obj = field.GetValue(null); } } if (obj == null) { obj = Object.FindObjectOfType(); } if (obj == null) { return; } FieldInfo field2 = typeof(DarkEnemySelector).GetField("_constructors", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 != null && field2.GetValue(obj) is DarkAbilityConstructor[] array) { int currentLevel = Singleton.Instance.currentLevel; if (currentLevel >= 0 && currentLevel < array.Length) { array[currentLevel].Provide(c); } else if (array.Length != 0) { array[^1].Provide(c); } } } catch { } } private void DoDarkAbility(string nickname) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Invalid comparison between Unknown and I4 Character player = GetPlayer(); if ((Object)player == (Object)null) { return; } UpgradeInventory upgrade = player.playerComponents.inventory.upgrade; if ((Object)upgrade == (Object)null) { return; } int num = _random.Next(1, 101); if (num <= 50) { List upgrades = upgrade.upgrades; List list = new List(); for (int i = 0; i < upgrades.Count; i++) { if ((Object)upgrades[i] != (Object)null) { list.Add(i); } } if (list.Count > 0) { int num2 = list[_random.Next(list.Count)]; upgrade.Remove(num2); upgrade.Trim(); ShowFloatingText(nickname + "이(가) 검은 능력을 삭제했어요!"); } else { ShowFloatingText(nickname + "의 파괴 시도! 하지만 능력이 없어요."); } return; } UpgradeManager instance = Singleton.Instance; if (!((Object)instance != (Object)null)) { return; } List collection = instance.GetUnlockList((Type)0) ?? new List(); List collection2 = instance.GetUnlockList((Type)1) ?? new List(); List list2 = new List(); list2.AddRange(collection); list2.AddRange(collection2); if (list2.Count > 0) { Reference val = list2[_random.Next(list2.Count)]; if (upgrade.TryEquip(val)) { string text = (((int)val.type == 1) ? "저주" : "검은 능력"); ShowFloatingText(nickname + "이(가) " + text + "을(를) 추가했어요!"); } else { ShowFloatingText(nickname + "의 부여 시도! 칸이 가득 찼어요."); } } else { ShowFloatingText(nickname + "의 부여 시도! 획득 가능한 능력이 없어요."); } } private void DoBoss(string nickname) { if (IsBossRushActive) { ShowFloatingText("보스 러쉬 중에는 보스를 소환할 수 없습니다!"); return; } Debug.Log((object)("[ChzzkGameMode] DoBoss 호출됨 (nickname: " + nickname + ")")); ((MonoBehaviour)this).StartCoroutine(C_DoBoss(nickname)); } private IEnumerator C_DoBoss(string nickname, bool isRecovery = false) { Debug.Log((object)$"[ChzzkGameMode] C_DoBoss 시작됨: {nickname}, isRecovery: {isRecovery}, SpawnedBossCount: {ChzzkStatManager.SaveData.SpawnedBossCount}"); Character player = GetPlayer(); if ((Object)Map.Instance == (Object)null || (Object)Map.Instance.waveContainer == (Object)null) { Map instance = Map.Instance; Map instance2 = Map.Instance; Debug.LogWarning((object)$"[ChzzkGameMode] C_DoBoss 중단: Map.Instance 또는 waveContainer가 null입니다. Map={instance}, waveContainer={((instance2 != null) ? instance2.waveContainer : null)}"); if (!isRecovery) { SaveWrapper saveData = ChzzkStatManager.SaveData; saveData.SpawnedBossCount++; ChzzkStatManager.Save(); Debug.Log((object)$"[ChzzkGameMode] waveContainer가 null이므로 다음 맵으로 소환을 예약합니다. SpawnedBossCount={ChzzkStatManager.SaveData.SpawnedBossCount}"); ForceNextDarkEnemy = true; _darkEnemyTargetMap = null; ShowFloatingText(nickname + "이(가) 다음 맵을 저주했어요!"); } yield break; } Bounds bounds; if ((Object)player != (Object)null && (Object)Map.Instance != (Object)null) { try { bounds = Map.Instance.bounds; float targetX = ((Bounds)(ref bounds)).center.x; float targetY = ((Component)player).transform.position.y; bounds = Map.Instance.bounds; Vector2 val = new Vector2(targetX, ((Bounds)(ref bounds)).max.y); Vector2 down = Vector2.down; bounds = Map.Instance.bounds; RaycastHit2D[] hits = Physics2D.RaycastAll(val, down, ((Bounds)(ref bounds)).size.y + 20f); RaycastHit2D[] array = hits; for (int i = 0; i < array.Length; i++) { RaycastHit2D hit = array[i]; if ((Object)(object)((RaycastHit2D)(ref hit)).collider != (Object)null && !((RaycastHit2D)(ref hit)).collider.isTrigger) { targetY = ((RaycastHit2D)(ref hit)).point.y + 1f; break; } } ((Component)player).transform.position = new Vector3(targetX, targetY, ((Component)player).transform.position.z); Debug.Log((object)$"[ChzzkGameMode] Player teleported to map center: ({targetX}, {targetY})"); } catch (Exception ex) { Exception ex2 = ex; Debug.LogWarning((object)("[ChzzkGameMode] Player teleport to center failed: " + ex2.Message)); } } List allEnemies = Resources.FindObjectsOfTypeAll().ToList(); HashSet allowedBosses = new HashSet { "ElderEnt(Hardmode)", "First Hero Phase 1", "First Hero Phase 2", "First Hero Phase 3", "ElderEnt", "Dark", "DarkSkeleton_Phase1", "DarkSkeleton_Phase2", "Emperor_Phase1", "Emperor4", "Pope", "Chimera", "First Hero Phase Dark", "LongHair", "ShortHair" }; new HashSet { "Veteran Hero", "Veteran Magician", "Veteran Cleric", "Veteran Thief", "Veteran Archer", "Veteran Warrior" }; HashSet allowedMobs = new HashSet { "CarleonRecruitInCannon", "Hound", "LandWizard", "OldTreeEnt", "AssassinMercenary", "ForestRootKeeper", "CarleonRecruit", "CannonSpecialist", "EntApocalypse", "BD_Chaser", "ThunderCaller", "CarleonManAtArms", "BlossomEnt", "Cannoneer", "Occulist", "Ent", "CarleonAssassin", "GiganticEnt", "GiantMushroomEnt", "Dimensionalist (C1)", "Dimensionalist (C4)", "Butler", "GoldmaneSpearMan", "CarleonGoldRecruit", "WindBand", "GoldManeArcher", "GoldManeGuard", "Maid01", "ChiefMaid", "LordChamberlain", "GoldmaneLowClassWizard", "FireCaerleonLowClassWizard", "Servant", "GoldmaneRecruit", "GoldManeCavalry", "Silentist", "WindBandLeader", "StickySubject_S", "StickySubject_M_0", "StickySubject_M_1", "StickySubject_L", "StickySubject_S_0", "StickySubject_S_1", "Alchemist", "Heart", "Ultimate", "Transcendent", "ToxicAlchemist", "StrangeSubject", "LooseSubject", "PerfectSubject", "BD_HighAlchemist(Summoner)_1", "BD_HighAlchemist(Summoner)_2", "ArmoredGolem", "FanaticRecruit", "Bombardier", "HolyKnightsArcher", "LeoniaOfProtection", "Executioner", "DemonHunter", "Fanatic", "MartyrFanatic", "Moderator", "Awakened", "HolyKnightsMagician", "Wisdom", "Brave", "HereticInquisitor", "HolyKnightsPriest", "HolyKnightsRecruit", "Aged Fanatic", "HighFanatic", "Arbiter", "HolyKnightsManAtArms", "HolyKnightsSpearMan", "Fire", "Escort Orb", "Cross", "Cross (1)", "Cross (2)", "Sentinel" }; _random.Next(100); Type targetType = (Type)3; HashSet targetAllowedNames = allowedBosses; Character original = null; List addressableKeys = new List(); if ((int)targetType == 3 || (int)targetType == 2) { foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object keyObj in locator.Keys) { string k = keyObj.ToString(); if (k.EndsWith(".prefab") && k.Contains("Enemies") && !k.Contains("effect") && !k.Contains("ui")) { string fileName = Path.GetFileNameWithoutExtension(k); if (targetAllowedNames.Contains(fileName)) { addressableKeys.Add(k); } } } } } Character bossChar = null; float bossOffsetX = ((_random.Next(2) == 0) ? 1f : (-1f)) * 3f; float bossX = (((Object)player != (Object)null) ? (((Component)player).transform.position.x + bossOffsetX) : 0f); float bossY = (((Object)player != (Object)null) ? ((Component)player).transform.position.y : 0f); if ((Object)player != (Object)null && (Object)Map.Instance != (Object)null) { float num = bossX; bounds = Map.Instance.bounds; float num2 = ((Bounds)(ref bounds)).min.x + 2f; bounds = Map.Instance.bounds; bossX = Mathf.Clamp(num, num2, ((Bounds)(ref bounds)).max.x - 2f); try { float num3 = bossX; bounds = Map.Instance.bounds; Vector2 val2 = new Vector2(num3, ((Bounds)(ref bounds)).max.y); Vector2 down2 = Vector2.down; bounds = Map.Instance.bounds; RaycastHit2D[] bossHits = Physics2D.RaycastAll(val2, down2, ((Bounds)(ref bounds)).size.y + 20f); RaycastHit2D[] array2 = bossHits; for (int j = 0; j < array2.Length; j++) { RaycastHit2D hit2 = array2[j]; if ((Object)(object)((RaycastHit2D)(ref hit2)).collider != (Object)null && !((RaycastHit2D)(ref hit2)).collider.isTrigger) { bossY = ((RaycastHit2D)(ref hit2)).point.y + 1f; break; } } } catch { } } Vector3 spawnPos = (Vector3)(((Object)player != (Object)null) ? new Vector3(bossX, bossY, ((Component)player).transform.position.z) : Vector3.zero); Debug.Log((object)$"[ChzzkGameMode] C_DoBoss: addressableKeys.Count={addressableKeys.Count}, targetType={targetType}"); if (addressableKeys.Count > 0) { string randomKey = addressableKeys[_random.Next(addressableKeys.Count)]; Debug.Log((object)("[ChzzkGameMode] C_DoBoss: Addressables 로딩 시작: " + randomKey)); AsyncOperationHandle handle = Addressables.InstantiateAsync((object)randomKey, (Transform)null, false, true); yield return handle; Debug.Log((object)$"[ChzzkGameMode] C_DoBoss: Addressables 로딩 상태: {handle.Status}"); if ((int)handle.Status == 1) { GameObject loadedObj = handle.Result; if ((Object)(object)loadedObj != (Object)null) { bossChar = loadedObj.GetComponent(); if ((Object)(object)bossChar != (Object)null) { original = bossChar; loadedObj.transform.position = spawnPos; Debug.Log((object)("[ChzzkGameMode] C_DoBoss: Addressables에서 bossChar 성공적으로 가져옴. name=" + ((Object)bossChar).name)); } else { Debug.LogWarning((object)"[ChzzkGameMode] C_DoBoss: 로드된 GameObject에 Character 컴포넌트가 없습니다."); } } else { Debug.LogWarning((object)"[ChzzkGameMode] C_DoBoss: 로드된 GameObject가 null입니다."); } } } if ((Object)bossChar == (Object)null) { List candidates = (from c in allEnemies.Where(delegate(Character c) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown if ((Object)c == (Object)null) { return false; } string item = ((Object)((Component)c).gameObject).name.Replace("(Clone)", "").Trim(); return targetAllowedNames.Contains(item); }) group c by ((Object)((Component)c).gameObject).name.Replace("(Clone)", "").Trim() into g select ((IEnumerable)g).FirstOrDefault((Func)delegate(Character c) { //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) Scene scene = ((Component)c).gameObject.scene; return !((Scene)(ref scene)).IsValid(); }) ?? g.First()).ToList(); if (candidates.Count == 0 && (int)targetType > 0) { candidates = (from c in allEnemies.Where(delegate(Character c) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown if ((Object)c == (Object)null) { return false; } string item = ((Object)((Component)c).gameObject).name.Replace("(Clone)", "").Trim(); return allowedMobs.Contains(item); }) group c by ((Object)((Component)c).gameObject).name.Replace("(Clone)", "").Trim() into g select ((IEnumerable)g).FirstOrDefault((Func)delegate(Character c) { //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) Scene scene = ((Component)c).gameObject.scene; return !((Scene)(ref scene)).IsValid(); }) ?? g.First()).ToList(); } if (candidates.Count > 0) { original = candidates[_random.Next(candidates.Count)]; } } if ((Object)bossChar == (Object)null && (Object)original == (Object)null) { Debug.LogError((object)"[ChzzkGameMode] C_DoBoss 실패: 소환할 캐릭터 원본(original)과 bossChar가 모두 null입니다."); if (!isRecovery) { SaveWrapper saveData2 = ChzzkStatManager.SaveData; saveData2.SpawnedBossCount++; ChzzkStatManager.Save(); ForceNextDarkEnemy = true; _darkEnemyTargetMap = null; ShowFloatingText(nickname + "이(가) 소환할 몬스터가 없어 다음 맵을 저주했어요!"); } yield break; } if ((Object)player == (Object)null) { Debug.LogWarning((object)"[ChzzkGameMode] C_DoBoss 중단: player가 null입니다."); if (!isRecovery) { SaveWrapper saveData3 = ChzzkStatManager.SaveData; saveData3.SpawnedBossCount++; ChzzkStatManager.Save(); } yield break; } if ((Object)bossChar == (Object)null) { try { Debug.Log((object)("[ChzzkGameMode] C_DoBoss: 메모리 원본에서 복제 시도: " + ((Object)original).name)); bossChar = Object.Instantiate(original, spawnPos, Quaternion.identity); } catch (Exception ex3) { Debug.LogError((object)("[ChzzkGameMode] Instantiate failed: " + ex3)); } } if ((Object)bossChar == (Object)null) { Debug.LogError((object)"[ChzzkGameMode] C_DoBoss 중단: 최종적으로 bossChar가 null입니다."); if (!isRecovery) { SaveWrapper saveData4 = ChzzkStatManager.SaveData; saveData4.SpawnedBossCount++; ChzzkStatManager.Save(); ForceNextDarkEnemy = true; _darkEnemyTargetMap = null; ShowFloatingText(nickname + "이(가) 소환할 몬스터가 없어 다음 맵을 저주했어요!"); } yield break; } ((Component)bossChar).gameObject.SetActive(true); if ((Object)(object)bossChar.attach != (Object)null) { bossChar.attach.SetActive(true); } yield return null; if ((Object)bossChar == (Object)null || (Object)player == (Object)null) { Debug.LogWarning((object)$"[ChzzkGameMode] C_DoBoss 중단 (1프레임 대기 후): bossChar={(Object)(object)bossChar != (Object)null}, player={(Object)(object)player != (Object)null}"); yield break; } try { if ((int)bossChar.type == 0 || (int)bossChar.type == 1) { ((Component)bossChar).transform.localScale = ((Component)original).transform.localScale * 1.8f; } double healthMultiplier = 0.05; try { Service service = Singleton.Instance; if ((Object)(object)service != (Object)null && (Object)(object)service.levelManager != (Object)null && (Object)(object)service.levelManager.currentChapter != (Object)null) { int chapterTypeVal = (int)service.levelManager.currentChapter.type; if (chapterTypeVal == 0) { healthMultiplier = 1.0; } else { double factor = 1.0 + 0.5 * (double)(chapterTypeVal - 1); healthMultiplier = 0.05 * factor; } } } catch { } if (healthMultiplier < 0.005) { healthMultiplier = 0.005; } if (healthMultiplier > 2.0) { healthMultiplier = 2.0; } try { bossChar.stat.AttachValues(new Values((Value[])(object)new Value[1] { new Value(Category.PercentPoint, Kind.Health, healthMultiplier - 1.0) })); } catch { } if ((Object)(object)bossChar.health != (Object)null) { try { ((Health)bossChar.health).Heal(999999.0, true); } catch (Exception ex) { Exception ex4 = ex; Debug.LogWarning((object)("[ChzzkGameMode] Heal 실패: " + ex4.Message)); } } try { InitializeSpawnedBossAI(bossChar, player); } catch (Exception ex5) { Debug.LogError((object)("[ChzzkGameMode] C_DoBoss AI 활성화 오류: " + ex5)); } if ((Object)Map.Instance != (Object)null && (Object)Map.Instance.waveContainer != (Object)null) { try { Map.Instance.waveContainer.AttachToSummonEnemyWave(bossChar); typeof(EnemyWaveContainer).GetMethod("CheckWaveState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(Map.Instance.waveContainer, null); } catch (Exception ex) { Exception ex6 = ex; Debug.LogWarning((object)("[ChzzkGameMode] waveContainer.AttachToSummonEnemyWave 실패: " + ex6.Message)); try { Map.Instance.waveContainer.Attach(bossChar); typeof(EnemyWaveContainer).GetMethod("CheckWaveState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(Map.Instance.waveContainer, null); } catch { } } } if (!isRecovery) { SaveWrapper saveData5 = ChzzkStatManager.SaveData; saveData5.SpawnedBossCount++; ChzzkStatManager.Save(); if ((Object)Map.Instance != (Object)null) { _lastSpawnedBossMap = ((Object)Map.Instance).name; } } if ((int)bossChar.type == 0 || (int)bossChar.type == 1) { SpriteRenderer bossRenderer = ((Component)bossChar).GetComponentInChildren(); if ((Object)bossRenderer != (Object)null) { bossRenderer.color = new Color(0.8f, 0.1f, 0.1f); } } if (!isRecovery) { ForceNextDarkEnemy = true; _darkEnemyTargetMap = null; ShowFloatingText(nickname + "이(가) 보스를 소환하고 다음 맵을 저주했어요!"); } } catch (Exception ex7) { Debug.LogError((object)("[ChzzkGameMode] DoBoss 소환 실패: " + ex7)); if (!isRecovery) { SaveWrapper saveData6 = ChzzkStatManager.SaveData; saveData6.SpawnedBossCount++; ChzzkStatManager.Save(); Debug.Log((object)$"[ChzzkGameMode] DoBoss 소환 예외 발생으로 다음 맵 소환 예약. SpawnedBossCount={ChzzkStatManager.SaveData.SpawnedBossCount}"); } List fallbackCandidates = Map.Instance.waveContainer.GetAllSpawnedEnemies(); if (fallbackCandidates.Count > 0) { Character fallbackChar = fallbackCandidates[_random.Next(fallbackCandidates.Count)]; Transform transform = ((Component)fallbackChar).transform; transform.localScale *= 1.5f; try { fallbackChar.stat.AttachValues(new Values((Value[])(object)new Value[1] { new Value(Category.PercentPoint, Kind.Health, 5.0) })); fallbackChar.stat.AttachValues(new Values((Value[])(object)new Value[1] { new Value(Category.PercentPoint, Kind.AttackDamage, 1.5) })); } catch { } ((Health)fallbackChar.health).Heal(999999.0, true); } if (!isRecovery) { ForceNextDarkEnemy = true; _darkEnemyTargetMap = null; ShowFloatingText(nickname + "이(가) 기존 적을 강화하고 다음 맵을 저주했어요!"); } } } private IEnumerator C_RecoverBossesForMap(string targetMapName) { Debug.Log((object)$"[ChzzkGameMode] C_RecoverBossesForMap 시작됨: targetMapName={targetMapName}, SpawnedBossCount={ChzzkStatManager.SaveData.SpawnedBossCount}"); Character player = null; for (int i = 0; i < 60; i++) { player = GetPlayer(); if ((Object)(object)player != (Object)null && (Object)(object)Map.Instance != (Object)null && ((Object)Map.Instance).name == targetMapName && (Object)(object)Map.Instance.waveContainer != (Object)null) { break; } yield return (object)new WaitForSeconds(0.5f); } object[] obj = new object[5] { (Object)(object)player != (Object)null, Map.Instance, null, null, null }; Map instance = Map.Instance; obj[2] = ((instance != null) ? ((Object)instance).name : null); obj[3] = targetMapName; Map instance2 = Map.Instance; obj[4] = (Object)(object)((instance2 != null) ? instance2.waveContainer : null) != (Object)null; Debug.Log((object)string.Format("[ChzzkGameMode] C_RecoverBossesForMap 대기 완료: player={0}, Map={1}, mapName={2}, targetMapName={3}, waveContainer={4}", obj)); if ((Object)(object)player == (Object)null || (Object)(object)Map.Instance == (Object)null || ((Object)Map.Instance).name != targetMapName || (Object)(object)Map.Instance.waveContainer == (Object)null) { object[] obj2 = new object[5] { player, Map.Instance, null, null, null }; Map instance3 = Map.Instance; obj2[2] = ((instance3 != null) ? ((Object)instance3).name : null); obj2[3] = targetMapName; Map instance4 = Map.Instance; obj2[4] = ((instance4 != null) ? instance4.waveContainer : null); Debug.LogWarning((object)string.Format("[ChzzkGameMode] C_RecoverBossesForMap 조건 불충족으로 중단: player={0}, map={1}, mapName={2}, targetMapName={3}, waveContainer={4}", obj2)); } else { int count = ChzzkStatManager.SaveData.SpawnedBossCount; ChzzkStatManager.SaveData.SpawnedBossCount = 0; ChzzkStatManager.Save(); Debug.Log((object)$"[ChzzkGameMode] C_RecoverBossesForMap 소환 시작: count={count}"); for (int j = 0; j < count; j++) { ((MonoBehaviour)this).StartCoroutine(C_DoBoss("재접속 복구", isRecovery: true)); } } } public static Character GetPlayer() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown try { if ((Object)(object)Object.FindObjectOfType() == (Object)null) { return null; } Service instance = Singleton.Instance; object obj; if ((Object)(object)instance == (Object)null) { obj = null; } else { LevelManager levelManager = instance.levelManager; obj = (((Object)(object)levelManager != (Object)null) ? levelManager.player : null); } return (Character)obj; } catch { return null; } } public static int GetCardCount(Item item = null) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { string name = ((Object)((Component)item).gameObject).name; if (name.Contains("_E") || name.Contains("_RE")) { return 4; } } Character player = GetPlayer(); if ((Object)(object)player == (Object)null || player.playerComponents == null || player.playerComponents.inventory == null || (Object)(object)player.playerComponents.inventory.synergy == (Object)null) { return 0; } try { return player.playerComponents.inventory.synergy.inscriptions[(Key)37]?.count ?? 0; } catch { return 0; } } public static bool IsCardSynergySuper(Item item = null) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { string name = ((Object)((Component)item).gameObject).name; if (name.Contains("_R") || name.Contains("_RE")) { return true; } } Character player = GetPlayer(); if ((Object)(object)player == (Object)null || player.playerComponents == null || player.playerComponents.inventory == null || (Object)(object)player.playerComponents.inventory.synergy == (Object)null) { return false; } try { Inscription val = player.playerComponents.inventory.synergy.inscriptions[(Key)37]; return val != null && val.isSuper; } catch { return false; } } private void CheckMoonSunFusion() { Character player = GetPlayer(); if ((Object)(object)player == (Object)null || player.playerComponents == null || player.playerComponents.inventory == null || (Object)(object)player.playerComponents.inventory.item == (Object)null) { return; } ItemInventory item = player.playerComponents.inventory.item; Item val = null; Item val2 = null; foreach (Item item2 in item.items) { if (!((Object)(object)item2 == (Object)null)) { string text = ((Object)((Component)item2).gameObject).name.Replace("(Clone)", "").Trim(); if (text == "Custom-CardMoon" || text == "CardMoon") { val = item2; } else if (text == "Custom-CardSun" || text == "CardSun") { val2 = item2; } } } if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { ((Object)((Component)val).gameObject).name = "FusedMoon"; ((Object)((Component)val2).gameObject).name = "FusedSun"; CustomItemReference val3 = ((IEnumerable)CustomItems.Items).FirstOrDefault((Func)((CustomItemReference i) => i.name == "Custom-CardSupernova" || i.name == "CardSupernova")); if (val3 != null) { ((MonoBehaviour)this).StartCoroutine(C_SwapToSupernova(val, val2, val3)); } } } private IEnumerator C_SwapToSupernova(Item moon, Item sun, CustomItemReference supernovaRef) { ItemRequest request = ((ItemReference)supernovaRef).LoadAsync(); while (!((Request)(object)request).isDone) { yield return null; } Character player = GetPlayer(); if ((Object)(object)player == (Object)null || player.playerComponents == null || player.playerComponents.inventory == null || (Object)(object)player.playerComponents.inventory.item == (Object)null) { yield break; } ItemInventory itemInventory = player.playerComponents.inventory.item; itemInventory.Remove(moon); itemInventory.Remove(sun); Item drop = Singleton.Instance.levelManager.DropItem(request, ((Component)player).transform.position); if ((Object)(object)drop != (Object)null) { if (itemInventory.items.Count((Item i) => (Object)(object)i != (Object)null) < (CustomGearsPatch.HasErrorCreator() ? 50 : 9)) { itemInventory.TryEquip(drop); ShowFloatingText(Plugin.IsKorean() ? "태양과 달이 만나 초신성 폭발 카드로 융합되었습니다!" : "Sun and Moon cards fused into the Supernova Card!"); } else { ShowFloatingText(Plugin.IsKorean() ? "인벤토리가 가득 차 초신성 폭발 카드가 바닥에 떨어졌습니다!" : "Inventory full! Supernova Card dropped on the ground!"); } } } private Service GetService() { try { if ((Object)(object)Object.FindObjectOfType() == (Object)null) { return null; } return Singleton.Instance; } catch { return null; } } private Rarity PickWeightedRarity() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected I4, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)Object.FindObjectOfType() == (Object)null) { return (Rarity)0; } Chapter currentChapter = Singleton.Instance.levelManager.currentChapter; Random random = new Random(Save.instance.randomSeed + 2028506624 + currentChapter.type * 256 + currentChapter.stageIndex * 16 + currentChapter.currentStage.pathIndex); return new RarityPossibilities(Array.Empty()).Evaluate(random); } catch { int num = _random.Next(100); if (num < 60) { return (Rarity)0; } if (num < 90) { return (Rarity)1; } if (num < 99) { return (Rarity)2; } return (Rarity)3; } } public void ShowFloatingText(string message) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if (message.Contains("$CHAOS$")) { message = "무언가가 일어났습니다!"; } try { Service instance = Singleton.Instance; object obj; if ((Object)(object)instance == (Object)null) { obj = null; } else { LevelManager levelManager = instance.levelManager; obj = (((Object)(object)levelManager != (Object)null) ? levelManager.player : null); } Character val = (Character)obj; if ((Object)val == (Object)null) { return; } Service instance2 = Singleton.Instance; if ((Object)(object)instance2 != (Object)null) { FloatingTextSpawner floatingTextSpawner = instance2.floatingTextSpawner; if ((Object)(object)floatingTextSpawner != (Object)null) { floatingTextSpawner.SpawnBuff(message, ((Component)val).transform.position + Vector3.up * 2f, "#FFD700"); } } } catch { } } private void ApplyVotedAction(string title) { if (string.IsNullOrEmpty(title)) { return; } ShowFloatingText("이전 투표 결과 복구: [" + title + "]"); switch (title) { case "랜덤 스컬 소환": ((MonoBehaviour)this).StartCoroutine(DoSkullCoroutine("재접속 복구")); return; case "랜덤 아이템 소환": ((MonoBehaviour)this).StartCoroutine(DoItemCoroutine("재접속 복구")); return; case "랜덤 스탯 변화": DoRandomStat("재접속 복구"); return; case "버프 또는 은총(저주)": DoBuffOrCurse("재접속 복구"); return; case "각인 추가": DoSynergy("재접속 복구"); return; case "보스 소환": DoBoss("재접속 복구"); return; case "음식(회복) 드롭": DoFood("재접속 복구"); return; case "랜덤 NPC 스폰": DoNPC("재접속 복구"); return; case "파편 (삭제/획득)": ((MonoBehaviour)this).StartCoroutine(DoFragmentCoroutine("재접속 복구")); return; case "뼈 조각 소환": DoBone("재접속 복구"); return; case "골드 지급": DoGold("재접속 복구"); return; case "검은 마석 지급": DoDarkQuartz("재접속 복구"); return; case "정수 소환": ((MonoBehaviour)this).StartCoroutine(DoQuintessenceCoroutine("재접속 복구")); return; case "검은 능력 지급": DoDarkAbility("재접속 복구"); return; case "흉조 아이템 드롭": DoOmen("재접속 복구"); return; case "체력 회복": DoHeal("재접속 복구"); return; case "방어력 (감소/증가)": DoDefense("재접속 복구"); return; case "버프 토템 (90초)": DoTotemBuff("재접속 복구"); return; case "상자 소환": DoChestSpawn("재접속 복구"); return; case "저주의 상자 (공격↑ 피해↑)": DoCursedChestBuff("재접속 복구"); return; case "핵폭발 발동": DoNuke("재접속 복구"); return; } if (title.EndsWith(" 모드")) { DoBossRush("재접속 복구"); } } private void StartVote() { if (_voteState != VoteState.Inactive) { return; } _votedUsers.Clear(); _currentVoteOptions.Clear(); _voteTimer = Plugin.VoteDurationSeconds.Value; List list = new List { new VoteOption { Title = "랜덤 스컬 소환", Votes = 0, Action = delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoSkullCoroutine(n)); } }, new VoteOption { Title = "랜덤 아이템 소환", Votes = 0, Action = delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoItemCoroutine(n)); } }, new VoteOption { Title = "랜덤 스탯 변화", Votes = 0, Action = delegate(string n) { DoRandomStat(n); } }, new VoteOption { Title = "버프 또는 은총(저주)", Votes = 0, Weight = Plugin.VoteWeightBuffCurse.Value, Action = delegate(string n) { DoBuffOrCurse(n); } }, new VoteOption { Title = "각인 추가", Votes = 0, Weight = Plugin.VoteWeightSynergy.Value, Action = delegate(string n) { DoSynergy(n); } }, new VoteOption { Title = "보스 소환", Votes = 0, Weight = Plugin.VoteWeightBoss.Value, Action = delegate(string n) { DoBoss(n); } }, new VoteOption { Title = "음식(회복) 드롭", Votes = 0, Weight = Plugin.VoteWeightFood.Value, Action = delegate(string n) { DoFood(n); } }, new VoteOption { Title = "랜덤 NPC 스폰", Votes = 0, Weight = Plugin.VoteWeightNPC.Value, Action = delegate(string n) { DoNPC(n); } }, new VoteOption { Title = "파편 (삭제/획득)", Votes = 0, Weight = Plugin.VoteWeightFragment.Value, Action = delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoFragmentCoroutine(n)); } }, new VoteOption { Title = "뼈 조각 소환", Votes = 0, Weight = Plugin.VoteWeightBone.Value, Action = delegate(string n) { DoBone(n); } }, new VoteOption { Title = "골드 지급", Votes = 0, Weight = Plugin.VoteWeightGold.Value, Action = delegate(string n) { DoGold(n); } }, new VoteOption { Title = "검은 마석 지급", Votes = 0, Weight = Plugin.VoteWeightDarkQuartz.Value, Action = delegate(string n) { DoDarkQuartz(n); } }, new VoteOption { Title = "정수 소환", Votes = 0, Weight = Plugin.VoteWeightQuintessence.Value, Action = delegate(string n) { ((MonoBehaviour)this).StartCoroutine(DoQuintessenceCoroutine(n)); } }, new VoteOption { Title = "검은 능력 지급", Votes = 0, Weight = Plugin.VoteWeightDarkAbility.Value, Action = delegate(string n) { DoDarkAbility(n); } }, new VoteOption { Title = "흉조 아이템 드롭", Votes = 0, Weight = Plugin.VoteWeightOmen.Value, Action = delegate(string n) { DoOmen(n); } }, new VoteOption { Title = "체력 회복", Votes = 0, Weight = Plugin.VoteWeightHeal.Value, Action = delegate(string n) { DoHeal(n); } }, new VoteOption { Title = "방어력 (감소/증가)", Votes = 0, Weight = Plugin.VoteWeightDefense.Value, Action = delegate(string n) { DoDefense(n); } }, new VoteOption { Title = "버프 토템 (90초)", Votes = 0, Weight = Plugin.VoteWeightTotem.Value, Action = delegate(string n) { DoTotemBuff(n); } }, new VoteOption { Title = "상자 소환", Votes = 0, Weight = Plugin.VoteWeightChest.Value, Action = delegate(string n) { DoChestSpawn(n); } }, new VoteOption { Title = "저주의 상자 (공격↑ 피해↑)", Votes = 0, Weight = Plugin.VoteWeightTotem.Value, Action = delegate(string n) { DoCursedChestBuff(n); } }, new VoteOption { Title = "핵폭발 발동", Votes = 0, Weight = Plugin.VoteWeightNuke.Value, Action = delegate(string n) { DoNuke(n); } } }; if (!IsBossRushActive) { list.Add(new VoteOption { Title = GetBossRushModeName() + " 모드", Votes = 0, Weight = Plugin.VoteWeightBossRush.Value, Action = delegate(string n) { DoBossRush(n); } }); } if (ChzzkStatManager.SaveData.CurrentVoteOptions != null && ChzzkStatManager.SaveData.CurrentVoteOptions.Count == 3) { foreach (string savedTitle in ChzzkStatManager.SaveData.CurrentVoteOptions) { VoteOption voteOption = list.Find((VoteOption x) => x.Title == savedTitle); if (voteOption != null) { _currentVoteOptions.Add(voteOption); list.Remove(voteOption); } } } while (_currentVoteOptions.Count < 3 && list.Count > 0) { int num = 0; for (int num2 = 0; num2 < list.Count; num2++) { num += list[num2].Weight; } if (num <= 0) { int index = _random.Next(list.Count); _currentVoteOptions.Add(list[index]); list.RemoveAt(index); continue; } int num3 = _random.Next(num); int num4 = 0; int index2 = 0; for (int num5 = 0; num5 < list.Count; num5++) { num4 += list[num5].Weight; if (num3 < num4) { index2 = num5; break; } } _currentVoteOptions.Add(list[index2]); list.RemoveAt(index2); } if (ChzzkStatManager.SaveData.CurrentVoteOptions == null) { ChzzkStatManager.SaveData.CurrentVoteOptions = new List(); } ChzzkStatManager.SaveData.CurrentVoteOptions.Clear(); foreach (VoteOption currentVoteOption in _currentVoteOptions) { ChzzkStatManager.SaveData.CurrentVoteOptions.Add(currentVoteOption.Title); } ChzzkStatManager.Save(); _voteState = VoteState.Voting; ShowFloatingText("투표가 시작되었습니다! 채팅창에 1, 2, 3을 입력하세요!"); } private void EndVote() { _voteState = VoteState.Processing; if (_currentVoteOptions.Count > 0) { VoteOption voteOption = _currentVoteOptions.OrderByDescending((VoteOption o) => o.Votes).First(); if (voteOption.Votes == 0) { voteOption = _currentVoteOptions[_random.Next(_currentVoteOptions.Count)]; ShowFloatingText("아무도 투표하지 않아 랜덤으로 [" + voteOption.Title + "] 이(가) 선택되었습니다!"); } else { ShowFloatingText($"투표 종료! [{voteOption.Title}] 이(가) {voteOption.Votes}표로 선택되었습니다!"); } ChzzkStatManager.SaveData.VotedResultTitle = voteOption.Title; ((MonoBehaviour)this).StartCoroutine(C_ExecuteVoteAction(voteOption)); } _voteState = VoteState.Inactive; ChzzkStatManager.SaveData.IsVoteCompletedInThisStage = true; if (ChzzkStatManager.SaveData.CurrentVoteOptions != null) { ChzzkStatManager.SaveData.CurrentVoteOptions.Clear(); } ChzzkStatManager.Save(); } private IEnumerator C_ExecuteVoteAction(VoteOption option) { yield return (object)new WaitForSecondsRealtime(2f); try { option.Action?.Invoke("시청자 투표"); } catch (Exception ex) { Debug.LogError((object)("[ChzzkGameMode] 투표 액션 실행 오류: " + ex)); } } private void InitializeSpawnedBossAI(Character bossChar, Character player) { //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bossChar == (Object)null || (Object)(object)player == (Object)null) { return; } ((Behaviour)bossChar).enabled = true; try { MonoBehaviour[] componentsInChildren = ((Component)bossChar).GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if (!(fieldInfo.FieldType == typeof(Transform))) { continue; } object value = fieldInfo.GetValue(val); if (value == null) { string text = "Dummy_" + fieldInfo.Name; GameObject val2 = new GameObject(text); val2.transform.parent = ((Component)bossChar).transform; if (fieldInfo.Name.Contains("minHeight") || fieldInfo.Name.Contains("MinHeight")) { val2.transform.position = new Vector3(((Component)bossChar).transform.position.x, ((Component)player).transform.position.y - 1.5f, 0f); } else { val2.transform.position = ((Component)bossChar).transform.position; } fieldInfo.SetValue(val, val2.transform); Debug.Log((object)("[ChzzkGameMode] Initialized null Transform field '" + fieldInfo.Name + "' on '" + type.Name + "' with a dummy transform.")); } } } } catch (Exception ex) { Debug.LogWarning((object)("[ChzzkGameMode] Failed to initialize null Transform fields on boss: " + ex.Message)); } try { MonoBehaviour[] componentsInChildren2 = ((Component)bossChar).GetComponentsInChildren(true); foreach (MonoBehaviour val3 in componentsInChildren2) { if ((Object)(object)val3 == (Object)null) { continue; } string fullName = ((object)val3).GetType().FullName; if (!fullName.Contains("AI") && !fullName.Contains("Behavior") && !fullName.Contains("Behaviour")) { continue; } ((Behaviour)val3).enabled = true; try { AIController val4 = (AIController)(object)((val3 is AIController) ? val3 : null); if (val4 != null) { val4.target = player; bossChar.ForceToLookAt(((Component)player).transform.position.x); try { val4.FoundEnemy(); } catch { } } } catch { } if (!fullName.Contains("BehaviorTree")) { continue; } try { Type type2 = ((object)val3).GetType(); MethodInfo method = type2.GetMethod("GetVariable"); MethodInfo method2 = type2.GetMethod("SetVariableValue"); object obj3 = method?.Invoke(val3, new object[1] { "Target" }) ?? method?.Invoke(val3, new object[1] { "target" }) ?? method?.Invoke(val3, new object[1] { "Player" }) ?? method?.Invoke(val3, new object[1] { "player" }) ?? method?.Invoke(val3, new object[1] { "Enemy" }) ?? method?.Invoke(val3, new object[1] { "enemy" }); if (obj3 != null) { MethodInfo method3 = obj3.GetType().GetMethod("SetValue"); if (obj3.GetType().Name.Contains("Character")) { method3?.Invoke(obj3, new object[1] { player }); } else { method3?.Invoke(obj3, new object[1] { ((Component)player).gameObject }); } } else { method2?.Invoke(val3, new object[2] { "Target", ((Component)player).gameObject }); method2?.Invoke(val3, new object[2] { "target", ((Component)player).gameObject }); method2?.Invoke(val3, new object[2] { "Player", ((Component)player).gameObject }); method2?.Invoke(val3, new object[2] { "player", ((Component)player).gameObject }); method2?.Invoke(val3, new object[2] { "Enemy", ((Component)player).gameObject }); method2?.Invoke(val3, new object[2] { "enemy", ((Component)player).gameObject }); } type2.GetMethod("EnableBehavior")?.Invoke(val3, null); } catch { } } } catch (Exception ex2) { Debug.LogWarning((object)("[ChzzkGameMode] Failed to activate AI/BT components: " + ex2.Message)); } try { string text2 = ((Object)((Component)bossChar).gameObject).name.Replace("(Clone)", "").Trim(); if (text2.Contains("Pope")) { MonoBehaviour[] componentsInChildren3 = ((Component)bossChar).GetComponentsInChildren(true); foreach (MonoBehaviour val5 in componentsInChildren3) { if (((object)val5).GetType().Name.Contains("PopeAI")) { ((object)val5).GetType().GetMethod("StartCombat")?.Invoke(val5, null); Debug.Log((object)"[ChzzkGameMode] Triggered StartCombat on PopeAI"); } } } if (text2.Contains("Chimera")) { MonoBehaviour[] componentsInChildren4 = ((Component)bossChar).GetComponentsInChildren(true); foreach (MonoBehaviour val6 in componentsInChildren4) { if (((object)val6).GetType().Name == "Chimera") { MethodInfo method4 = ((object)val6).GetType().GetMethod("Combat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method4 != null) { ((MonoBehaviour)this).StartCoroutine((IEnumerator)method4.Invoke(val6, null)); Debug.Log((object)"[ChzzkGameMode] Triggered Combat coroutine on Chimera"); } } } } if (!text2.Contains("LongHair") && !text2.Contains("ShortHair")) { return; } GoldenAideAI componentInChildren = ((Component)bossChar).GetComponentInChildren(); DarkAideAI componentInChildren2 = ((Component)bossChar).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { ((MonoBehaviour)componentInChildren).StopAllCoroutines(); CheckWithinSight componentInChildren3 = ((Component)componentInChildren).GetComponentInChildren(); if ((Object)(object)componentInChildren3 != (Object)null) { ((MonoBehaviour)this).StartCoroutine(((Behaviour)componentInChildren3).CRun((AIController)(object)componentInChildren)); } ((MonoBehaviour)this).StartCoroutine(CChzzkGoldenAideCombat(componentInChildren)); Debug.Log((object)"[ChzzkGameMode] Started custom single combat loop for GoldenAideAI (LongHair)."); } else if ((Object)(object)componentInChildren2 != (Object)null) { ((MonoBehaviour)componentInChildren2).StopAllCoroutines(); CheckWithinSight componentInChildren4 = ((Component)componentInChildren2).GetComponentInChildren(); if ((Object)(object)componentInChildren4 != (Object)null) { ((MonoBehaviour)this).StartCoroutine(((Behaviour)componentInChildren4).CRun((AIController)(object)componentInChildren2)); } ((MonoBehaviour)this).StartCoroutine(CChzzkDarkAideCombat(componentInChildren2)); Debug.Log((object)"[ChzzkGameMode] Started custom single combat loop for DarkAideAI (ShortHair)."); } } catch (Exception ex3) { Debug.LogWarning((object)("[ChzzkGameMode] Special Boss AI wakeup failed: " + ex3.Message)); } } private IEnumerator CChzzkGoldenAideCombat(GoldenAideAI aide) { yield return ChronometerExtension.WaitForSeconds((ChronometerBase)(object)((AIController)aide).character.chronometer.master, 1f); List patterns = new List { "GoldenMeteor", "MeteorAir", "MeteorGround", "MeteorGround2", "Rush", "DimensionPierce", "RisingPierce", "Dash", "Backstep", "Homing" }; string lastPattern = ""; while ((Object)(object)aide != (Object)null && !((AIController)aide).dead) { while (((AIController)aide).character.stunedOrFreezed) { yield return null; } string pattern; do { pattern = patterns[_random.Next(patterns.Count)]; } while (pattern == lastPattern && patterns.Count > 1); lastPattern = pattern; IEnumerator patternCoroutine = null; switch (pattern) { case "GoldenMeteor": patternCoroutine = aide.CastGoldenMeteor(); break; case "MeteorAir": patternCoroutine = aide.CastMeteorInAir(); break; case "MeteorGround": patternCoroutine = aide.CastMeteorInGround(); break; case "MeteorGround2": patternCoroutine = aide.CastMeteorInGround2(); break; case "Rush": patternCoroutine = aide.CastRush(); break; case "DimensionPierce": patternCoroutine = aide.CastDimensionPierce(); break; case "RisingPierce": patternCoroutine = aide.CastRisingPierce(); break; case "Dash": patternCoroutine = aide.CastDash(0f); break; case "Backstep": patternCoroutine = aide.CastBackstep(); break; case "Homing": patternCoroutine = aide.CastRangeAttackHoming(false); break; } if (patternCoroutine != null) { yield return ((MonoBehaviour)this).StartCoroutine(patternCoroutine); } float delay = Random.Range(1.5f, 2.5f); yield return ChronometerExtension.WaitForSeconds((ChronometerBase)(object)((AIController)aide).character.chronometer.master, delay); } } private IEnumerator CChzzkDarkAideCombat(DarkAideAI aide) { yield return ChronometerExtension.WaitForSeconds((ChronometerBase)(object)((AIController)aide).character.chronometer.master, 1f); List patterns = new List { "GoldenMeteor", "MeteorAir", "MeteorGround2", "Rush", "DimensionPierce", "Backstep", "Homing" }; string lastPattern = ""; while ((Object)(object)aide != (Object)null && !((AIController)aide).dead) { while (((AIController)aide).character.stunedOrFreezed) { yield return null; } string pattern; do { pattern = patterns[_random.Next(patterns.Count)]; } while (pattern == lastPattern && patterns.Count > 1); lastPattern = pattern; IEnumerator patternCoroutine = null; switch (pattern) { case "GoldenMeteor": patternCoroutine = aide.CastGoldenMeteor(); break; case "MeteorAir": patternCoroutine = aide.CastMeteorInAir(); break; case "MeteorGround2": patternCoroutine = aide.CastMeteorInGround2(); break; case "Rush": patternCoroutine = aide.CastRush(); break; case "DimensionPierce": patternCoroutine = aide.CastDimensionPierce(); break; case "Backstep": patternCoroutine = aide.CastBackstep(); break; case "Homing": patternCoroutine = aide.CastRangeAttackHoming(); break; } if (patternCoroutine != null) { yield return ((MonoBehaviour)this).StartCoroutine(patternCoroutine); } float delay = Random.Range(1.5f, 2.5f); yield return ChronometerExtension.WaitForSeconds((ChronometerBase)(object)((AIController)aide).character.chronometer.master, delay); } } private bool TryParseCardItem(string name, out string baseName, out bool isReversed, out bool isEnhanced) { baseName = null; isReversed = false; isEnhanced = false; if (string.IsNullOrEmpty(name)) { return false; } string text = name.Replace("(Clone)", "").Trim(); string text2 = text; if (text2.StartsWith("Custom-")) { text2 = text2.Substring("Custom-".Length); } if (!text2.StartsWith("Card")) { return false; } string text3 = text2; if (text3.EndsWith("_RE")) { isReversed = true; isEnhanced = true; text3 = text3.Substring(0, text3.Length - 3); } else if (text3.EndsWith("_R")) { isReversed = true; isEnhanced = false; text3 = text3.Substring(0, text3.Length - 2); } else if (text3.EndsWith("_E")) { isReversed = false; isEnhanced = true; text3 = text3.Substring(0, text3.Length - 2); } baseName = text3; return true; } private void UpdateCardSynergy(Character player) { //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Invalid comparison between Unknown and I4 //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) if (!PluginItems.IsModActive || (Object)(object)player == (Object)null || player.playerComponents == null || player.playerComponents.inventory == null || (Object)(object)player.playerComponents.inventory.synergy == (Object)null) { return; } try { ItemInventory item = player.playerComponents.inventory.item; if ((Object)(object)item != (Object)null && item.items != null) { int num = 0; Synergy synergy = player.playerComponents.inventory.synergy; try { Inscription val = ChzzkCardSynergy.TryGetCardInscription(player); if (val != null) { num = val.count; } } catch { } bool flag = IsCardSynergySuper(); List list = new List(item.items); ItemReference val2 = default(ItemReference); foreach (Item item2 in list) { if ((Object)(object)item2 == (Object)null || !TryParseCardItem(((Object)((Component)item2).gameObject).name, out var baseName, out var isReversed, out var isEnhanced)) { continue; } bool flag2 = isReversed || flag; bool flag3 = isEnhanced || num >= 4; if (flag2 == isReversed && flag3 == isEnhanced) { continue; } string text = ""; if (flag2 && flag3) { text = "_RE"; } else if (flag2) { text = "_R"; } else if (flag3) { text = "_E"; } string text2 = "Custom-" + baseName + text; if (!GearResource.instance.TryGetItemReferenceByName(text2, ref val2)) { continue; } ItemRequest val3 = val2.LoadAsync(); ((Request)(object)val3).WaitForCompletion(); if ((int)((Gear)item2).state == 1) { Vector3 position = ((Component)player).transform.position; Item val4 = Singleton.Instance.levelManager.DropItem(val3, position); item2.ChangeOnInventory(val4); if (Plugin.IsKorean()) { ShowFloatingText(Localization.GetLocalizedString(((Gear)item2).displayNameKey) + " 카드가 새로운 형태로 진화했습니다!"); } else { ShowFloatingText(Localization.GetLocalizedString(((Gear)item2).displayNameKey) + " evolved!"); } } } } } catch (Exception ex) { Debug.LogError((object)("[UpdateCardSynergy] Card evolve error: " + ex)); } int num2 = 0; try { Inscription val5 = ChzzkCardSynergy.TryGetCardInscription(player); if (val5 != null) { num2 = val5.count; } } catch { } int num3 = 0; if (num2 >= 4) { num3 = 2; } else if (num2 >= 2) { num3 = 1; } if (num3 == _lastCardSynergyStep) { return; } if (_cardSynergyStats != null) { try { player.stat.DetachValues(_cardSynergyStats); } catch { } _cardSynergyStats = null; } _lastCardSynergyStep = num3; List list2 = new List(); if (list2.Count > 0) { _cardSynergyStats = new Values(list2.ToArray()); try { player.stat.AttachValues(_cardSynergyStats); } catch { } } try { player.stat.SetNeedUpdate(); } catch { } } private bool OnGiveDamageForCardSynergy(ITarget target, ref Damage damage) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (_isApplyingCardSynergyDamage) { return false; } Character player = GetPlayer(); if ((Object)(object)player == (Object)null || target == null || (Object)(object)target.character == (Object)null || (Object)(object)target.character.health == (Object)null || ((Health)target.character.health).dead) { return false; } if ((int)damage.attackType == 4) { return false; } if (_lastCardSynergyStep >= 2) { try { double num = ((Damage)(ref damage)).amount * 1.1; if (num > 0.0) { _isApplyingCardSynergyDamage = true; try { Damage val = default(Damage); ((Damage)(ref val))..ctor(Attacker.op_Implicit(player), num, Vector2.op_Implicit(((Component)target.character).transform.position), (Attribute)2, (AttackType)4, (MotionType)0, 1.0, 0f, 0.0, 1.0, 1.0, true, false, 0.0, 0.0, (short)0, (PriorityList)null, 1.0); player.Attack(target, ref val); } finally { _isApplyingCardSynergyDamage = false; } } } catch { } } return false; } } [HarmonyPatch] public class ActionSealPatch { [HarmonyTargetMethods] private static IEnumerable TargetMethods() { Type typeFromHandle = typeof(Action); List list = new List(); Type[] types = typeFromHandle.Assembly.GetTypes(); foreach (Type type in types) { if (type.IsSubclassOf(typeFromHandle) && !type.IsAbstract) { MethodInfo method = type.GetMethod("TryStart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null && method.DeclaringType != typeFromHandle) { list.Add(method); } } } return list.Distinct(); } private static bool Prefix(Action __instance, ref bool __result) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (ChzzkGameMode.IsScreenEffectActive) { if (ChzzkGameMode._screenEffectType == 11) { Character player = ChzzkGameMode.GetPlayer(); if ((Object)(object)player != (Object)null && (Object)(object)player.playerComponents.inventory.weapon.current != (Object)null) { SkillInfo[] skills = player.playerComponents.inventory.weapon.current.skills; if (skills.Length != 0 && (Object)(object)__instance == (Object)(object)skills[0]) { __result = false; return false; } } } else if (ChzzkGameMode._screenEffectType == 12) { string text = ((object)__instance.type/*cast due to .constrained prefix*/).ToString(); if (text.Contains("Quintessence") || ((Object)((Component)__instance).gameObject).name.Contains("Quintessence")) { __result = false; return false; } } } return true; } } [HarmonyPatch] public class OmenChestPath { private static ChzzkUnity streamingConnection; private static bool _forceNextOmen; public static bool ForceNextOmen { get { return _forceNextOmen; } set { _forceNextOmen = value; ChzzkStatManager.Save(); } } [HarmonyPostfix] [HarmonyPatch(typeof(HardmodeChest), "TryToChangeOmenChest")] private static void OmenChest(ref HardmodeChest __instance, ref bool ____isOmenChest) { if (ForceNextOmen) { ____isOmenChest = true; ForceNextOmen = false; Debug.Log((object)"[OmenChestPath] !omen 커맨드로 흉조 상자가 강제 활성화되었습니다."); } } [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static void Inscription_isSuper_Postfix(Inscription __instance, ref bool __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (ChzzkGameMode.CustomSuperInscriptions.Contains(__instance.key)) { __result = true; } } public static async Task StartChzzk(ChzzkGameMode gameModeHandler, string channelId) { GameObject existingHost = GameObject.Find("ChatIntegrationHost"); if ((Object)(object)existingHost != (Object)null) { Object.Destroy((Object)(object)existingHost); await Task.Delay(100); } GameObject go = new GameObject("ChatIntegrationHost"); Object.DontDestroyOnLoad((Object)(object)go); if (!string.IsNullOrEmpty(channelId)) { streamingConnection = go.AddComponent(); streamingConnection.onMessage.AddListener((UnityAction)delegate(ChzzkUnity.Profile profile, string msg) { gameModeHandler.OnChatMessage(profile?.nickname, msg); }); streamingConnection.onDonation.AddListener((UnityAction)delegate(ChzzkUnity.Profile profile, string msg, ChzzkUnity.DonationExtras donation) { gameModeHandler.OnDonation(profile?.nickname, donation?.payAmount ?? 0, msg); }); streamingConnection.Connect(channelId); } if (Plugin.EnableYoutube.Value && !string.IsNullOrEmpty(Plugin.YoutubeApiKey.Value) && !string.IsNullOrEmpty(Plugin.YoutubeVideoId.Value)) { YouTubeUnity ytConnection = go.AddComponent(); ytConnection.onMessage.AddListener((UnityAction)delegate(string nickname, string msg) { gameModeHandler.OnChatMessage(nickname, msg); }); ytConnection.onDonation.AddListener((UnityAction)delegate(string nickname, string msg, int amount) { gameModeHandler.OnDonation(nickname, amount, msg); }); ytConnection.Connect(Plugin.YoutubeApiKey.Value, Plugin.YoutubeVideoId.Value, Plugin.YoutubePollInterval.Value); Debug.Log((object)"[OmenChestPath] YouTube Live Chat integration started."); } await Task.CompletedTask; } public static void Reconnect(ChzzkGameMode gameModeHandler) { StartChzzk(gameModeHandler, Plugin.ChannelID.Value); Debug.Log((object)"[OmenChestPath] Reconnecting to Chzzk/YouTube streams..."); } } [HarmonyPatch(typeof(PoolObject), "OnDestroy")] public class PoolObjectOnDestroyPatch { private static bool Prefix(PoolObject __instance) { try { FieldInfo field = typeof(PoolObject).GetField("_pool", BindingFlags.Instance | BindingFlags.NonPublic); object obj = ((field != null) ? field.GetValue(__instance) : null); if (obj != null) { Type type = obj.GetType(); PropertyInfo property = type.GetProperty("releasing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(property != null) || !(bool)property.GetValue(obj)) { FieldInfo field2 = type.GetField("_objects", BindingFlags.Instance | BindingFlags.NonPublic); IList list = ((field2 != null) ? (field2.GetValue(obj) as IList) : null); FieldInfo field3 = typeof(PoolObject).GetField("_poolIndex", BindingFlags.Instance | BindingFlags.NonPublic); int num = ((field3 != null) ? ((int)field3.GetValue(__instance)) : (-1)); bool flag = false; if (list == null || num < 0 || num >= list.Count) { flag = true; } if (flag) { Debug.LogWarning((object)$"[ChzzkSkul] [PoolObjectOnDestroyPatch] Prevented crash on {((Object)((Component)__instance).gameObject).name}. _poolIndex={num}, objectsCount={list?.Count ?? 0}"); if (field != null) { field.SetValue(__instance, null); } if (field3 != null) { field3.SetValue(__instance, 0); } } } } } catch (Exception ex) { Debug.LogError((object)("[ChzzkSkul] Error in PoolObjectOnDestroyPatch: " + ex)); } return true; } } [BepInPlugin("com.slibul.chzzkskulstreamer", "ChzzkSkulStreamer", "1.1.8")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static ManualLogSource Log; public static ConfigEntry ChannelID; public static ConfigEntry EnableYoutube; public static ConfigEntry YoutubeApiKey; public static ConfigEntry YoutubeVideoId; public static ConfigEntry YoutubePollInterval; public static ConfigEntry TTSProvider; public static ConfigEntry AllowHeal; public static ConfigEntry AllowBuffCurse; public static ConfigEntry AllowItem; public static ConfigEntry AllowSkull; public static ConfigEntry AllowSynergy; public static ConfigEntry AllowOmen; public static ConfigEntry AllowBoss; public static ConfigEntry AllowDarkAbility; public static ConfigEntry AllowRandomStat; public static ConfigEntry AllowNpc; public static ConfigEntry AllowFood; public static ConfigEntry AllowBone; public static ConfigEntry AllowGold; public static ConfigEntry AllowDarkQuartz; public static ConfigEntry AllowTotem; public static ConfigEntry AllowQuintessence; public static ConfigEntry AllowFragment; public static ConfigEntry AllowDefense; public static ConfigEntry AllowNuke; public static ConfigEntry AllowChest; public static ConfigEntry EnableVote; public static ConfigEntry VoteTriggerMode; public static ConfigEntry VoteIntervalSeconds; public static ConfigEntry VoteDurationSeconds; public static ConfigEntry VoteWeightItem; public static ConfigEntry VoteWeightSkull; public static ConfigEntry VoteWeightRandomStat; public static ConfigEntry VoteWeightBuffCurse; public static ConfigEntry VoteWeightSynergy; public static ConfigEntry VoteWeightBoss; public static ConfigEntry VoteWeightFood; public static ConfigEntry VoteWeightNPC; public static ConfigEntry VoteWeightFragment; public static ConfigEntry VoteWeightBone; public static ConfigEntry VoteWeightGold; public static ConfigEntry VoteWeightTotem; public static ConfigEntry VoteWeightDarkQuartz; public static ConfigEntry VoteWeightQuintessence; public static ConfigEntry VoteWeightDarkAbility; public static ConfigEntry VoteWeightOmen; public static ConfigEntry VoteWeightHeal; public static ConfigEntry VoteWeightDefense; public static ConfigEntry VoteWeightBossRush; public static ConfigEntry VoteWeightNuke; public static ConfigEntry VoteWeightChest; public static ConfigEntry AllowStreamerCommand; public static ConfigEntry StreamerNickname; public static ConfigEntry CommandCooldown; public static ConfigEntry NukeCountdownTime; public static ConfigEntry EnableNukeWarningUI; public static ConfigEntry EnableNukeWarningText; public static ConfigEntry NukeNormalEnemyDamageType; public static ConfigEntry NukeNormalEnemyDamageValue; public static ConfigEntry NukeBossDamageType; public static ConfigEntry NukeBossDamageValue; public static ConfigEntry CmdHealString; public static ConfigEntry CmdBuffCurseString; public static ConfigEntry CmdItemString; public static ConfigEntry CmdSkullString; public static ConfigEntry CmdSynergyString; public static ConfigEntry CmdOmenString; public static ConfigEntry CmdBossString; public static ConfigEntry CmdDarkEnemyString; public static ConfigEntry CmdDarkAbilityString; public static ConfigEntry CmdRandomString; public static ConfigEntry CmdRandomStatString; public static ConfigEntry CmdNpcString; public static ConfigEntry CmdFoodString; public static ConfigEntry CmdBoneString; public static ConfigEntry CmdGoldString; public static ConfigEntry CmdDarkQuartzString; public static ConfigEntry CmdQuintessenceString; public static ConfigEntry CmdFragmentString; public static ConfigEntry CmdDefenseString; public static ConfigEntry CmdTotemString; public static ConfigEntry CmdChestString; public static ConfigEntry EnableDonationTTS; public static ConfigEntry EnableChatTTS; public static ConfigEntry DonAmtNukeAll; public static ConfigEntry DonAmtNukeItems; public static ConfigEntry DonAmtSubSkullDelete; public static ConfigEntry DonAmtDarkAbilityDelete; public static ConfigEntry DonAmtItemDelete; public static ConfigEntry DonAmtBossRush; public static ConfigEntry DonAmtBoss; public static ConfigEntry DonAmtScreenEffect; public static ConfigEntry DonAmtSynergy; public static ConfigEntry DonAmtDarkAbility; public static ConfigEntry DonAmtFragment; public static ConfigEntry DonAmtOmen; public static ConfigEntry DonAmtItem; public static ConfigEntry DonAmtSkull; public static ConfigEntry DonAmtQuintessence; public static ConfigEntry DonAmtNPC; public static ConfigEntry DonAmtStat; public static ConfigEntry DonAmtRandomStat; public static ConfigEntry DonAmtBuffCurse; public static ConfigEntry DonAmtHeal; public static ConfigEntry DonAmtDefense; public static ConfigEntry DonAmtTotem; public static ConfigEntry DonAmtFood; public static ConfigEntry DonAmtNuke; public static ConfigEntry DonAmtChest; public static ConfigEntry EnableChatCommands; public static ConfigEntry EnableChaosMode; public static ConfigEntry ChaosIntervalSeconds; public static ConfigEntry PoisonChance; public static ConfigEntry BuffChance; public static ConfigEntry ItemEmptyChance; public static ConfigEntry ItemDeleteChance; public static ConfigEntry ItemOmenChance; public static ConfigEntry ItemAutoEquipChance; public static ConfigEntry SkullSuperChance; public static ConfigEntry SkullEvolveChance; public static ConfigEntry SkullReplaceChance; public static ConfigEntry SkullDeleteChance; public static ConfigEntry FragmentDeleteChance; public static ConfigEntry DarkAbilityDeleteChance; public static Plugin Instance; private static Harmony _harmonyInstance; private static bool? _isEnabled; private static GameObject _gameModeObject; private static Action _onSaveSync; private static Action _onLoadSync; private static Action _onClearSync; public ChzzkGameMode _gameModeHandler; private bool _showSettings = false; private Rect _windowRect = new Rect(100f, 100f, 500f, 600f); private Vector2 _scrollPosition = Vector2.zero; private Dictionary _sectionExpanded = new Dictionary(); private GUIStyle _windowStyle; private GUIStyle _labelStyle; private GUIStyle _buttonStyle; private GUIStyle _textFieldStyle; private GUIStyle _toggleStyle; private GUIStyle _headerStyle; private bool _styleInitialized = false; private GUIStyle _lineStyle; public static bool IsKorean() { return PluginItems.IsKorean(); } private void Awake() { //IL_07b7: Unknown result type (might be due to invalid IL or missing references) //IL_07c1: Expected O, but got Unknown //IL_0834: Unknown result type (might be due to invalid IL or missing references) //IL_083e: Expected O, but got Unknown //IL_113c: Unknown result type (might be due to invalid IL or missing references) //IL_1146: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ChannelID = ((BaseUnityPlugin)this).Config.Bind("Chzzk", "치지직 채널 ID", "", "연결할 치지직 스트리머의 채널 ID입니다."); EnableYoutube = ((BaseUnityPlugin)this).Config.Bind("YouTube", "유튜브 연동 켜기", false, "유튜브 실시간 채팅 연동 기능을 활성화합니다."); YoutubeApiKey = ((BaseUnityPlugin)this).Config.Bind("YouTube", "유튜브 API 키", "", "구글 클라우드에서 발급받은 YouTube Data API v3 키를 입력하세요."); YoutubeVideoId = ((BaseUnityPlugin)this).Config.Bind("YouTube", "유튜브 방송 Video ID", "", "현재 방송 중인 유튜브 스트리밍의 Video ID를 입력하세요."); YoutubePollInterval = ((BaseUnityPlugin)this).Config.Bind("YouTube", "유튜브 폴링 간격 (초)", 10f, "유튜브 채팅을 가져오는 주기(초)입니다."); EnableChatCommands = ((BaseUnityPlugin)this).Config.Bind("Commands", "채팅 명령어 전체 활성화", false, "모든 채팅 명령어를 켜거나 끕니다."); AllowHeal = ((BaseUnityPlugin)this).Config.Bind("Commands", "힐 활성화", true, "!heal / !힐 명령어 활성화 여부"); AllowBuffCurse = ((BaseUnityPlugin)this).Config.Bind("Commands", "버프저주 활성화", true, "!buff / !curse 명령어 활성화 여부"); AllowItem = ((BaseUnityPlugin)this).Config.Bind("Commands", "아이템 활성화", true, "!item / !아이템 명령어 활성화 여부"); AllowSkull = ((BaseUnityPlugin)this).Config.Bind("Commands", "스컬 활성화", true, "!skull / !해골 명령어 활성화 여부"); AllowSynergy = ((BaseUnityPlugin)this).Config.Bind("Commands", "각인 활성화", true, "!synergy / !각인 명령어 활성화 여부"); AllowOmen = ((BaseUnityPlugin)this).Config.Bind("Commands", "흉조 활성화", true, "!omen / !흉조 명령어 활성화 여부"); AllowBoss = ((BaseUnityPlugin)this).Config.Bind("Commands", "보스 활성화", true, "!boss / !보스 명령어 활성화 여부"); AllowDarkAbility = ((BaseUnityPlugin)this).Config.Bind("Commands", "검은능력 활성화", true, "!dark / !검은능력 명령어 활성화 여부"); AllowRandomStat = ((BaseUnityPlugin)this).Config.Bind("Commands", "랜덤스탯 활성화", true, "!랜덤스탯 명령어 활성화 여부"); AllowNpc = ((BaseUnityPlugin)this).Config.Bind("Commands", "NPC 활성화", true, "!npc 명령어 활성화 여부"); AllowFood = ((BaseUnityPlugin)this).Config.Bind("Commands", "음식 활성화", true, "!food 명령어 활성화 여부"); AllowBone = ((BaseUnityPlugin)this).Config.Bind("Commands", "뼈 활성화", true, "!bone 명령어 활성화 여부"); AllowGold = ((BaseUnityPlugin)this).Config.Bind("Commands", "골드 활성화", true, "!gold 명령어 활성화 여부"); AllowDarkQuartz = ((BaseUnityPlugin)this).Config.Bind("Commands", "마석 활성화", true, "!darkquartz 명령어 활성화 여부"); AllowTotem = ((BaseUnityPlugin)this).Config.Bind("Commands", "토템 활성화", true, "!totem / !토템 명령어 활성화 여부"); AllowQuintessence = ((BaseUnityPlugin)this).Config.Bind("Commands", "정수 활성화", true, "!정수 명령어 활성화 여부"); AllowFragment = ((BaseUnityPlugin)this).Config.Bind("Commands", "파편 활성화", true, "!파편 명령어 활성화 여부"); AllowDefense = ((BaseUnityPlugin)this).Config.Bind("Commands", "방어력 활성화", true, "!defense / !방어력 명령어 활성화 여부"); AllowNuke = ((BaseUnityPlugin)this).Config.Bind("Commands", "핵폭발 활성화", true, "!핵 명령어 활성화 여부"); AllowChest = ((BaseUnityPlugin)this).Config.Bind("Commands", "상자소환 활성화", true, "!chest / !상자 명령어 활성화 여부"); EnableVote = ((BaseUnityPlugin)this).Config.Bind("Vote", "채팅 투표 활성화", true, "자동 채팅 투표 시스템을 켤지 끌지 설정합니다."); VoteTriggerMode = ((BaseUnityPlugin)this).Config.Bind("Vote", "투표 시작 방식", "Scene", "투표를 여는 방식: 'Timer'(시간마다) 또는 'Scene'(맵 이동 시마다)"); VoteIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind("Vote", "타이머 간격 (초)", 300f, "타이머 방식일 경우, 몇 초마다 투표를 열지 설정합니다."); VoteDurationSeconds = ((BaseUnityPlugin)this).Config.Bind("Vote", "투표 진행 시간 (초)", 30f, "투표가 열린 후 닫힐 때까지의 시간입니다."); VoteWeightItem = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "아이템 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightSkull = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "스컬 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightRandomStat = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "랜덤스탯 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightBuffCurse = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "버프저주 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightSynergy = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "각인 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightBoss = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "보스 비중", 15, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightFood = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "음식 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightNPC = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "NPC 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightFragment = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "파편 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightBone = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "뼈 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightGold = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "골드 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightTotem = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "토템 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightDarkQuartz = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "마석 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightQuintessence = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "정수 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightDarkAbility = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "검은능력 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightOmen = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "흉조 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightHeal = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "체력회복 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightDefense = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "방어력 증감 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightBossRush = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "보스러쉬 비중", 5, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightNuke = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "핵폭발 비중", 2, "투표 옵션으로 나올 비중 (1~100)"); VoteWeightChest = ((BaseUnityPlugin)this).Config.Bind("VoteWeights", "상자소환 비중", 50, "투표 옵션으로 나올 비중 (1~100)"); AllowStreamerCommand = ((BaseUnityPlugin)this).Config.Bind("General", "스트리머 명령어 허용", true, "스트리머 전용 명령어 사용 여부"); StreamerNickname = ((BaseUnityPlugin)this).Config.Bind("General", "스트리머 닉네임", "스트리머", "스트리머 치지직 닉네임 입력하세요."); CommandCooldown = ((BaseUnityPlugin)this).Config.Bind("General", "명령어 쿨타임", 30f, "일반 시청자 명령어 쿨타임 (초)"); NukeCountdownTime = ((BaseUnityPlugin)this).Config.Bind("Nuclear", "핵폭발 카운트다운 시간", 90f, "핵 폭발까지의 카운트다운 시간 (초)"); EnableNukeWarningUI = ((BaseUnityPlugin)this).Config.Bind("Nuclear", "핵폭발 화면 경고 켜기", true, "핵 카운트다운 중 화면 외곽에 붉은색 경고 UI를 띄웁니다."); EnableNukeWarningText = ((BaseUnityPlugin)this).Config.Bind("Nuclear", "핵폭발 텍스트 알림 켜기", true, "핵 카운트다운 중 남은 시간 알림 텍스트를 띄웁니다."); NukeNormalEnemyDamageType = ((BaseUnityPlugin)this).Config.Bind("Nuclear", "핵폭발 일반몹 피해 타입", "InstantKill", new ConfigDescription("일반 잡몹의 피해 방식.", (AcceptableValueBase)(object)new AcceptableValueList(new string[4] { "InstantKill", "Fixed", "Percent", "None" }), Array.Empty())); NukeNormalEnemyDamageValue = ((BaseUnityPlugin)this).Config.Bind("Nuclear", "핵폭발 일반몹 피해량", 0f, "고정 피해 혹은 비율(%) 피해 수치를 설정합니다."); NukeBossDamageType = ((BaseUnityPlugin)this).Config.Bind("Nuclear", "핵폭발 보스/고정몹 피해 타입", "None", new ConfigDescription("보스/네임드/모험가 등 고정몹 피해 방식.", (AcceptableValueBase)(object)new AcceptableValueList(new string[4] { "InstantKill", "Fixed", "Percent", "None" }), Array.Empty())); NukeBossDamageValue = ((BaseUnityPlugin)this).Config.Bind("Nuclear", "핵폭발 보스/고정몹 피해량", 0f, "고정 피해 혹은 비율(%) 피해 수치를 설정합니다."); CmdHealString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "힐 명령어", "!heal,!힐", "쉼표(,)로 구분하세요."); CmdBuffCurseString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "버프저주 명령어", "!buff,!버프,!curse,!저주", "쉼표(,)로 구분하세요."); CmdItemString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "아이템 명령어", "!item,!아이템", "쉼표(,)로 구분하세요."); CmdSkullString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "스컬 명령어", "!skull,!해골,!머리,!대머리,!skul", "쉼표(,)로 구분하세요."); CmdSynergyString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "각인 명령어", "!synergy,!각인", "쉼표(,)로 구분하세요."); CmdOmenString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "흉조 명령어", "!omen,!흉조", "쉼표(,)로 구분하세요."); CmdBossString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "보스 명령어", "!boss,!보스", "쉼표(,)로 구분하세요."); CmdDarkEnemyString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "검은적 명령어", "!darkenemy,!검은적", "스트리머 전용 검은적 강제 적용 명령어."); CmdDarkAbilityString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "검은능력 명령어", "!dark,!검은능력", "쉼표(,)로 구분하세요."); CmdRandomString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "랜덤 명령어", "!random,!랜덤", "쉼표(,)로 구분하세요."); CmdRandomStatString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "랜덤스탯 명령어", "!randomstat,!랜덤스탯", "쉼표(,)로 구분하세요."); CmdNpcString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "NPC 명령어", "!npc,!엔피씨,!상인,!npc스폰", "쉼표(,)로 구분하세요."); CmdFoodString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "음식 명령어", "!food,!음식,!밥", "쉼표(,)로 구분하세요."); CmdBoneString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "뼈 명령어", "!bone,!뼈", "쉼표(,)로 구분하세요."); CmdGoldString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "골드 명령어", "!gold,!골드,!돈", "쉼표(,)로 구분하세요."); CmdDarkQuartzString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "마석 명령어", "!darkquartz,!마석", "쉼표(,)로 구분하세요."); CmdQuintessenceString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "정수 명령어", "!quintessence,!정수", "쉼표(,)로 구분하세요."); CmdFragmentString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "파편 명령어", "!파편,!fragment", "쉼표(,)로 구분하세요."); CmdDefenseString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "방어력 명령어", "!defense,!방어력", "쉼표(,)로 구분하세요."); CmdTotemString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "토템 명령어", "!totem,!토템", "쉼표(,)로 구분하세요."); CmdChestString = ((BaseUnityPlugin)this).Config.Bind("CommandStrings", "상자소환 명령어", "!chest,!상자,!상자소환", "쉼표(,)로 구분하세요."); TTSProvider = ((BaseUnityPlugin)this).Config.Bind("TTS", "TTS 엔진 선택", "Google", "사용할 TTS 엔진 ('Google', 'Windows', 또는 'None')"); EnableDonationTTS = ((BaseUnityPlugin)this).Config.Bind("TTS", "후원 TTS 활성화", true, "후원 메시지를 음성으로 읽어줍니다."); EnableChatTTS = ((BaseUnityPlugin)this).Config.Bind("TTS", "채팅 TTS 활성화", true, "일반 채팅 메시지를 음성으로 읽어줍니다."); DonAmtNukeAll = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "모두파괴 금액", 700000, "모든 아이템/검은능력 파괴"); DonAmtNukeItems = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "아이템전부파괴 금액", 500000, "모든 아이템 파괴"); DonAmtSubSkullDelete = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "보조스컬삭제 금액", 150000, "보조스컬 파괴"); DonAmtDarkAbilityDelete = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "검은능력삭제 금액", 100000, "검은능력 1개 파괴"); DonAmtItemDelete = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "아이템1개삭제 금액", 50000, "아이템 1개 파괴"); DonAmtBossRush = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "보스러쉬 금액", 50000, "보스러쉬 발동"); DonAmtBoss = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "보스소환 금액", 30000, "보스 소환"); DonAmtScreenEffect = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "화면효과 금액", 30000, "랜덤 화면 효과"); DonAmtSynergy = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "각인 금액", 20000, "각인 강화/추가"); DonAmtDarkAbility = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "검은능력지급 금액", 10000, "검은능력 추가"); DonAmtFragment = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "파편 금액", 10000, "파편 추가/삭제"); DonAmtOmen = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "흉조 금액", 10000, "흉조 상자 강제"); DonAmtItem = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "아이템지급 금액", 5000, "랜덤 아이템 지급"); DonAmtSkull = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "스컬지급 금액", 5000, "랜덤 스컬 지급"); DonAmtQuintessence = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "정수지급 금액", 5000, "랜덤 정수 지급"); DonAmtNPC = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "NPC소환 금액", 5000, "NPC 소환"); DonAmtStat = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "기본재화 금액", 1000, "골드/마석/뼈 지급"); DonAmtRandomStat = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "랜덤스탯 금액", 1000, "랜덤 스탯 증감"); DonAmtBuffCurse = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "버프저주 금액", 1000, "버프 또는 저주"); DonAmtHeal = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "체력회복 금액", 5000, "체력 회복"); DonAmtDefense = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "방어력 금액", 5000, "방어력 증감"); DonAmtTotem = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "토템 금액", 5000, "몹 버프 토템 소환"); DonAmtFood = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "음식 금액", 1000, "음식 드롭"); DonAmtNuke = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "핵폭발 금액", 50000, "핵폭발 기믹 발동"); DonAmtChest = ((BaseUnityPlugin)this).Config.Bind("DonationAmounts", "상자소환 금액", 10000, "상자 소환"); EnableChaosMode = ((BaseUnityPlugin)this).Config.Bind("Chaos", "카오스 모드 활성화", false, "카오스 모드가 실행됩니다."); ChaosIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind("Chaos", "카오스 모드 발동 간격 (초)", 60f, "카오스 모드 발동 주기"); PoisonChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "힐 시 독약 확률 (%)", 30f, "독약 확률"); BuffChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "버프저주 시 버프 확률 (%)", 70f, "버프 확률"); ItemEmptyChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "아이템 시 올삭제 확률 (%)", 0.01f, "올삭제 확률"); ItemDeleteChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "아이템 시 1개삭제 확률 (%)", 40f, "삭제 확률"); ItemOmenChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "아이템 시 흉조 확률 (%)", 30f, "흉조 확률"); ItemAutoEquipChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "아이템 시 자동장착 확률 (%)", 70f, "장착 확률"); SkullSuperChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "스컬 시 슈퍼스컬 확률 (%)", 0.5f, "슈퍼스컬 확률"); SkullEvolveChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "스컬 시 진화단계 확률 (%)", 30f, "진화 확률"); SkullReplaceChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "스컬 시 보조교체 확률 (%)", 50f, "교체 확률"); SkullDeleteChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "스컬 시 보조삭제 확률 (%)", 20f, "삭제 확률"); FragmentDeleteChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "파편 시 삭제 확률 (%)", 50f, "삭제 확률"); DarkAbilityDeleteChance = ((BaseUnityPlugin)this).Config.Bind("Luck Percent", "검은능력 시 삭제 확률 (%)", 50f, "삭제 확률"); _harmonyInstance = new Harmony("com.slibul.chzzkskulstreamer"); _onSaveSync = delegate { ChzzkStatManager.SaveData.IsBossRushActive = ChzzkGameMode._isBossRushActive; ChzzkStatManager.SaveData.ForceNextDarkEnemy = ChzzkGameMode._forceNextDarkEnemy; ChzzkStatManager.SaveData.ForceNextOmen = OmenChestPath.ForceNextOmen; ChzzkStatManager.SaveData.IsScreenEffectActive = ChzzkGameMode.IsScreenEffectActive; ChzzkStatManager.SaveData.ScreenEffectType = ChzzkGameMode._screenEffectType.ToString(); ChzzkStatManager.SaveData.ScreenEffectTimer = ChzzkGameMode._screenEffectTimer; ChzzkStatManager.SaveData.IsNukeActive = ChzzkGameMode._isNukeActive; ChzzkStatManager.SaveData.NukeScenesPassed = ChzzkGameMode._nukeScenesPassed; ChzzkStatManager.SaveData.NukeElapsed = ChzzkGameMode._nukeElapsed; ChzzkStatManager.SaveData.BossRushElapsed = ChzzkGameMode._bossRushElapsed; }; _onLoadSync = delegate { SaveWrapper saveData = ChzzkStatManager.SaveData; ChzzkGameMode._isBossRushActive = saveData.IsBossRushActive; ChzzkGameMode._forceNextDarkEnemy = saveData.ForceNextDarkEnemy; OmenChestPath.ForceNextOmen = saveData.ForceNextOmen; ChzzkGameMode.IsScreenEffectActive = saveData.IsScreenEffectActive; ChzzkGameMode._screenEffectType = (int.TryParse(saveData.ScreenEffectType, out var result) ? result : 0); ChzzkGameMode._screenEffectTimer = ((saveData.ScreenEffectTimer > 0f) ? saveData.ScreenEffectTimer : 20f); ChzzkGameMode._isNukeActive = saveData.IsNukeActive; ChzzkGameMode._nukeScenesPassed = saveData.NukeScenesPassed; ChzzkGameMode._nukeElapsed = saveData.NukeElapsed; ChzzkGameMode._bossRushElapsed = saveData.BossRushElapsed; }; _onClearSync = delegate { ChzzkGameMode._forceNextDarkEnemy = false; OmenChestPath.ForceNextOmen = false; ChzzkGameMode.IsScreenEffectActive = false; ChzzkGameMode.CustomSuperInscriptions.Clear(); }; bool enabled = _isEnabled ?? true; _isEnabled = null; SetEnabled(enabled); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ChzzkSkulStreamer (Streamer & Donation Link) loaded!"); } public static void SetEnabled(bool enabled) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown if (Log == null || _harmonyInstance == null) { _isEnabled = enabled; } else { if (_isEnabled == enabled) { return; } if (enabled) { Log.LogInfo((object)"[PluginStreamer] Enabling Streamer module (Applying patches & connecting)..."); try { _harmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); ChzzkStatManager.OnSave += _onSaveSync; ChzzkStatManager.OnLoad += _onLoadSync; ChzzkStatManager.OnClear += _onClearSync; _gameModeObject = new GameObject("ChzzkGameModeHost"); Object.DontDestroyOnLoad((Object)(object)_gameModeObject); Instance._gameModeHandler = _gameModeObject.AddComponent(); try { ChzzkStatManager.Load(); } catch (Exception ex) { Log.LogError((object)("Failed to sync ChzzkStatManager: " + ex)); } OmenChestPath.StartChzzk(Instance._gameModeHandler, ChannelID.Value); } catch (Exception ex2) { Log.LogError((object)("Error enabling PluginStreamer: " + ex2)); } } else { Log.LogInfo((object)"[PluginStreamer] Disabling Streamer module (Unpatching & disconnecting)..."); try { _harmonyInstance.UnpatchSelf(); ChzzkStatManager.OnSave -= _onSaveSync; ChzzkStatManager.OnLoad -= _onLoadSync; ChzzkStatManager.OnClear -= _onClearSync; if ((Object)(object)_gameModeObject != (Object)null) { Object.Destroy((Object)(object)_gameModeObject); _gameModeObject = null; } GameObject val = GameObject.Find("ChatIntegrationHost"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } catch (Exception ex3) { Log.LogError((object)("Error disabling PluginStreamer: " + ex3)); } } _isEnabled = enabled; } } public static void ReloadAndReconnect() { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Config.Reload(); } if (_isEnabled == true && (Object)(object)Instance != (Object)null && (Object)(object)Instance._gameModeHandler != (Object)null) { OmenChestPath.Reconnect(Instance._gameModeHandler); } } private Texture2D MakeTex(int width, int height, Color col) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_002e: Expected O, but got Unknown Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = col; } Texture2D val = new Texture2D(width, height); val.SetPixels(array); val.Apply(); ((Object)val).hideFlags = (HideFlags)61; return val; } private Texture2D MakeRoundedTex(int width, int height, Color col, int radius) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { bool flag = false; float num = 0f; if (j < radius && i < radius) { flag = true; num = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)radius, (float)radius)); } else if (j >= width - radius && i < radius) { flag = true; num = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)(width - radius - 1), (float)radius)); } else if (j < radius && i >= height - radius) { flag = true; num = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)radius, (float)(height - radius - 1))); } else if (j >= width - radius && i >= height - radius) { flag = true; num = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)(width - radius - 1), (float)(height - radius - 1))); } if (flag && num > (float)radius) { array[i * width + j] = Color.clear; } else { array[i * width + j] = col; } } } val.SetPixels(array); val.Apply(); ((Object)val).hideFlags = (HideFlags)61; return val; } private void InitStyles() { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Expected O, but got Unknown //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Expected O, but got Unknown //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Expected O, but got Unknown //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Expected O, but got Unknown //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Expected O, but got Unknown if (!_styleInitialized) { _styleInitialized = true; Color col = default(Color); ((Color)(ref col))..ctor(0.12f, 0.1f, 0.15f, 0.95f); Color col2 = default(Color); ((Color)(ref col2))..ctor(0.3f, 0.2f, 0.4f, 1f); Color col3 = default(Color); ((Color)(ref col3))..ctor(0.25f, 0.15f, 0.35f, 1f); Color col4 = default(Color); ((Color)(ref col4))..ctor(0.4f, 0.25f, 0.55f, 1f); Color textColor = default(Color); ((Color)(ref textColor))..ctor(1f, 0.85f, 0.4f, 1f); Color textColor2 = default(Color); ((Color)(ref textColor2))..ctor(0.9f, 0.9f, 0.95f, 1f); Color col5 = default(Color); ((Color)(ref col5))..ctor(0.05f, 0.05f, 0.08f, 1f); int num = 32; int num2 = 14; _windowStyle = new GUIStyle(GUI.skin.window); _windowStyle.normal.background = MakeRoundedTex(num, num, col, num2); _windowStyle.onNormal.background = MakeRoundedTex(num, num, col, num2); _windowStyle.border = new RectOffset(num2, num2, num2, num2); _windowStyle.normal.textColor = textColor; _windowStyle.onNormal.textColor = textColor; _windowStyle.fontSize = 18; _windowStyle.fontStyle = (FontStyle)1; _windowStyle.padding = new RectOffset(10, 10, 30, 10); _windowStyle.alignment = (TextAnchor)1; _headerStyle = new GUIStyle(GUI.skin.label); _headerStyle.fontSize = 16; _headerStyle.fontStyle = (FontStyle)1; _headerStyle.normal.textColor = textColor; _headerStyle.margin = new RectOffset(0, 0, 10, 5); _labelStyle = new GUIStyle(GUI.skin.label); _labelStyle.fontSize = 14; _labelStyle.normal.textColor = textColor2; _labelStyle.alignment = (TextAnchor)3; int num3 = 8; _buttonStyle = new GUIStyle(GUI.skin.button); _buttonStyle.normal.background = MakeRoundedTex(num, num, col3, num3); _buttonStyle.hover.background = MakeRoundedTex(num, num, col4, num3); _buttonStyle.active.background = MakeRoundedTex(num, num, col2, num3); _buttonStyle.border = new RectOffset(num3, num3, num3, num3); _buttonStyle.normal.textColor = textColor2; _buttonStyle.hover.textColor = Color.white; _buttonStyle.fontSize = 15; _buttonStyle.fontStyle = (FontStyle)1; int num4 = 6; _textFieldStyle = new GUIStyle(GUI.skin.textField); _textFieldStyle.normal.background = MakeRoundedTex(num, num, col5, num4); _textFieldStyle.border = new RectOffset(num4, num4, num4, num4); _textFieldStyle.normal.textColor = textColor2; _textFieldStyle.fontSize = 14; _textFieldStyle.alignment = (TextAnchor)3; _toggleStyle = new GUIStyle(GUI.skin.toggle); _toggleStyle.normal.textColor = textColor2; _lineStyle = new GUIStyle(GUI.skin.box); _lineStyle.normal.background = MakeTex(2, 2, col2); _lineStyle.margin = new RectOffset(0, 0, 8, 8); } } private void Update() { if (Input.GetKeyDown((KeyCode)286)) { ((BaseUnityPlugin)this).Config.Reload(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Plugin] Config 파일이 재로드 되었습니다!"); } if (Input.GetKeyDown((KeyCode)107)) { _showSettings = !_showSettings; } } private void OnGUI() { //IL_001a: 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_003b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (_showSettings) { InitStyles(); _windowRect = GUI.Window(9999, _windowRect, new WindowFunction(DrawSettingsWindow), "치지직 스컬 모드 설정", _windowStyle); } } private void DrawSettingsWindow(int windowID) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, Array.Empty()); string text = ""; bool flag = true; foreach (ConfigDefinition key in ((BaseUnityPlugin)this).Config.Keys) { ConfigEntryBase val = ((BaseUnityPlugin)this).Config[key]; if (text != key.Section) { if (!flag) { GUILayout.Space(10f); GUILayout.Box(GUIContent.none, _lineStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(2f), GUILayout.ExpandWidth(true) }); } flag = false; text = key.Section; if (!_sectionExpanded.ContainsKey(text)) { _sectionExpanded[text] = true; } GUILayout.Space(10f); string text2 = (_sectionExpanded[text] ? "▼" : "▶"); if (GUILayout.Button(text2 + " [ " + text + " ]", _headerStyle, Array.Empty())) { _sectionExpanded[text] = !_sectionExpanded[text]; } GUILayout.Space(5f); } if (!_sectionExpanded[text]) { continue; } GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(key.Key, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }); if (key.Key == "투표 시작 방식") { string text3 = (string)val.BoxedValue; if (GUILayout.Button((text3 == "Scene") ? "◉ 맵 이동시" : "○ 맵 이동시", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { text3 = "Scene"; } if (GUILayout.Button((text3 == "Timer") ? "◉ 시간마다" : "○ 시간마다", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { text3 = "Timer"; } if ((string)val.BoxedValue != text3) { val.BoxedValue = text3; } } else if (key.Key == "TTS 엔진 선택") { string text4 = (string)val.BoxedValue; if (GUILayout.Button((text4 == "Google") ? "◉ 구글 번역기" : "○ 구글 번역기", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { text4 = "Google"; } if (GUILayout.Button((text4 == "Windows") ? "◉ 윈도우 내장" : "○ 윈도우 내장", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { text4 = "Windows"; } if (GUILayout.Button((text4 == "None") ? "◉ 비활성화" : "○ 비활성화", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { text4 = "None"; } if ((string)val.BoxedValue != text4) { val.BoxedValue = text4; } } else if (key.Key == "핵폭발 일반몹 피해 타입" || key.Key == "핵폭발 보스/고정몹 피해 타입") { string text5 = (string)val.BoxedValue; if (GUILayout.Button((text5 == "InstantKill") ? "◉ 즉사" : "○ 즉사", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { text5 = "InstantKill"; } if (GUILayout.Button((text5 == "Fixed") ? "◉ 고정" : "○ 고정", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { text5 = "Fixed"; } if (GUILayout.Button((text5 == "Percent") ? "◉ 비율" : "○ 비율", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { text5 = "Percent"; } if (GUILayout.Button((text5 == "None") ? "◉ 없음" : "○ 없음", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { text5 = "None"; } if ((string)val.BoxedValue != text5) { val.BoxedValue = text5; } } else if (val.SettingType == typeof(int)) { string text6 = val.BoxedValue.ToString(); string s = GUILayout.TextField(text6, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if (int.TryParse(s, out var result)) { val.BoxedValue = result; } } else if (val.SettingType == typeof(float)) { string text7 = val.BoxedValue.ToString(); string s2 = GUILayout.TextField(text7, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if (float.TryParse(s2, out var result2)) { val.BoxedValue = result2; } } else if (val.SettingType == typeof(bool)) { bool flag2 = (bool)val.BoxedValue; bool flag3 = GUILayout.Toggle(flag2, "", _toggleStyle, Array.Empty()); if (flag2 != flag3) { val.BoxedValue = flag3; } } else if (val.SettingType == typeof(string)) { string text8 = (string)val.BoxedValue; string text9 = GUILayout.TextField(text8, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if (text8 != text9) { val.BoxedValue = text9; } } GUILayout.EndHorizontal(); GUILayout.Space(2f); } GUILayout.EndScrollView(); GUILayout.Space(10f); if (GUILayout.Button("저장 및 닫기", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) })) { ((BaseUnityPlugin)this).Config.Save(); _showSettings = false; OmenChestPath.Reconnect(_gameModeHandler); } GUI.DragWindow(); } } public class YouTubeUnity : MonoBehaviour { public UnityEvent onMessage = new UnityEvent(); public UnityEvent onDonation = new UnityEvent(); private List _apiKeys = new List(); private int _currentKeyIndex = 0; private string _apiKey; private string _videoId; private string _liveChatId; private string _nextPageToken = ""; private float _pollingIntervalMillis = 10000f; private float _minPollingIntervalMillis = 10000f; private bool _isRunning = false; public void Connect(string apiKey, string videoId, float pollInterval = 10f) { _minPollingIntervalMillis = Mathf.Max(2000f, pollInterval * 1000f); _pollingIntervalMillis = _minPollingIntervalMillis; _videoId = videoId; _isRunning = true; _nextPageToken = ""; _apiKeys = (from k in (apiKey ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select k.Trim() into k where !string.IsNullOrEmpty(k) select k).ToList(); _currentKeyIndex = 0; if (_apiKeys.Count > 0) { _apiKey = _apiKeys[0]; } else { _apiKey = apiKey; } Debug.Log((object)$"[YouTubeUnity] Initializing connection with Video ID: {videoId}. Found {_apiKeys.Count} API Key(s) for rotation."); ((MonoBehaviour)this).StartCoroutine(FetchLiveChatIdRoutine()); } private bool RotateApiKey() { if (_apiKeys == null || _apiKeys.Count <= 1) { return false; } _currentKeyIndex = (_currentKeyIndex + 1) % _apiKeys.Count; _apiKey = _apiKeys[_currentKeyIndex]; Debug.LogWarning((object)$"[YouTubeUnity] YouTube API quota exceeded or key invalid. Switching to API Key #{_currentKeyIndex + 1} ({((_apiKey.Length > 8) ? _apiKey.Substring(0, 8) : _apiKey)}...)"); return true; } private IEnumerator FetchLiveChatIdRoutine() { string url = "https://www.googleapis.com/youtube/v3/videos?id=" + _videoId + "&part=liveStreamingDetails&key=" + _apiKey; UnityWebRequest request = UnityWebRequest.Get(url); try { yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { Debug.LogError((object)("[YouTubeUnity] Failed to get liveChatId: " + request.error + "\n" + request.downloadHandler.text)); if ((request.responseCode == 403 || (request.downloadHandler != null && !string.IsNullOrEmpty(request.downloadHandler.text) && request.downloadHandler.text.Contains("quotaExceeded"))) && RotateApiKey()) { ((MonoBehaviour)this).StartCoroutine(FetchLiveChatIdRoutine()); } else { _isRunning = false; } yield break; } try { JObject json = JObject.Parse(request.downloadHandler.text); JArray items = (JArray)json["items"]; if (items != null && ((JContainer)items).Count > 0) { JToken streamingDetails = items[0][(object)"liveStreamingDetails"]; if (streamingDetails != null) { _liveChatId = (string)streamingDetails[(object)"activeLiveChatId"]; } } if (string.IsNullOrEmpty(_liveChatId)) { Debug.LogError((object)("[YouTubeUnity] Could not find activeLiveChatId for Video ID: " + _videoId + ". Is it a live stream?")); _isRunning = false; yield break; } Debug.Log((object)("[YouTubeUnity] Successfully connected to YouTube Live Chat! (Chat ID: " + _liveChatId + ")")); ((MonoBehaviour)this).StartCoroutine(PollMessagesRoutine()); } catch (Exception ex) { Debug.LogError((object)("[YouTubeUnity] Error parsing liveChatId: " + ex.Message)); _isRunning = false; } } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator PollMessagesRoutine() { while (_isRunning) { string url = "https://www.googleapis.com/youtube/v3/liveChat/messages?liveChatId=" + _liveChatId + "&part=snippet,authorDetails&key=" + _apiKey; if (!string.IsNullOrEmpty(_nextPageToken)) { url = url + "&pageToken=" + _nextPageToken; } UnityWebRequest request = UnityWebRequest.Get(url); try { yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { Debug.LogError((object)("[YouTubeUnity] Fetch error: " + request.error + "\n" + request.downloadHandler.text)); if (request.responseCode != 403 && (request.downloadHandler == null || string.IsNullOrEmpty(request.downloadHandler.text) || !request.downloadHandler.text.Contains("quotaExceeded"))) { yield return (object)new WaitForSeconds(5f); continue; } if (RotateApiKey()) { yield return (object)new WaitForSeconds(1f); continue; } Debug.LogError((object)"[YouTubeUnity] YouTube API quota exceeded! Disabling YouTube integration for this session to prevent log spam."); _isRunning = false; } else { ParseMessages(request.downloadHandler.text); } } finally { ((IDisposable)request)?.Dispose(); } yield return (object)new WaitForSeconds(_pollingIntervalMillis / 1000f); } } private void ParseMessages(string jsonResponse) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown try { JObject val = JObject.Parse(jsonResponse); if (val["pollingIntervalMillis"] != null) { _pollingIntervalMillis = Math.Max(_minPollingIntervalMillis, (float)val["pollingIntervalMillis"]); } else { _pollingIntervalMillis = _minPollingIntervalMillis; } bool flag = string.IsNullOrEmpty(_nextPageToken); if (val["nextPageToken"] != null) { _nextPageToken = (string)val["nextPageToken"]; } JArray val2 = (JArray)val["items"]; if (val2 == null || flag) { return; } foreach (JToken item in val2) { JToken val3 = item[(object)"snippet"]; JToken val4 = item[(object)"authorDetails"]; if (val3 == null || val4 == null) { continue; } string text = (string)val3[(object)"type"]; if (text == "textMessageEvent") { string text2 = (string)val4[(object)"displayName"]; string text3 = (string)val3[(object)"displayMessage"]; onMessage?.Invoke(text2, text3); } else if (text == "superChatEvent") { string text4 = (string)val4[(object)"displayName"]; string text5 = (string)val3[(object)"displayMessage"]; JToken val5 = val3[(object)"superChatDetails"]; if (val5 != null) { long num = (long)val5[(object)"amountMicros"]; int num2 = (int)(num / 1000000); onDonation?.Invoke(text4, text5, num2); } } } } catch (Exception ex) { Debug.LogError((object)("[YouTubeUnity] Parse error: " + ex.Message)); } } private void OnDestroy() { _isRunning = false; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ChzzkStream"; public const string PLUGIN_NAME = "ChzzkStream"; public const string PLUGIN_VERSION = "1.1.8"; } } namespace System { internal readonly struct Index : IEquatable { private readonly int _value; public static Index Start => new Index(0); public static Index End => new Index(-1); public bool IsFromEnd => _value < 0; public int Value => IsFromEnd ? (~_value) : _value; [MethodImpl(MethodImplOptions.AggressiveInlining)] public Index(int value, bool fromEnd = false) { if (value < 0) { throw new ArgumentOutOfRangeException("value"); } _value = (fromEnd ? (~value) : value); } private Index(int value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Index(int value) { return new Index(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetOffset(int length) { int num = _value; if (IsFromEnd) { num += length + 1; } return num; } public bool Equals(Index other) { return _value == other._value; } public override bool Equals(object value) { return value is Index index && _value == index._value; } public override int GetHashCode() { return _value; } public override string ToString() { return IsFromEnd ? $"^{Value}" : Value.ToString(); } } internal readonly struct Range : IEquatable { public Index Start { get; } public Index End { get; } public static Range All => Index.Start..Index.End; public Range(Index start, Index end) { Start = start; End = end; } public static Range StartAt(Index start) { return start..Index.End; } public static Range EndAt(Index end) { return Index.Start..end; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public (int Offset, int Length) GetOffsetAndLength(int length) { int offset = Start.GetOffset(length); int offset2 = End.GetOffset(length); if ((uint)offset2 > (uint)length || (uint)offset > (uint)offset2) { throw new ArgumentOutOfRangeException("length"); } return (Offset: offset, Length: offset2 - offset); } public bool Equals(Range other) { return Start.Equals(other.Start) && End.Equals(other.End); } public override bool Equals(object value) { return value is Range range && range.Equals(this); } public override int GetHashCode() { return Start.GetHashCode() ^ (End.GetHashCode() << 16); } public override string ToString() { return $"{Start}..{End}"; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } internal static class IsExternalInit { } }